00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avformat.h"
00022 #include "riff.h"
00023 #include "mpegaudio.h"
00024 #include "asf.h"
00025 #include "common.h"
00026 #include "asfcrypt.h"
00027
00028 extern void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format);
00029
00030 #undef NDEBUG
00031 #include <assert.h>
00032
00033 #define FRAME_HEADER_SIZE 17
00034
00035
00036 static const GUID index_guid = {
00037 0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb
00038 };
00039
00040 static const GUID stream_bitrate_guid = {
00041 0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2
00042 };
00043
00044
00045
00046
00047
00048 #ifdef DEBUG
00049 #define PRINT_IF_GUID(g,cmp) \
00050 if (!memcmp(g, &cmp, sizeof(GUID))) \
00051 printf("(GUID: %s) ", #cmp)
00052
00053 static void print_guid(const GUID *g)
00054 {
00055 int i;
00056 PRINT_IF_GUID(g, asf_header);
00057 else PRINT_IF_GUID(g, file_header);
00058 else PRINT_IF_GUID(g, stream_header);
00059 else PRINT_IF_GUID(g, audio_stream);
00060 else PRINT_IF_GUID(g, audio_conceal_none);
00061 else PRINT_IF_GUID(g, video_stream);
00062 else PRINT_IF_GUID(g, video_conceal_none);
00063 else PRINT_IF_GUID(g, command_stream);
00064 else PRINT_IF_GUID(g, comment_header);
00065 else PRINT_IF_GUID(g, codec_comment_header);
00066 else PRINT_IF_GUID(g, codec_comment1_header);
00067 else PRINT_IF_GUID(g, data_header);
00068 else PRINT_IF_GUID(g, index_guid);
00069 else PRINT_IF_GUID(g, head1_guid);
00070 else PRINT_IF_GUID(g, head2_guid);
00071 else PRINT_IF_GUID(g, my_guid);
00072 else PRINT_IF_GUID(g, ext_stream_header);
00073 else PRINT_IF_GUID(g, extended_content_header);
00074 else PRINT_IF_GUID(g, ext_stream_embed_stream_header);
00075 else PRINT_IF_GUID(g, ext_stream_audio_stream);
00076 else PRINT_IF_GUID(g, metadata_header);
00077 else PRINT_IF_GUID(g, stream_bitrate_guid);
00078 else
00079 printf("(GUID: unknown) ");
00080 for(i=0;i<16;i++)
00081 printf(" 0x%02x,", (*g)[i]);
00082 printf("}\n");
00083 }
00084 #undef PRINT_IF_GUID
00085 #endif
00086
00087 static void get_guid(ByteIOContext *s, GUID *g)
00088 {
00089 assert(sizeof(*g) == 16);
00090 get_buffer(s, *g, sizeof(*g));
00091 }
00092
00093 #if 0
00094 static void get_str16(ByteIOContext *pb, char *buf, int buf_size)
00095 {
00096 int len, c;
00097 char *q;
00098
00099 len = get_le16(pb);
00100 q = buf;
00101 while (len > 0) {
00102 c = get_le16(pb);
00103 if ((q - buf) < buf_size - 1)
00104 *q++ = c;
00105 len--;
00106 }
00107 *q = '\0';
00108 }
00109 #endif
00110
00111 static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size)
00112 {
00113 char* q = buf;
00114 len /= 2;
00115 while (len--) {
00116 uint8_t tmp;
00117 PUT_UTF8(get_le16(pb), tmp, if (q - buf < buf_size - 1) *q++ = tmp;)
00118 }
00119 *q = '\0';
00120 }
00121
00122 static int asf_probe(AVProbeData *pd)
00123 {
00124
00125 if (!memcmp(pd->buf, &asf_header, sizeof(GUID)))
00126 return AVPROBE_SCORE_MAX;
00127 else
00128 return 0;
00129 }
00130
00131 static int get_value(ByteIOContext *pb, int type){
00132 switch(type){
00133 case 2: return get_le32(pb);
00134 case 3: return get_le32(pb);
00135 case 4: return get_le64(pb);
00136 case 5: return get_le16(pb);
00137 default:return INT_MIN;
00138 }
00139 }
00140
00141 static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
00142 {
00143 ASFContext *asf = s->priv_data;
00144 GUID g;
00145 ByteIOContext *pb = s->pb;
00146 AVStream *st;
00147 ASFStream *asf_st;
00148 int size, i;
00149 int64_t gsize;
00150 AVRational dar[128];
00151 uint32_t bitrate[128];
00152
00153 memset(dar, 0, sizeof(dar));
00154 memset(bitrate, 0, sizeof(bitrate));
00155
00156 get_guid(pb, &g);
00157 if (memcmp(&g, &asf_header, sizeof(GUID)))
00158 goto fail;
00159 get_le64(pb);
00160 get_le32(pb);
00161 get_byte(pb);
00162 get_byte(pb);
00163 memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
00164 for(;;) {
00165 get_guid(pb, &g);
00166 gsize = get_le64(pb);
00167 #ifdef DEBUG
00168 printf("%08"PRIx64": ", url_ftell(pb) - 24);
00169 print_guid(&g);
00170 printf(" size=0x%"PRIx64"\n", gsize);
00171 #endif
00172 if (!memcmp(&g, &data_header, sizeof(GUID))) {
00173 asf->data_object_offset = url_ftell(pb);
00174
00175 if (!(asf->hdr.flags & 0x01) && gsize >= 100) {
00176 asf->data_object_size = gsize - 24;
00177 } else {
00178 asf->data_object_size = (uint64_t)-1;
00179 }
00180 break;
00181 }
00182 if (gsize < 24)
00183 goto fail;
00184 if (!memcmp(&g, &file_header, sizeof(GUID))) {
00185 get_guid(pb, &asf->hdr.guid);
00186 asf->hdr.file_size = get_le64(pb);
00187 asf->hdr.create_time = get_le64(pb);
00188 asf->nb_packets = get_le64(pb);
00189 asf->hdr.send_time = get_le64(pb);
00190 asf->hdr.play_time = get_le64(pb);
00191 asf->hdr.preroll = get_le32(pb);
00192 asf->hdr.ignore = get_le32(pb);
00193 asf->hdr.flags = get_le32(pb);
00194 asf->hdr.min_pktsize = get_le32(pb);
00195 asf->hdr.max_pktsize = get_le32(pb);
00196 asf->hdr.max_bitrate = get_le32(pb);
00197 asf->packet_size = asf->hdr.max_pktsize;
00198 } else if (!memcmp(&g, &stream_header, sizeof(GUID))) {
00199 int type, type_specific_size, sizeX;
00200 uint64_t total_size;
00201 unsigned int tag1;
00202 int64_t pos1, pos2, start_time;
00203 int test_for_ext_stream_audio, is_dvr_ms_audio=0;
00204
00205 pos1 = url_ftell(pb);
00206
00207 st = av_new_stream(s, 0);
00208 if (!st)
00209 goto fail;
00210 av_set_pts_info(st, 32, 1, 1000);
00211 asf_st = av_mallocz(sizeof(ASFStream));
00212 if (!asf_st)
00213 goto fail;
00214 st->priv_data = asf_st;
00215 start_time = asf->hdr.preroll;
00216
00217 if(!(asf->hdr.flags & 0x01)) {
00218 st->duration = asf->hdr.send_time /
00219 (10000000 / 1000) - start_time;
00220 }
00221 get_guid(pb, &g);
00222
00223 test_for_ext_stream_audio = 0;
00224 if (!memcmp(&g, &audio_stream, sizeof(GUID))) {
00225 type = CODEC_TYPE_AUDIO;
00226 } else if (!memcmp(&g, &video_stream, sizeof(GUID))) {
00227 type = CODEC_TYPE_VIDEO;
00228 } else if (!memcmp(&g, &command_stream, sizeof(GUID))) {
00229 type = CODEC_TYPE_UNKNOWN;
00230 } else if (!memcmp(&g, &ext_stream_embed_stream_header, sizeof(GUID))) {
00231 test_for_ext_stream_audio = 1;
00232 type = CODEC_TYPE_UNKNOWN;
00233 } else {
00234 goto fail;
00235 }
00236 get_guid(pb, &g);
00237 total_size = get_le64(pb);
00238 type_specific_size = get_le32(pb);
00239 get_le32(pb);
00240 st->id = get_le16(pb) & 0x7f;
00241
00242 asf->asfid2avid[st->id] = s->nb_streams - 1;
00243
00244 get_le32(pb);
00245
00246 if (test_for_ext_stream_audio) {
00247 get_guid(pb, &g);
00248 if (!memcmp(&g, &ext_stream_audio_stream, sizeof(GUID))) {
00249 type = CODEC_TYPE_AUDIO;
00250 is_dvr_ms_audio=1;
00251 get_guid(pb, &g);
00252 get_le32(pb);
00253 get_le32(pb);
00254 get_le32(pb);
00255 get_guid(pb, &g);
00256 get_le32(pb);
00257 }
00258 }
00259
00260 st->codec->codec_type = type;
00261 if (type == CODEC_TYPE_AUDIO) {
00262 get_wav_header(pb, st->codec, type_specific_size);
00263 if (is_dvr_ms_audio) {
00264
00265
00266 st->codec->codec_id = CODEC_ID_NONE;
00267 st->codec->codec_tag = 0;
00268 }
00269 st->need_parsing = AVSTREAM_PARSE_FULL;
00270
00271 pos2 = url_ftell(pb);
00272 if (gsize >= (pos2 + 8 - pos1 + 24)) {
00273 asf_st->ds_span = get_byte(pb);
00274 asf_st->ds_packet_size = get_le16(pb);
00275 asf_st->ds_chunk_size = get_le16(pb);
00276 get_le16(pb);
00277 get_byte(pb);
00278 }
00279
00280
00281
00282 if (asf_st->ds_span > 1) {
00283 if (!asf_st->ds_chunk_size
00284 || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
00285 || asf_st->ds_packet_size % asf_st->ds_chunk_size)
00286 asf_st->ds_span = 0;
00287 }
00288 switch (st->codec->codec_id) {
00289 case CODEC_ID_MP3:
00290 st->codec->frame_size = MPA_FRAME_SIZE;
00291 break;
00292 case CODEC_ID_PCM_S16LE:
00293 case CODEC_ID_PCM_S16BE:
00294 case CODEC_ID_PCM_U16LE:
00295 case CODEC_ID_PCM_U16BE:
00296 case CODEC_ID_PCM_S8:
00297 case CODEC_ID_PCM_U8:
00298 case CODEC_ID_PCM_ALAW:
00299 case CODEC_ID_PCM_MULAW:
00300 st->codec->frame_size = 1;
00301 break;
00302 default:
00303
00304 st->codec->frame_size = 1;
00305 break;
00306 }
00307 } else if (type == CODEC_TYPE_VIDEO) {
00308 get_le32(pb);
00309 get_le32(pb);
00310 get_byte(pb);
00311 size = get_le16(pb);
00312 sizeX= get_le32(pb);
00313 st->codec->width = get_le32(pb);
00314 st->codec->height = get_le32(pb);
00315
00316 get_le16(pb);
00317 st->codec->bits_per_sample = get_le16(pb);
00318 tag1 = get_le32(pb);
00319 url_fskip(pb, 20);
00320
00321 size= sizeX;
00322 if (size > 40) {
00323 st->codec->extradata_size = size - 40;
00324 st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
00325 get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
00326 }
00327
00328
00329
00330
00331 if (st->codec->extradata_size && (st->codec->bits_per_sample <= 8)) {
00332 st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
00333 #ifdef WORDS_BIGENDIAN
00334 for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
00335 st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]);
00336 #else
00337 memcpy(st->codec->palctrl->palette, st->codec->extradata,
00338 FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
00339 #endif
00340 st->codec->palctrl->palette_changed = 1;
00341 }
00342
00343 st->codec->codec_tag = tag1;
00344 st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1);
00345 if(tag1 == MKTAG('D', 'V', 'R', ' '))
00346 st->need_parsing = AVSTREAM_PARSE_FULL;
00347 }
00348 pos2 = url_ftell(pb);
00349 url_fskip(pb, gsize - (pos2 - pos1 + 24));
00350 } else if (!memcmp(&g, &comment_header, sizeof(GUID))) {
00351 int len1, len2, len3, len4, len5;
00352
00353 len1 = get_le16(pb);
00354 len2 = get_le16(pb);
00355 len3 = get_le16(pb);
00356 len4 = get_le16(pb);
00357 len5 = get_le16(pb);
00358 get_str16_nolen(pb, len1, s->title , sizeof(s->title));
00359 get_str16_nolen(pb, len2, s->author , sizeof(s->author));
00360 get_str16_nolen(pb, len3, s->copyright, sizeof(s->copyright));
00361 get_str16_nolen(pb, len4, s->comment , sizeof(s->comment));
00362 url_fskip(pb, len5);
00363 } else if (!memcmp(&g, &stream_bitrate_guid, sizeof(GUID))) {
00364 int stream_count = get_le16(pb);
00365 int j;
00366
00367
00368
00369 for(j = 0; j < stream_count; j++) {
00370 int flags, bitrate, stream_id;
00371
00372 flags= get_le16(pb);
00373 bitrate= get_le32(pb);
00374 stream_id= (flags & 0x7f);
00375
00376 asf->stream_bitrates[stream_id]= bitrate;
00377 }
00378 } else if (!memcmp(&g, &extended_content_header, sizeof(GUID))) {
00379 int desc_count, i;
00380
00381 desc_count = get_le16(pb);
00382 for(i=0;i<desc_count;i++)
00383 {
00384 int name_len,value_type,value_len;
00385 uint64_t value_num = 0;
00386 char name[1024];
00387
00388 name_len = get_le16(pb);
00389 get_str16_nolen(pb, name_len, name, sizeof(name));
00390 value_type = get_le16(pb);
00391 value_len = get_le16(pb);
00392 if ((value_type == 0) || (value_type == 1))
00393 {
00394 if (!strcmp(name,"WM/AlbumTitle")) get_str16_nolen(pb, value_len, s->album, sizeof(s->album));
00395 else if(!strcmp(name,"WM/Genre" )) get_str16_nolen(pb, value_len, s->genre, sizeof(s->genre));
00396 else if(!strcmp(name,"WM/Year" )) {
00397 char year[8];
00398 get_str16_nolen(pb, value_len, year, sizeof(year));
00399 s->year = atoi(year);
00400 }
00401 else if(!strcmp(name,"WM/Track") && s->track == 0) {
00402 char track[8];
00403 get_str16_nolen(pb, value_len, track, sizeof(track));
00404 s->track = strtol(track, NULL, 10) + 1;
00405 }
00406 else if(!strcmp(name,"WM/TrackNumber")) {
00407 char track[8];
00408 get_str16_nolen(pb, value_len, track, sizeof(track));
00409 s->track = strtol(track, NULL, 10);
00410 }
00411 else url_fskip(pb, value_len);
00412 }
00413 if ((value_type >= 2) && (value_type <= 5))
00414 {
00415 value_num= get_value(pb, value_type);
00416 if (!strcmp(name,"WM/Track" ) && s->track == 0) s->track = value_num + 1;
00417 if (!strcmp(name,"WM/TrackNumber")) s->track = value_num;
00418 }
00419 }
00420 } else if (!memcmp(&g, &metadata_header, sizeof(GUID))) {
00421 int n, stream_num, name_len, value_len, value_type, value_num;
00422 n = get_le16(pb);
00423
00424 for(i=0;i<n;i++) {
00425 char name[1024];
00426
00427 get_le16(pb);
00428 stream_num= get_le16(pb);
00429 name_len= get_le16(pb);
00430 value_type= get_le16(pb);
00431 value_len= get_le32(pb);
00432
00433 get_str16_nolen(pb, name_len, name, sizeof(name));
00434
00435 value_num= get_le16(pb);
00436 url_fskip(pb, value_len - 2);
00437
00438 if(stream_num<128){
00439 if (!strcmp(name, "AspectRatioX")) dar[stream_num].num= value_num;
00440 else if(!strcmp(name, "AspectRatioY")) dar[stream_num].den= value_num;
00441 }
00442 }
00443 } else if (!memcmp(&g, &ext_stream_header, sizeof(GUID))) {
00444 int ext_len, payload_ext_ct, stream_ct;
00445 uint32_t ext_d, leak_rate, stream_num;
00446 int64_t pos_ex_st;
00447 pos_ex_st = url_ftell(pb);
00448
00449 get_le64(pb);
00450 get_le64(pb);
00451 leak_rate = get_le32(pb);
00452 get_le32(pb);
00453 get_le32(pb);
00454 get_le32(pb);
00455 get_le32(pb);
00456 get_le32(pb);
00457 get_le32(pb);
00458 get_le32(pb);
00459 stream_num = get_le16(pb);
00460 get_le16(pb);
00461 get_le64(pb);
00462 stream_ct = get_le16(pb);
00463 payload_ext_ct = get_le16(pb);
00464
00465 if (stream_num < 128)
00466 bitrate[stream_num] = leak_rate;
00467
00468 for (i=0; i<stream_ct; i++){
00469 get_le16(pb);
00470 ext_len = get_le16(pb);
00471 url_fseek(pb, ext_len, SEEK_CUR);
00472 }
00473
00474 for (i=0; i<payload_ext_ct; i++){
00475 get_guid(pb, &g);
00476 ext_d=get_le16(pb);
00477 ext_len=get_le32(pb);
00478 url_fseek(pb, ext_len, SEEK_CUR);
00479 }
00480
00481
00482
00483 } else if (!memcmp(&g, &head1_guid, sizeof(GUID))) {
00484 int v1, v2;
00485 get_guid(pb, &g);
00486 v1 = get_le32(pb);
00487 v2 = get_le16(pb);
00488 #if 0
00489 } else if (!memcmp(&g, &codec_comment_header, sizeof(GUID))) {
00490 int len, v1, n, num;
00491 char str[256], *q;
00492 char tag[16];
00493
00494 get_guid(pb, &g);
00495 print_guid(&g);
00496
00497 n = get_le32(pb);
00498 for(i=0;i<n;i++) {
00499 num = get_le16(pb);
00500 get_str16(pb, str, sizeof(str));
00501 get_str16(pb, str, sizeof(str));
00502 len = get_le16(pb);
00503 q = tag;
00504 while (len > 0) {
00505 v1 = get_byte(pb);
00506 if ((q - tag) < sizeof(tag) - 1)
00507 *q++ = v1;
00508 len--;
00509 }
00510 *q = '\0';
00511 }
00512 #endif
00513 } else if (url_feof(pb)) {
00514 goto fail;
00515 } else {
00516 url_fseek(pb, gsize - 24, SEEK_CUR);
00517 }
00518 }
00519 get_guid(pb, &g);
00520 get_le64(pb);
00521 get_byte(pb);
00522 get_byte(pb);
00523 if (url_feof(pb))
00524 goto fail;
00525 asf->data_offset = url_ftell(pb);
00526 asf->packet_size_left = 0;
00527
00528
00529 for(i=0; i<128; i++){
00530 int stream_num= asf->asfid2avid[i];
00531 if(stream_num>=0){
00532 AVCodecContext *codec= s->streams[stream_num]->codec;
00533 if (!codec->bit_rate)
00534 codec->bit_rate = bitrate[i];
00535 if (dar[i].num > 0 && dar[i].den > 0)
00536 av_reduce(&codec->sample_aspect_ratio.num,
00537 &codec->sample_aspect_ratio.den,
00538 dar[i].num, dar[i].den, INT_MAX);
00539
00540 }
00541 }
00542
00543 return 0;
00544
00545 fail:
00546 for(i=0;i<s->nb_streams;i++) {
00547 AVStream *st = s->streams[i];
00548 if (st) {
00549 av_free(st->priv_data);
00550 av_free(st->codec->extradata);
00551 }
00552 av_free(st);
00553 }
00554 return -1;
00555 }
00556
00557 #define DO_2BITS(bits, var, defval) \
00558 switch (bits & 3) \
00559 { \
00560 case 3: var = get_le32(pb); rsize += 4; break; \
00561 case 2: var = get_le16(pb); rsize += 2; break; \
00562 case 1: var = get_byte(pb); rsize++; break; \
00563 default: var = defval; break; \
00564 }
00565
00570 static int asf_get_packet(AVFormatContext *s)
00571 {
00572 ASFContext *asf = s->priv_data;
00573 ByteIOContext *pb = s->pb;
00574 uint32_t packet_length, padsize;
00575 int rsize = 8;
00576 int c, d, e, off;
00577
00578 off= (url_ftell(s->pb) - s->data_offset) % asf->packet_size + 3;
00579
00580 c=d=e=-1;
00581 while(off-- > 0){
00582 c=d; d=e;
00583 e= get_byte(pb);
00584 if(c == 0x82 && !d && !e)
00585 break;
00586 }
00587
00588 if (c != 0x82) {
00589 if (!url_feof(pb))
00590 av_log(s, AV_LOG_ERROR, "ff asf bad header %x at:%"PRId64"\n", c, url_ftell(pb));
00591 }
00592 if ((c & 0x8f) == 0x82) {
00593 if (d || e) {
00594 if (!url_feof(pb))
00595 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
00596 return -1;
00597 }
00598 c= get_byte(pb);
00599 d= get_byte(pb);
00600 rsize+=3;
00601 }else{
00602 url_fseek(pb, -1, SEEK_CUR);
00603 }
00604
00605 asf->packet_flags = c;
00606 asf->packet_property = d;
00607
00608 DO_2BITS(asf->packet_flags >> 5, packet_length, asf->packet_size);
00609 DO_2BITS(asf->packet_flags >> 1, padsize, 0);
00610 DO_2BITS(asf->packet_flags >> 3, padsize, 0);
00611
00612
00613 if(packet_length >= (1U<<29)){
00614 av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, url_ftell(pb));
00615 return -1;
00616 }
00617 if(padsize >= packet_length){
00618 av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, url_ftell(pb));
00619 return -1;
00620 }
00621
00622 asf->packet_timestamp = get_le32(pb);
00623 get_le16(pb);
00624
00625
00626 if (asf->packet_flags & 0x01) {
00627 asf->packet_segsizetype = get_byte(pb); rsize++;
00628 asf->packet_segments = asf->packet_segsizetype & 0x3f;
00629 } else {
00630 asf->packet_segments = 1;
00631 asf->packet_segsizetype = 0x80;
00632 }
00633 asf->packet_size_left = packet_length - padsize - rsize;
00634 if (packet_length < asf->hdr.min_pktsize)
00635 padsize += asf->hdr.min_pktsize - packet_length;
00636 asf->packet_padsize = padsize;
00637 #ifdef DEBUG
00638 printf("packet: size=%d padsize=%d left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left);
00639 #endif
00640 return 0;
00641 }
00642
00647 static int asf_read_frame_header(AVFormatContext *s){
00648 ASFContext *asf = s->priv_data;
00649 ByteIOContext *pb = s->pb;
00650 int rsize = 1;
00651 int num = get_byte(pb);
00652 int64_t ts0, ts1;
00653
00654 asf->packet_segments--;
00655 asf->packet_key_frame = num >> 7;
00656 asf->stream_index = asf->asfid2avid[num & 0x7f];
00657
00658 DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
00659 DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
00660 DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
00661
00662 if (asf->packet_replic_size >= 8) {
00663 asf->packet_obj_size = get_le32(pb);
00664 if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){
00665 av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
00666 return -1;
00667 }
00668 asf->packet_frag_timestamp = get_le32(pb);
00669 if(asf->packet_replic_size >= 8+38+4){
00670
00671
00672
00673 url_fskip(pb, 10);
00674 ts0= get_le64(pb);
00675 ts1= get_le64(pb);
00676 url_fskip(pb, 12);
00677 get_le32(pb);
00678 url_fskip(pb, asf->packet_replic_size - 8 - 38 - 4);
00679 if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
00680 else asf->packet_frag_timestamp= AV_NOPTS_VALUE;
00681 }else
00682 url_fskip(pb, asf->packet_replic_size - 8);
00683 rsize += asf->packet_replic_size;
00684 } else if (asf->packet_replic_size==1){
00685
00686 asf->packet_time_start = asf->packet_frag_offset;
00687 asf->packet_frag_offset = 0;
00688 asf->packet_frag_timestamp = asf->packet_timestamp;
00689
00690 asf->packet_time_delta = get_byte(pb);
00691 rsize++;
00692 }else if(asf->packet_replic_size!=0){
00693 av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
00694 return -1;
00695 }
00696 if (asf->packet_flags & 0x01) {
00697 DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0);
00698 if(asf->packet_frag_size > asf->packet_size_left - rsize){
00699 av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid\n");
00700 return -1;
00701 }
00702
00703 } else {
00704 asf->packet_frag_size = asf->packet_size_left - rsize;
00705
00706 }
00707 if (asf->packet_replic_size == 1) {
00708 asf->packet_multi_size = asf->packet_frag_size;
00709 if (asf->packet_multi_size > asf->packet_size_left)
00710 return -1;
00711 }
00712 asf->packet_size_left -= rsize;
00713
00714
00715 return 0;
00716 }
00717
00718 static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
00719 {
00720 ASFContext *asf = s->priv_data;
00721 ASFStream *asf_st = 0;
00722 ByteIOContext *pb = s->pb;
00723
00724 for (;;) {
00725 if(url_feof(pb))
00726 return AVERROR(EIO);
00727 if (asf->packet_size_left < FRAME_HEADER_SIZE
00728 || asf->packet_segments < 1) {
00729
00730 int ret = asf->packet_size_left + asf->packet_padsize;
00731
00732 assert(ret>=0);
00733
00734 url_fskip(pb, ret);
00735
00736 asf->packet_pos= url_ftell(s->pb);
00737 if (asf->data_object_size != (uint64_t)-1 &&
00738 (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
00739 return AVERROR(EIO);
00740 ret = asf_get_packet(s);
00741
00742 if (ret < 0)
00743 assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
00744 asf->packet_time_start = 0;
00745 continue;
00746 }
00747 if (asf->packet_time_start == 0) {
00748 if(asf_read_frame_header(s) < 0){
00749 asf->packet_segments= 0;
00750 continue;
00751 }
00752 if (asf->stream_index < 0
00753 || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL
00754 || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)
00755 ) {
00756 asf->packet_time_start = 0;
00757
00758 url_fskip(pb, asf->packet_frag_size);
00759 asf->packet_size_left -= asf->packet_frag_size;
00760 if(asf->stream_index < 0)
00761 av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size);
00762 continue;
00763 }
00764 asf->asf_st = s->streams[asf->stream_index]->priv_data;
00765 }
00766 asf_st = asf->asf_st;
00767
00768 if (asf->packet_replic_size == 1) {
00769
00770 asf->packet_frag_timestamp = asf->packet_time_start;
00771 asf->packet_time_start += asf->packet_time_delta;
00772 asf->packet_obj_size = asf->packet_frag_size = get_byte(pb);
00773 asf->packet_size_left--;
00774 asf->packet_multi_size--;
00775 if (asf->packet_multi_size < asf->packet_obj_size)
00776 {
00777 asf->packet_time_start = 0;
00778 url_fskip(pb, asf->packet_multi_size);
00779 asf->packet_size_left -= asf->packet_multi_size;
00780 continue;
00781 }
00782 asf->packet_multi_size -= asf->packet_obj_size;
00783
00784 }
00785 if(
00786 asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size
00787 && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){
00788 av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
00789 asf_st->frag_offset, asf->packet_frag_size,
00790 asf->packet_obj_size, asf_st->pkt.size);
00791 asf->packet_obj_size= asf_st->pkt.size;
00792 }
00793
00794 if ( asf_st->pkt.size != asf->packet_obj_size
00795 || asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {
00796 if(asf_st->pkt.data){
00797 av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", asf_st->pkt.size, asf->packet_obj_size);
00798 asf_st->frag_offset = 0;
00799 av_free_packet(&asf_st->pkt);
00800 }
00801
00802 av_new_packet(&asf_st->pkt, asf->packet_obj_size);
00803 asf_st->seq = asf->packet_seq;
00804 asf_st->pkt.pts = asf->packet_frag_timestamp;
00805 asf_st->pkt.stream_index = asf->stream_index;
00806 asf_st->pkt.pos =
00807 asf_st->packet_pos= asf->packet_pos;
00808
00809
00810
00811 if (s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO)
00812 asf->packet_key_frame = 1;
00813 if (asf->packet_key_frame)
00814 asf_st->pkt.flags |= PKT_FLAG_KEY;
00815 }
00816
00817
00818
00819
00820
00821 asf->packet_size_left -= asf->packet_frag_size;
00822 if (asf->packet_size_left < 0)
00823 continue;
00824
00825 if( asf->packet_frag_offset >= asf_st->pkt.size
00826 || asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset){
00827 av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n",
00828 asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size);
00829 continue;
00830 }
00831
00832 get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,
00833 asf->packet_frag_size);
00834 if (s->key && s->keylen == 20)
00835 ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,
00836 asf->packet_frag_size);
00837 asf_st->frag_offset += asf->packet_frag_size;
00838
00839 if (asf_st->frag_offset == asf_st->pkt.size) {
00840
00841 if( s->streams[asf->stream_index]->codec->codec_id == CODEC_ID_MPEG2VIDEO
00842 && asf_st->pkt.size > 100){
00843 int i;
00844 for(i=0; i<asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
00845 if(i == asf_st->pkt.size){
00846 av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
00847 asf_st->frag_offset = 0;
00848 av_free_packet(&asf_st->pkt);
00849 continue;
00850 }
00851 }
00852
00853
00854 if (asf_st->ds_span > 1) {
00855 if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){
00856 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);
00857 }else{
00858
00859 uint8_t *newdata = av_malloc(asf_st->pkt.size);
00860 if (newdata) {
00861 int offset = 0;
00862 while (offset < asf_st->pkt.size) {
00863 int off = offset / asf_st->ds_chunk_size;
00864 int row = off / asf_st->ds_span;
00865 int col = off % asf_st->ds_span;
00866 int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;
00867
00868
00869 assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);
00870 assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
00871 memcpy(newdata + offset,
00872 asf_st->pkt.data + idx * asf_st->ds_chunk_size,
00873 asf_st->ds_chunk_size);
00874 offset += asf_st->ds_chunk_size;
00875 }
00876 av_free(asf_st->pkt.data);
00877 asf_st->pkt.data = newdata;
00878 }
00879 }
00880 }
00881 asf_st->frag_offset = 0;
00882 *pkt= asf_st->pkt;
00883
00884 asf_st->pkt.size = 0;
00885 asf_st->pkt.data = 0;
00886 break;
00887 }
00888 }
00889 return 0;
00890 }
00891
00892
00893
00894
00895 static void asf_reset_header(AVFormatContext *s)
00896 {
00897 ASFContext *asf = s->priv_data;
00898 ASFStream *asf_st;
00899 int i;
00900
00901 asf->packet_nb_frames = 0;
00902 asf->packet_size_left = 0;
00903 asf->packet_segments = 0;
00904 asf->packet_flags = 0;
00905 asf->packet_property = 0;
00906 asf->packet_timestamp = 0;
00907 asf->packet_segsizetype = 0;
00908 asf->packet_segments = 0;
00909 asf->packet_seq = 0;
00910 asf->packet_replic_size = 0;
00911 asf->packet_key_frame = 0;
00912 asf->packet_padsize = 0;
00913 asf->packet_frag_offset = 0;
00914 asf->packet_frag_size = 0;
00915 asf->packet_frag_timestamp = 0;
00916 asf->packet_multi_size = 0;
00917 asf->packet_obj_size = 0;
00918 asf->packet_time_delta = 0;
00919 asf->packet_time_start = 0;
00920
00921 for(i=0; i<s->nb_streams; i++){
00922 asf_st= s->streams[i]->priv_data;
00923 av_free_packet(&asf_st->pkt);
00924 asf_st->frag_offset=0;
00925 asf_st->seq=0;
00926 }
00927 asf->asf_st= NULL;
00928 }
00929
00930 static int asf_read_close(AVFormatContext *s)
00931 {
00932 int i;
00933
00934 asf_reset_header(s);
00935 for(i=0;i<s->nb_streams;i++) {
00936 AVStream *st = s->streams[i];
00937 av_free(st->priv_data);
00938 av_free(st->codec->palctrl);
00939 }
00940 return 0;
00941 }
00942
00943 static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
00944 {
00945 ASFContext *asf = s->priv_data;
00946 AVPacket pkt1, *pkt = &pkt1;
00947 ASFStream *asf_st;
00948 int64_t pts;
00949 int64_t pos= *ppos;
00950 int i;
00951 int64_t start_pos[s->nb_streams];
00952
00953 for(i=0; i<s->nb_streams; i++){
00954 start_pos[i]= pos;
00955 }
00956
00957 pos= (pos+asf->packet_size-1-s->data_offset)/asf->packet_size*asf->packet_size+ s->data_offset;
00958 *ppos= pos;
00959 url_fseek(s->pb, pos, SEEK_SET);
00960
00961
00962 asf_reset_header(s);
00963 for(;;){
00964 if (av_read_frame(s, pkt) < 0){
00965 av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
00966 return AV_NOPTS_VALUE;
00967 }
00968
00969 pts= pkt->pts;
00970
00971 av_free_packet(pkt);
00972 if(pkt->flags&PKT_FLAG_KEY){
00973 i= pkt->stream_index;
00974
00975 asf_st= s->streams[i]->priv_data;
00976
00977
00978 pos= asf_st->packet_pos;
00979
00980 av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
00981 start_pos[i]= asf_st->packet_pos + 1;
00982
00983 if(pkt->stream_index == stream_index)
00984 break;
00985 }
00986 }
00987
00988 *ppos= pos;
00989
00990
00991 return pts;
00992 }
00993
00994 static void asf_build_simple_index(AVFormatContext *s, int stream_index)
00995 {
00996 GUID g;
00997 ASFContext *asf = s->priv_data;
00998 int64_t gsize, itime;
00999 int64_t pos, current_pos, index_pts;
01000 int i;
01001 int pct,ict;
01002
01003 current_pos = url_ftell(s->pb);
01004
01005 url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
01006 get_guid(s->pb, &g);
01007 if (!memcmp(&g, &index_guid, sizeof(GUID))) {
01008 gsize = get_le64(s->pb);
01009 get_guid(s->pb, &g);
01010 itime=get_le64(s->pb);
01011 pct=get_le32(s->pb);
01012 ict=get_le32(s->pb);
01013 av_log(NULL, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
01014
01015 for (i=0;i<ict;i++){
01016 int pktnum=get_le32(s->pb);
01017 int pktct =get_le16(s->pb);
01018 av_log(NULL, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
01019
01020 pos=s->data_offset + asf->packet_size*(int64_t)pktnum;
01021 index_pts=av_rescale(itime, i, 10000);
01022
01023 av_add_index_entry(s->streams[stream_index], pos, index_pts, asf->packet_size, 0, AVINDEX_KEYFRAME);
01024 }
01025 asf->index_read= 1;
01026 }
01027 url_fseek(s->pb, current_pos, SEEK_SET);
01028 }
01029
01030 static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
01031 {
01032 ASFContext *asf = s->priv_data;
01033 AVStream *st = s->streams[stream_index];
01034 int64_t pos;
01035 int index;
01036
01037 if (asf->packet_size <= 0)
01038 return -1;
01039
01040
01041 if(s->pb) {
01042 int ret = av_url_read_fseek(s->pb, stream_index, pts, flags);
01043 if(ret >= 0)
01044 asf_reset_header(s);
01045 if (ret != AVERROR(ENOSYS))
01046 return ret;
01047 }
01048
01049 if (!asf->index_read)
01050 asf_build_simple_index(s, stream_index);
01051
01052 if(!(asf->index_read && st->index_entries)){
01053 if(av_seek_frame_binary(s, stream_index, pts, flags)<0)
01054 return -1;
01055 }else{
01056 index= av_index_search_timestamp(st, pts, flags);
01057 if(index<0)
01058 return -1;
01059
01060
01061 pos = st->index_entries[index].pos;
01062 pts = st->index_entries[index].timestamp;
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
01087 url_fseek(s->pb, pos, SEEK_SET);
01088 }
01089 asf_reset_header(s);
01090 return 0;
01091 }
01092
01093 AVInputFormat asf_demuxer = {
01094 "asf",
01095 "asf format",
01096 sizeof(ASFContext),
01097 asf_probe,
01098 asf_read_header,
01099 asf_read_packet,
01100 asf_read_close,
01101 asf_read_seek,
01102 asf_read_pts,
01103 };