1/* 2 * ASF compatible demuxer 3 * Copyright (c) 2000, 2001 Fabrice Bellard 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/common.h" 23#include "libavcodec/mpegaudio.h" 24#include "avformat.h" 25#include "riff.h" 26#include "asf.h" 27#include "asfcrypt.h" 28 29void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format); 30 31#undef NDEBUG 32#include <assert.h> 33 34#define FRAME_HEADER_SIZE 17 35// Fix Me! FRAME_HEADER_SIZE may be different. 36 37static const GUID index_guid = { 38 0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb 39}; 40 41static const GUID stream_bitrate_guid = { /* (http://get.to/sdp) */ 42 0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2 43}; 44/**********************************/ 45/* decoding */ 46 47//#define DEBUG 48 49#ifdef DEBUG 50#define PRINT_IF_GUID(g,cmp) \ 51if (!memcmp(g, &cmp, sizeof(GUID))) \ 52 dprintf(NULL, "(GUID: %s) ", #cmp) 53 54static void print_guid(const GUID *g) 55{ 56 int i; 57 PRINT_IF_GUID(g, ff_asf_header); 58 else PRINT_IF_GUID(g, ff_asf_file_header); 59 else PRINT_IF_GUID(g, ff_asf_stream_header); 60 else PRINT_IF_GUID(g, ff_asf_audio_stream); 61 else PRINT_IF_GUID(g, ff_asf_audio_conceal_none); 62 else PRINT_IF_GUID(g, ff_asf_video_stream); 63 else PRINT_IF_GUID(g, ff_asf_video_conceal_none); 64 else PRINT_IF_GUID(g, ff_asf_command_stream); 65 else PRINT_IF_GUID(g, ff_asf_comment_header); 66 else PRINT_IF_GUID(g, ff_asf_codec_comment_header); 67 else PRINT_IF_GUID(g, ff_asf_codec_comment1_header); 68 else PRINT_IF_GUID(g, ff_asf_data_header); 69 else PRINT_IF_GUID(g, index_guid); 70 else PRINT_IF_GUID(g, ff_asf_head1_guid); 71 else PRINT_IF_GUID(g, ff_asf_head2_guid); 72 else PRINT_IF_GUID(g, ff_asf_my_guid); 73 else PRINT_IF_GUID(g, ff_asf_ext_stream_header); 74 else PRINT_IF_GUID(g, ff_asf_extended_content_header); 75 else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); 76 else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); 77 else PRINT_IF_GUID(g, ff_asf_metadata_header); 78 else PRINT_IF_GUID(g, stream_bitrate_guid); 79 else 80 dprintf(NULL, "(GUID: unknown) "); 81 for(i=0;i<16;i++) 82 dprintf(NULL, " 0x%02x,", (*g)[i]); 83 dprintf(NULL, "}\n"); 84} 85#undef PRINT_IF_GUID 86#else 87#define print_guid(g) 88#endif 89 90static void get_guid(ByteIOContext *s, GUID *g) 91{ 92 assert(sizeof(*g) == 16); 93 get_buffer(s, *g, sizeof(*g)); 94} 95 96#if 0 97static void get_str16(ByteIOContext *pb, char *buf, int buf_size) 98{ 99 int len, c; 100 char *q; 101 102 len = get_le16(pb); 103 q = buf; 104 while (len > 0) { 105 c = get_le16(pb); 106 if ((q - buf) < buf_size - 1) 107 *q++ = c; 108 len--; 109 } 110 *q = '\0'; 111} 112#endif 113 114static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) 115{ 116 char* q = buf; 117 len /= 2; 118 while (len--) { 119 uint8_t tmp; 120 PUT_UTF8(get_le16(pb), tmp, if (q - buf < buf_size - 1) *q++ = tmp;) 121 } 122 *q = '\0'; 123} 124 125static int asf_probe(AVProbeData *pd) 126{ 127 /* check file header */ 128 if (!memcmp(pd->buf, &ff_asf_header, sizeof(GUID))) 129 return AVPROBE_SCORE_MAX; 130 else 131 return 0; 132} 133 134static int get_value(ByteIOContext *pb, int type){ 135 switch(type){ 136 case 2: return get_le32(pb); 137 case 3: return get_le32(pb); 138 case 4: return get_le64(pb); 139 case 5: return get_le16(pb); 140 default:return INT_MIN; 141 } 142} 143 144static void get_tag(AVFormatContext *s, const char *key, int type, int len) 145{ 146 char value[1024]; 147 if (type <= 1) { // unicode or byte 148 get_str16_nolen(s->pb, len, value, sizeof(value)); 149 } else if (type <= 5) { // boolean or DWORD or QWORD or WORD 150 uint64_t num = get_value(s->pb, type); 151 snprintf(value, sizeof(value), "%"PRIu64, num); 152 } else { 153 url_fskip(s->pb, len); 154 return; 155 } 156 if (strncmp(key, "WM/", 3)) 157 key += 3; 158 av_metadata_set(&s->metadata, key, value); 159} 160 161static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) 162{ 163 ASFContext *asf = s->priv_data; 164 GUID g; 165 ByteIOContext *pb = s->pb; 166 AVStream *st; 167 ASFStream *asf_st; 168 int size, i; 169 int64_t gsize; 170 AVRational dar[128]; 171 uint32_t bitrate[128]; 172 173 memset(dar, 0, sizeof(dar)); 174 memset(bitrate, 0, sizeof(bitrate)); 175 176 get_guid(pb, &g); 177 if (memcmp(&g, &ff_asf_header, sizeof(GUID))) 178 return -1; 179 get_le64(pb); 180 get_le32(pb); 181 get_byte(pb); 182 get_byte(pb); 183 memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); 184 for(;;) { 185 get_guid(pb, &g); 186 gsize = get_le64(pb); 187 dprintf(s, "%08"PRIx64": ", url_ftell(pb) - 24); 188 print_guid(&g); 189 dprintf(s, " size=0x%"PRIx64"\n", gsize); 190 if (!memcmp(&g, &ff_asf_data_header, sizeof(GUID))) { 191 asf->data_object_offset = url_ftell(pb); 192 // if not streaming, gsize is not unlimited (how?), and there is enough space in the file.. 193 if (!(asf->hdr.flags & 0x01) && gsize >= 100) { 194 asf->data_object_size = gsize - 24; 195 } else { 196 asf->data_object_size = (uint64_t)-1; 197 } 198 break; 199 } 200 if (gsize < 24) 201 return -1; 202 if (!memcmp(&g, &ff_asf_file_header, sizeof(GUID))) { 203 get_guid(pb, &asf->hdr.guid); 204 asf->hdr.file_size = get_le64(pb); 205 asf->hdr.create_time = get_le64(pb); 206 asf->nb_packets = get_le64(pb); 207 asf->hdr.play_time = get_le64(pb); 208 asf->hdr.send_time = get_le64(pb); 209 asf->hdr.preroll = get_le32(pb); 210 asf->hdr.ignore = get_le32(pb); 211 asf->hdr.flags = get_le32(pb); 212 asf->hdr.min_pktsize = get_le32(pb); 213 asf->hdr.max_pktsize = get_le32(pb); 214 asf->hdr.max_bitrate = get_le32(pb); 215 s->packet_size = asf->hdr.max_pktsize; 216 } else if (!memcmp(&g, &ff_asf_stream_header, sizeof(GUID))) { 217 enum CodecType type; 218 int type_specific_size, sizeX; 219 uint64_t total_size; 220 unsigned int tag1; 221 int64_t pos1, pos2, start_time; 222 int test_for_ext_stream_audio, is_dvr_ms_audio=0; 223 224 pos1 = url_ftell(pb); 225 226 st = av_new_stream(s, 0); 227 if (!st) 228 return AVERROR(ENOMEM); 229 av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ 230 asf_st = av_mallocz(sizeof(ASFStream)); 231 if (!asf_st) 232 return AVERROR(ENOMEM); 233 st->priv_data = asf_st; 234 start_time = asf->hdr.preroll; 235 236 if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... 237 st->duration = asf->hdr.send_time / 238 (10000000 / 1000) - start_time; 239 } 240 get_guid(pb, &g); 241 242 test_for_ext_stream_audio = 0; 243 if (!memcmp(&g, &ff_asf_audio_stream, sizeof(GUID))) { 244 type = CODEC_TYPE_AUDIO; 245 } else if (!memcmp(&g, &ff_asf_video_stream, sizeof(GUID))) { 246 type = CODEC_TYPE_VIDEO; 247 } else if (!memcmp(&g, &ff_asf_command_stream, sizeof(GUID))) { 248 type = CODEC_TYPE_DATA; 249 } else if (!memcmp(&g, &ff_asf_ext_stream_embed_stream_header, sizeof(GUID))) { 250 test_for_ext_stream_audio = 1; 251 type = CODEC_TYPE_UNKNOWN; 252 } else { 253 return -1; 254 } 255 get_guid(pb, &g); 256 total_size = get_le64(pb); 257 type_specific_size = get_le32(pb); 258 get_le32(pb); 259 st->id = get_le16(pb) & 0x7f; /* stream id */ 260 // mapping of asf ID to AV stream ID; 261 asf->asfid2avid[st->id] = s->nb_streams - 1; 262 263 get_le32(pb); 264 265 if (test_for_ext_stream_audio) { 266 get_guid(pb, &g); 267 if (!memcmp(&g, &ff_asf_ext_stream_audio_stream, sizeof(GUID))) { 268 type = CODEC_TYPE_AUDIO; 269 is_dvr_ms_audio=1; 270 get_guid(pb, &g); 271 get_le32(pb); 272 get_le32(pb); 273 get_le32(pb); 274 get_guid(pb, &g); 275 get_le32(pb); 276 } 277 } 278 279 st->codec->codec_type = type; 280 if (type == CODEC_TYPE_AUDIO) { 281 get_wav_header(pb, st->codec, type_specific_size); 282 if (is_dvr_ms_audio) { 283 // codec_id and codec_tag are unreliable in dvr_ms 284 // files. Set them later by probing stream. 285 st->codec->codec_id = CODEC_ID_PROBE; 286 st->codec->codec_tag = 0; 287 } 288 if (st->codec->codec_id == CODEC_ID_AAC) { 289 st->need_parsing = AVSTREAM_PARSE_NONE; 290 } else { 291 st->need_parsing = AVSTREAM_PARSE_FULL; 292 } 293 /* We have to init the frame size at some point .... */ 294 pos2 = url_ftell(pb); 295 if (gsize >= (pos2 + 8 - pos1 + 24)) { 296 asf_st->ds_span = get_byte(pb); 297 asf_st->ds_packet_size = get_le16(pb); 298 asf_st->ds_chunk_size = get_le16(pb); 299 get_le16(pb); //ds_data_size 300 get_byte(pb); //ds_silence_data 301 } 302 //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", 303 // asf_st->ds_packet_size, asf_st->ds_chunk_size, 304 // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); 305 if (asf_st->ds_span > 1) { 306 if (!asf_st->ds_chunk_size 307 || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1) 308 || asf_st->ds_packet_size % asf_st->ds_chunk_size) 309 asf_st->ds_span = 0; // disable descrambling 310 } 311 switch (st->codec->codec_id) { 312 case CODEC_ID_MP3: 313 st->codec->frame_size = MPA_FRAME_SIZE; 314 break; 315 case CODEC_ID_PCM_S16LE: 316 case CODEC_ID_PCM_S16BE: 317 case CODEC_ID_PCM_U16LE: 318 case CODEC_ID_PCM_U16BE: 319 case CODEC_ID_PCM_S8: 320 case CODEC_ID_PCM_U8: 321 case CODEC_ID_PCM_ALAW: 322 case CODEC_ID_PCM_MULAW: 323 st->codec->frame_size = 1; 324 break; 325 default: 326 /* This is probably wrong, but it prevents a crash later */ 327 st->codec->frame_size = 1; 328 break; 329 } 330 } else if (type == CODEC_TYPE_VIDEO) { 331 get_le32(pb); 332 get_le32(pb); 333 get_byte(pb); 334 size = get_le16(pb); /* size */ 335 sizeX= get_le32(pb); /* size */ 336 st->codec->width = get_le32(pb); 337 st->codec->height = get_le32(pb); 338 /* not available for asf */ 339 get_le16(pb); /* panes */ 340 st->codec->bits_per_coded_sample = get_le16(pb); /* depth */ 341 tag1 = get_le32(pb); 342 url_fskip(pb, 20); 343// av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX); 344 size= sizeX; 345 if (size > 40) { 346 st->codec->extradata_size = size - 40; 347 st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); 348 get_buffer(pb, st->codec->extradata, st->codec->extradata_size); 349 } 350 351 /* Extract palette from extradata if bpp <= 8 */ 352 /* This code assumes that extradata contains only palette */ 353 /* This is true for all paletted codecs implemented in ffmpeg */ 354 if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { 355 st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); 356#ifdef WORDS_BIGENDIAN 357 for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) 358 st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]); 359#else 360 memcpy(st->codec->palctrl->palette, st->codec->extradata, 361 FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); 362#endif 363 st->codec->palctrl->palette_changed = 1; 364 } 365 366 st->codec->codec_tag = tag1; 367 st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1); 368 if(tag1 == MKTAG('D', 'V', 'R', ' ')) 369 st->need_parsing = AVSTREAM_PARSE_FULL; 370 } 371 pos2 = url_ftell(pb); 372 url_fskip(pb, gsize - (pos2 - pos1 + 24)); 373 } else if (!memcmp(&g, &ff_asf_comment_header, sizeof(GUID))) { 374 int len1, len2, len3, len4, len5; 375 376 len1 = get_le16(pb); 377 len2 = get_le16(pb); 378 len3 = get_le16(pb); 379 len4 = get_le16(pb); 380 len5 = get_le16(pb); 381 get_tag(s, "title" , 0, len1); 382 get_tag(s, "author" , 0, len2); 383 get_tag(s, "copyright", 0, len3); 384 get_tag(s, "comment" , 0, len4); 385 url_fskip(pb, len5); 386 } else if (!memcmp(&g, &stream_bitrate_guid, sizeof(GUID))) { 387 int stream_count = get_le16(pb); 388 int j; 389 390// av_log(s, AV_LOG_ERROR, "stream bitrate properties\n"); 391// av_log(s, AV_LOG_ERROR, "streams %d\n", streams); 392 for(j = 0; j < stream_count; j++) { 393 int flags, bitrate, stream_id; 394 395 flags= get_le16(pb); 396 bitrate= get_le32(pb); 397 stream_id= (flags & 0x7f); 398// av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate); 399 asf->stream_bitrates[stream_id]= bitrate; 400 } 401 } else if (!memcmp(&g, &ff_asf_extended_content_header, sizeof(GUID))) { 402 int desc_count, i; 403 404 desc_count = get_le16(pb); 405 for(i=0;i<desc_count;i++) 406 { 407 int name_len,value_type,value_len; 408 char name[1024]; 409 410 name_len = get_le16(pb); 411 get_str16_nolen(pb, name_len, name, sizeof(name)); 412 value_type = get_le16(pb); 413 value_len = get_le16(pb); 414 get_tag(s, name, value_type, value_len); 415 } 416 } else if (!memcmp(&g, &ff_asf_metadata_header, sizeof(GUID))) { 417 int n, stream_num, name_len, value_len, value_type, value_num; 418 n = get_le16(pb); 419 420 for(i=0;i<n;i++) { 421 char name[1024]; 422 423 get_le16(pb); //lang_list_index 424 stream_num= get_le16(pb); 425 name_len= get_le16(pb); 426 value_type= get_le16(pb); 427 value_len= get_le32(pb); 428 429 get_str16_nolen(pb, name_len, name, sizeof(name)); 430//av_log(s, AV_LOG_ERROR, "%d %d %d %d %d <%s>\n", i, stream_num, name_len, value_type, value_len, name); 431 value_num= get_le16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere 432 url_fskip(pb, value_len - 2); 433 434 if(stream_num<128){ 435 if (!strcmp(name, "AspectRatioX")) dar[stream_num].num= value_num; 436 else if(!strcmp(name, "AspectRatioY")) dar[stream_num].den= value_num; 437 } 438 } 439 } else if (!memcmp(&g, &ff_asf_ext_stream_header, sizeof(GUID))) { 440 int ext_len, payload_ext_ct, stream_ct; 441 uint32_t ext_d, leak_rate, stream_num; 442 int64_t pos_ex_st; 443 pos_ex_st = url_ftell(pb); 444 445 get_le64(pb); // starttime 446 get_le64(pb); // endtime 447 leak_rate = get_le32(pb); // leak-datarate 448 get_le32(pb); // bucket-datasize 449 get_le32(pb); // init-bucket-fullness 450 get_le32(pb); // alt-leak-datarate 451 get_le32(pb); // alt-bucket-datasize 452 get_le32(pb); // alt-init-bucket-fullness 453 get_le32(pb); // max-object-size 454 get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved) 455 stream_num = get_le16(pb); // stream-num 456 get_le16(pb); // stream-language-id-index 457 get_le64(pb); // avg frametime in 100ns units 458 stream_ct = get_le16(pb); //stream-name-count 459 payload_ext_ct = get_le16(pb); //payload-extension-system-count 460 461 if (stream_num < 128) 462 bitrate[stream_num] = leak_rate; 463 464 for (i=0; i<stream_ct; i++){ 465 get_le16(pb); 466 ext_len = get_le16(pb); 467 url_fseek(pb, ext_len, SEEK_CUR); 468 } 469 470 for (i=0; i<payload_ext_ct; i++){ 471 get_guid(pb, &g); 472 ext_d=get_le16(pb); 473 ext_len=get_le32(pb); 474 url_fseek(pb, ext_len, SEEK_CUR); 475 } 476 477 // there could be a optional stream properties object to follow 478 // if so the next iteration will pick it up 479 } else if (!memcmp(&g, &ff_asf_head1_guid, sizeof(GUID))) { 480 int v1, v2; 481 get_guid(pb, &g); 482 v1 = get_le32(pb); 483 v2 = get_le16(pb); 484#if 0 485 } else if (!memcmp(&g, &ff_asf_codec_comment_header, sizeof(GUID))) { 486 int len, v1, n, num; 487 char str[256], *q; 488 char tag[16]; 489 490 get_guid(pb, &g); 491 print_guid(&g); 492 493 n = get_le32(pb); 494 for(i=0;i<n;i++) { 495 num = get_le16(pb); /* stream number */ 496 get_str16(pb, str, sizeof(str)); 497 get_str16(pb, str, sizeof(str)); 498 len = get_le16(pb); 499 q = tag; 500 while (len > 0) { 501 v1 = get_byte(pb); 502 if ((q - tag) < sizeof(tag) - 1) 503 *q++ = v1; 504 len--; 505 } 506 *q = '\0'; 507 } 508#endif 509 } else if (url_feof(pb)) { 510 return -1; 511 } else { 512 url_fseek(pb, gsize - 24, SEEK_CUR); 513 } 514 } 515 get_guid(pb, &g); 516 get_le64(pb); 517 get_byte(pb); 518 get_byte(pb); 519 if (url_feof(pb)) 520 return -1; 521 asf->data_offset = url_ftell(pb); 522 asf->packet_size_left = 0; 523 524 525 for(i=0; i<128; i++){ 526 int stream_num= asf->asfid2avid[i]; 527 if(stream_num>=0){ 528 AVStream *st = s->streams[stream_num]; 529 if (!st->codec->bit_rate) 530 st->codec->bit_rate = bitrate[i]; 531 if (dar[i].num > 0 && dar[i].den > 0) 532 av_reduce(&st->sample_aspect_ratio.num, 533 &st->sample_aspect_ratio.den, 534 dar[i].num, dar[i].den, INT_MAX); 535//av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); 536 } 537 } 538 539 return 0; 540} 541 542#define DO_2BITS(bits, var, defval) \ 543 switch (bits & 3) \ 544 { \ 545 case 3: var = get_le32(pb); rsize += 4; break; \ 546 case 2: var = get_le16(pb); rsize += 2; break; \ 547 case 1: var = get_byte(pb); rsize++; break; \ 548 default: var = defval; break; \ 549 } 550 551int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb) 552{ 553 ASFContext *asf = s->priv_data; 554 uint32_t packet_length, padsize; 555 int rsize = 8; 556 int c, d, e, off; 557 558 off= 32768; 559 if (s->packet_size > 0) 560 off= (url_ftell(pb) - s->data_offset) % s->packet_size + 3; 561 562 c=d=e=-1; 563 while(off-- > 0){ 564 c=d; d=e; 565 e= get_byte(pb); 566 if(c == 0x82 && !d && !e) 567 break; 568 } 569 570 if (c != 0x82) { 571 if (!url_feof(pb)) 572 av_log(s, AV_LOG_ERROR, "ff asf bad header %x at:%"PRId64"\n", c, url_ftell(pb)); 573 } 574 if ((c & 0x8f) == 0x82) { 575 if (d || e) { 576 if (!url_feof(pb)) 577 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n"); 578 return -1; 579 } 580 c= get_byte(pb); 581 d= get_byte(pb); 582 rsize+=3; 583 }else{ 584 url_fseek(pb, -1, SEEK_CUR); //FIXME 585 } 586 587 asf->packet_flags = c; 588 asf->packet_property = d; 589 590 DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size); 591 DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored 592 DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length 593 594 //the following checks prevent overflows and infinite loops 595 if(!packet_length || packet_length >= (1U<<29)){ 596 av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, url_ftell(pb)); 597 return -1; 598 } 599 if(padsize >= packet_length){ 600 av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, url_ftell(pb)); 601 return -1; 602 } 603 604 asf->packet_timestamp = get_le32(pb); 605 get_le16(pb); /* duration */ 606 // rsize has at least 11 bytes which have to be present 607 608 if (asf->packet_flags & 0x01) { 609 asf->packet_segsizetype = get_byte(pb); rsize++; 610 asf->packet_segments = asf->packet_segsizetype & 0x3f; 611 } else { 612 asf->packet_segments = 1; 613 asf->packet_segsizetype = 0x80; 614 } 615 asf->packet_size_left = packet_length - padsize - rsize; 616 if (packet_length < asf->hdr.min_pktsize) 617 padsize += asf->hdr.min_pktsize - packet_length; 618 asf->packet_padsize = padsize; 619 dprintf(s, "packet: size=%d padsize=%d left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left); 620 return 0; 621} 622 623/** 624 * 625 * @return <0 if error 626 */ 627static int asf_read_frame_header(AVFormatContext *s, ByteIOContext *pb){ 628 ASFContext *asf = s->priv_data; 629 int rsize = 1; 630 int num = get_byte(pb); 631 int64_t ts0, ts1; 632 633 asf->packet_segments--; 634 asf->packet_key_frame = num >> 7; 635 asf->stream_index = asf->asfid2avid[num & 0x7f]; 636 // sequence should be ignored! 637 DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0); 638 DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); 639 DO_2BITS(asf->packet_property, asf->packet_replic_size, 0); 640//printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size); 641 if (asf->packet_replic_size >= 8) { 642 asf->packet_obj_size = get_le32(pb); 643 if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){ 644 av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n"); 645 return -1; 646 } 647 asf->packet_frag_timestamp = get_le32(pb); // timestamp 648 if(asf->packet_replic_size >= 8+38+4){ 649// for(i=0; i<asf->packet_replic_size-8; i++) 650// av_log(s, AV_LOG_DEBUG, "%02X ",get_byte(pb)); 651// av_log(s, AV_LOG_DEBUG, "\n"); 652 url_fskip(pb, 10); 653 ts0= get_le64(pb); 654 ts1= get_le64(pb); 655 url_fskip(pb, 12); 656 get_le32(pb); 657 url_fskip(pb, asf->packet_replic_size - 8 - 38 - 4); 658 if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000; 659 else asf->packet_frag_timestamp= AV_NOPTS_VALUE; 660 }else 661 url_fskip(pb, asf->packet_replic_size - 8); 662 rsize += asf->packet_replic_size; // FIXME - check validity 663 } else if (asf->packet_replic_size==1){ 664 // multipacket - frag_offset is beginning timestamp 665 asf->packet_time_start = asf->packet_frag_offset; 666 asf->packet_frag_offset = 0; 667 asf->packet_frag_timestamp = asf->packet_timestamp; 668 669 asf->packet_time_delta = get_byte(pb); 670 rsize++; 671 }else if(asf->packet_replic_size!=0){ 672 av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size); 673 return -1; 674 } 675 if (asf->packet_flags & 0x01) { 676 DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal 677 if(asf->packet_frag_size > asf->packet_size_left - rsize){ 678 av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid\n"); 679 return -1; 680 } 681 //printf("Fragsize %d\n", asf->packet_frag_size); 682 } else { 683 asf->packet_frag_size = asf->packet_size_left - rsize; 684 //printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize); 685 } 686 if (asf->packet_replic_size == 1) { 687 asf->packet_multi_size = asf->packet_frag_size; 688 if (asf->packet_multi_size > asf->packet_size_left) 689 return -1; 690 } 691 asf->packet_size_left -= rsize; 692 //printf("___objsize____ %d %d rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize); 693 694 return 0; 695} 696 697int ff_asf_parse_packet(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt) 698{ 699 ASFContext *asf = s->priv_data; 700 ASFStream *asf_st = 0; 701 for (;;) { 702 if(url_feof(pb)) 703 return AVERROR(EIO); 704 if (asf->packet_size_left < FRAME_HEADER_SIZE 705 || asf->packet_segments < 1) { 706 //asf->packet_size_left <= asf->packet_padsize) { 707 int ret = asf->packet_size_left + asf->packet_padsize; 708 //printf("PacketLeftSize:%d Pad:%d Pos:%"PRId64"\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb)); 709 assert(ret>=0); 710 /* fail safe */ 711 url_fskip(pb, ret); 712 713 asf->packet_pos= url_ftell(pb); 714 if (asf->data_object_size != (uint64_t)-1 && 715 (asf->packet_pos - asf->data_object_offset >= asf->data_object_size)) 716 return AVERROR(EIO); /* Do not exceed the size of the data object */ 717 return 1; 718 } 719 if (asf->packet_time_start == 0) { 720 if(asf_read_frame_header(s, pb) < 0){ 721 asf->packet_segments= 0; 722 continue; 723 } 724 if (asf->stream_index < 0 725 || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL 726 || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY) 727 ) { 728 asf->packet_time_start = 0; 729 /* unhandled packet (should not happen) */ 730 url_fskip(pb, asf->packet_frag_size); 731 asf->packet_size_left -= asf->packet_frag_size; 732 if(asf->stream_index < 0) 733 av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size); 734 continue; 735 } 736 asf->asf_st = s->streams[asf->stream_index]->priv_data; 737 } 738 asf_st = asf->asf_st; 739 740 if (asf->packet_replic_size == 1) { 741 // frag_offset is here used as the beginning timestamp 742 asf->packet_frag_timestamp = asf->packet_time_start; 743 asf->packet_time_start += asf->packet_time_delta; 744 asf->packet_obj_size = asf->packet_frag_size = get_byte(pb); 745 asf->packet_size_left--; 746 asf->packet_multi_size--; 747 if (asf->packet_multi_size < asf->packet_obj_size) 748 { 749 asf->packet_time_start = 0; 750 url_fskip(pb, asf->packet_multi_size); 751 asf->packet_size_left -= asf->packet_multi_size; 752 continue; 753 } 754 asf->packet_multi_size -= asf->packet_obj_size; 755 //printf("COMPRESS size %d %d %d ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size); 756 } 757 if( /*asf->packet_frag_size == asf->packet_obj_size*/ 758 asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size 759 && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){ 760 av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n", 761 asf_st->frag_offset, asf->packet_frag_size, 762 asf->packet_obj_size, asf_st->pkt.size); 763 asf->packet_obj_size= asf_st->pkt.size; 764 } 765 766 if ( asf_st->pkt.size != asf->packet_obj_size 767 || asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { //FIXME is this condition sufficient? 768 if(asf_st->pkt.data){ 769 av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", asf_st->pkt.size, asf->packet_obj_size); 770 asf_st->frag_offset = 0; 771 av_free_packet(&asf_st->pkt); 772 } 773 /* new packet */ 774 av_new_packet(&asf_st->pkt, asf->packet_obj_size); 775 asf_st->seq = asf->packet_seq; 776 asf_st->pkt.dts = asf->packet_frag_timestamp; 777 asf_st->pkt.stream_index = asf->stream_index; 778 asf_st->pkt.pos = 779 asf_st->packet_pos= asf->packet_pos; 780//printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", 781//asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY, 782//s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO, asf->packet_obj_size); 783 if (s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO) 784 asf->packet_key_frame = 1; 785 if (asf->packet_key_frame) 786 asf_st->pkt.flags |= PKT_FLAG_KEY; 787 } 788 789 /* read data */ 790 //printf("READ PACKET s:%d os:%d o:%d,%d l:%d DATA:%p\n", 791 // s->packet_size, asf_st->pkt.size, asf->packet_frag_offset, 792 // asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data); 793 asf->packet_size_left -= asf->packet_frag_size; 794 if (asf->packet_size_left < 0) 795 continue; 796 797 if( asf->packet_frag_offset >= asf_st->pkt.size 798 || asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset){ 799 av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n", 800 asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size); 801 continue; 802 } 803 804 get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset, 805 asf->packet_frag_size); 806 if (s->key && s->keylen == 20) 807 ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset, 808 asf->packet_frag_size); 809 asf_st->frag_offset += asf->packet_frag_size; 810 /* test if whole packet is read */ 811 if (asf_st->frag_offset == asf_st->pkt.size) { 812 //workaround for macroshit radio DVR-MS files 813 if( s->streams[asf->stream_index]->codec->codec_id == CODEC_ID_MPEG2VIDEO 814 && asf_st->pkt.size > 100){ 815 int i; 816 for(i=0; i<asf_st->pkt.size && !asf_st->pkt.data[i]; i++); 817 if(i == asf_st->pkt.size){ 818 av_log(s, AV_LOG_DEBUG, "discarding ms fart\n"); 819 asf_st->frag_offset = 0; 820 av_free_packet(&asf_st->pkt); 821 continue; 822 } 823 } 824 825 /* return packet */ 826 if (asf_st->ds_span > 1) { 827 if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){ 828 av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * ds_span (%d %d %d)\n", asf_st->pkt.size, asf_st->ds_packet_size, asf_st->ds_span); 829 }else{ 830 /* packet descrambling */ 831 uint8_t *newdata = av_malloc(asf_st->pkt.size); 832 if (newdata) { 833 int offset = 0; 834 while (offset < asf_st->pkt.size) { 835 int off = offset / asf_st->ds_chunk_size; 836 int row = off / asf_st->ds_span; 837 int col = off % asf_st->ds_span; 838 int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size; 839 //printf("off:%d row:%d col:%d idx:%d\n", off, row, col, idx); 840 841 assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size); 842 assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size); 843 memcpy(newdata + offset, 844 asf_st->pkt.data + idx * asf_st->ds_chunk_size, 845 asf_st->ds_chunk_size); 846 offset += asf_st->ds_chunk_size; 847 } 848 av_free(asf_st->pkt.data); 849 asf_st->pkt.data = newdata; 850 } 851 } 852 } 853 asf_st->frag_offset = 0; 854 *pkt= asf_st->pkt; 855 //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size); 856 asf_st->pkt.size = 0; 857 asf_st->pkt.data = 0; 858 break; // packet completed 859 } 860 } 861 return 0; 862} 863 864static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) 865{ 866 ASFContext *asf = s->priv_data; 867 868 for (;;) { 869 int ret; 870 871 /* parse cached packets, if any */ 872 if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0) 873 return ret; 874 if ((ret = ff_asf_get_packet(s, s->pb)) < 0) 875 assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1); 876 asf->packet_time_start = 0; 877 } 878 879 return 0; 880} 881 882// Added to support seeking after packets have been read 883// If information is not reset, read_packet fails due to 884// leftover information from previous reads 885static void asf_reset_header(AVFormatContext *s) 886{ 887 ASFContext *asf = s->priv_data; 888 ASFStream *asf_st; 889 int i; 890 891 asf->packet_nb_frames = 0; 892 asf->packet_size_left = 0; 893 asf->packet_segments = 0; 894 asf->packet_flags = 0; 895 asf->packet_property = 0; 896 asf->packet_timestamp = 0; 897 asf->packet_segsizetype = 0; 898 asf->packet_segments = 0; 899 asf->packet_seq = 0; 900 asf->packet_replic_size = 0; 901 asf->packet_key_frame = 0; 902 asf->packet_padsize = 0; 903 asf->packet_frag_offset = 0; 904 asf->packet_frag_size = 0; 905 asf->packet_frag_timestamp = 0; 906 asf->packet_multi_size = 0; 907 asf->packet_obj_size = 0; 908 asf->packet_time_delta = 0; 909 asf->packet_time_start = 0; 910 911 for(i=0; i<s->nb_streams; i++){ 912 asf_st= s->streams[i]->priv_data; 913 av_free_packet(&asf_st->pkt); 914 asf_st->frag_offset=0; 915 asf_st->seq=0; 916 } 917 asf->asf_st= NULL; 918} 919 920static int asf_read_close(AVFormatContext *s) 921{ 922 int i; 923 924 asf_reset_header(s); 925 for(i=0;i<s->nb_streams;i++) { 926 AVStream *st = s->streams[i]; 927 av_free(st->codec->palctrl); 928 } 929 return 0; 930} 931 932static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit) 933{ 934 AVPacket pkt1, *pkt = &pkt1; 935 ASFStream *asf_st; 936 int64_t pts; 937 int64_t pos= *ppos; 938 int i; 939 int64_t start_pos[s->nb_streams]; 940 941 for(i=0; i<s->nb_streams; i++){ 942 start_pos[i]= pos; 943 } 944 945 if (s->packet_size > 0) 946 pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset; 947 *ppos= pos; 948 url_fseek(s->pb, pos, SEEK_SET); 949 950//printf("asf_read_pts\n"); 951 asf_reset_header(s); 952 for(;;){ 953 if (av_read_frame(s, pkt) < 0){ 954 av_log(s, AV_LOG_INFO, "asf_read_pts failed\n"); 955 return AV_NOPTS_VALUE; 956 } 957 958 pts= pkt->pts; 959 960 av_free_packet(pkt); 961 if(pkt->flags&PKT_FLAG_KEY){ 962 i= pkt->stream_index; 963 964 asf_st= s->streams[i]->priv_data; 965 966// assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0); 967 pos= asf_st->packet_pos; 968 969 av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME); 970 start_pos[i]= asf_st->packet_pos + 1; 971 972 if(pkt->stream_index == stream_index) 973 break; 974 } 975 } 976 977 *ppos= pos; 978//printf("found keyframe at %"PRId64" stream %d stamp:%"PRId64"\n", *ppos, stream_index, pts); 979 980 return pts; 981} 982 983static void asf_build_simple_index(AVFormatContext *s, int stream_index) 984{ 985 GUID g; 986 ASFContext *asf = s->priv_data; 987 int64_t gsize, itime; 988 int64_t pos, current_pos, index_pts; 989 int i; 990 int pct,ict; 991 992 current_pos = url_ftell(s->pb); 993 994 url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET); 995 get_guid(s->pb, &g); 996 if (!memcmp(&g, &index_guid, sizeof(GUID))) { 997 gsize = get_le64(s->pb); 998 get_guid(s->pb, &g); 999 itime=get_le64(s->pb); 1000 pct=get_le32(s->pb); 1001 ict=get_le32(s->pb); 1002 av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict); 1003 1004 for (i=0;i<ict;i++){ 1005 int pktnum=get_le32(s->pb); 1006 int pktct =get_le16(s->pb); 1007 av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct); 1008 1009 pos=s->data_offset + s->packet_size*(int64_t)pktnum; 1010 index_pts=av_rescale(itime, i, 10000); 1011 1012 av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME); 1013 } 1014 asf->index_read= 1; 1015 } 1016 url_fseek(s->pb, current_pos, SEEK_SET); 1017} 1018 1019static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags) 1020{ 1021 ASFContext *asf = s->priv_data; 1022 AVStream *st = s->streams[stream_index]; 1023 int64_t pos; 1024 int index; 1025 1026 if (s->packet_size <= 0) 1027 return -1; 1028 1029 /* Try using the protocol's read_seek if available */ 1030 if(s->pb) { 1031 int ret = av_url_read_fseek(s->pb, stream_index, pts, flags); 1032 if(ret >= 0) 1033 asf_reset_header(s); 1034 if (ret != AVERROR(ENOSYS)) 1035 return ret; 1036 } 1037 1038 if (!asf->index_read) 1039 asf_build_simple_index(s, stream_index); 1040 1041 if(!(asf->index_read && st->index_entries)){ 1042 if(av_seek_frame_binary(s, stream_index, pts, flags)<0) 1043 return -1; 1044 }else{ 1045 index= av_index_search_timestamp(st, pts, flags); 1046 if(index<0) 1047 return -1; 1048 1049 /* find the position */ 1050 pos = st->index_entries[index].pos; 1051 pts = st->index_entries[index].timestamp; 1052 1053 // various attempts to find key frame have failed so far 1054 // asf_reset_header(s); 1055 // url_fseek(s->pb, pos, SEEK_SET); 1056 // key_pos = pos; 1057 // for(i=0;i<16;i++){ 1058 // pos = url_ftell(s->pb); 1059 // if (av_read_frame(s, &pkt) < 0){ 1060 // av_log(s, AV_LOG_INFO, "seek failed\n"); 1061 // return -1; 1062 // } 1063 // asf_st = s->streams[stream_index]->priv_data; 1064 // pos += st->parser->frame_offset; 1065 // 1066 // if (pkt.size > b) { 1067 // b = pkt.size; 1068 // key_pos = pos; 1069 // } 1070 // 1071 // av_free_packet(&pkt); 1072 // } 1073 1074 /* do the seek */ 1075 av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos); 1076 url_fseek(s->pb, pos, SEEK_SET); 1077 } 1078 asf_reset_header(s); 1079 return 0; 1080} 1081 1082AVInputFormat asf_demuxer = { 1083 "asf", 1084 NULL_IF_CONFIG_SMALL("ASF format"), 1085 sizeof(ASFContext), 1086 asf_probe, 1087 asf_read_header, 1088 asf_read_packet, 1089 asf_read_close, 1090 asf_read_seek, 1091 asf_read_pts, 1092 .metadata_conv = ff_asf_metadata_conv, 1093}; 1094