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