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/bswap.h"
00025 #include "libavutil/common.h"
00026 #include "libavutil/avstring.h"
00027 #include "libavutil/dict.h"
00028 #include "libavutil/mathematics.h"
00029 #include "libavutil/opt.h"
00030 #include "avformat.h"
00031 #include "internal.h"
00032 #include "avio_internal.h"
00033 #include "id3v2.h"
00034 #include "riff.h"
00035 #include "asf.h"
00036 #include "asfcrypt.h"
00037 #include "avlanguage.h"
00038
00039 typedef struct {
00040 const AVClass *class;
00041 int asfid2avid[128];
00042 ASFStream streams[128];
00043 uint32_t stream_bitrates[128];
00044 AVRational dar[128];
00045 char stream_languages[128][6];
00046
00047
00048 int packet_size_left;
00049
00050 uint64_t data_offset;
00051 uint64_t data_object_offset;
00052 uint64_t data_object_size;
00053 int index_read;
00054
00055 ASFMainHeader hdr;
00056
00057 int packet_flags;
00058 int packet_property;
00059 int packet_timestamp;
00060 int packet_segsizetype;
00061 int packet_segments;
00062 int packet_seq;
00063 int packet_replic_size;
00064 int packet_key_frame;
00065 int packet_padsize;
00066 unsigned int packet_frag_offset;
00067 unsigned int packet_frag_size;
00068 int64_t packet_frag_timestamp;
00069 int packet_multi_size;
00070 int packet_obj_size;
00071 int packet_time_delta;
00072 int packet_time_start;
00073 int64_t packet_pos;
00074
00075 int stream_index;
00076
00077 ASFStream* asf_st;
00078
00079 int no_resync_search;
00080 } ASFContext;
00081
00082 static const AVOption options[] = {
00083 {"no_resync_search", "Don't try to resynchronize by looking for a certain optional start code", offsetof(ASFContext, no_resync_search), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
00084 { NULL },
00085 };
00086
00087 static const AVClass asf_class = {
00088 .class_name = "asf demuxer",
00089 .item_name = av_default_item_name,
00090 .option = options,
00091 .version = LIBAVUTIL_VERSION_INT,
00092 };
00093
00094 #undef NDEBUG
00095 #include <assert.h>
00096
00097 #define ASF_MAX_STREAMS 127
00098 #define FRAME_HEADER_SIZE 16
00099
00100
00101 #ifdef DEBUG
00102 static const ff_asf_guid stream_bitrate_guid = {
00103 0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2
00104 };
00105
00106 #define PRINT_IF_GUID(g,cmp) \
00107 if (!ff_guidcmp(g, &cmp)) \
00108 av_dlog(NULL, "(GUID: %s) ", #cmp)
00109
00110 static void print_guid(const ff_asf_guid *g)
00111 {
00112 int i;
00113 PRINT_IF_GUID(g, ff_asf_header);
00114 else PRINT_IF_GUID(g, ff_asf_file_header);
00115 else PRINT_IF_GUID(g, ff_asf_stream_header);
00116 else PRINT_IF_GUID(g, ff_asf_audio_stream);
00117 else PRINT_IF_GUID(g, ff_asf_audio_conceal_none);
00118 else PRINT_IF_GUID(g, ff_asf_video_stream);
00119 else PRINT_IF_GUID(g, ff_asf_video_conceal_none);
00120 else PRINT_IF_GUID(g, ff_asf_command_stream);
00121 else PRINT_IF_GUID(g, ff_asf_comment_header);
00122 else PRINT_IF_GUID(g, ff_asf_codec_comment_header);
00123 else PRINT_IF_GUID(g, ff_asf_codec_comment1_header);
00124 else PRINT_IF_GUID(g, ff_asf_data_header);
00125 else PRINT_IF_GUID(g, ff_asf_simple_index_header);
00126 else PRINT_IF_GUID(g, ff_asf_head1_guid);
00127 else PRINT_IF_GUID(g, ff_asf_head2_guid);
00128 else PRINT_IF_GUID(g, ff_asf_my_guid);
00129 else PRINT_IF_GUID(g, ff_asf_ext_stream_header);
00130 else PRINT_IF_GUID(g, ff_asf_extended_content_header);
00131 else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header);
00132 else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream);
00133 else PRINT_IF_GUID(g, ff_asf_metadata_header);
00134 else PRINT_IF_GUID(g, ff_asf_marker_header);
00135 else PRINT_IF_GUID(g, stream_bitrate_guid);
00136 else PRINT_IF_GUID(g, ff_asf_language_guid);
00137 else
00138 av_dlog(NULL, "(GUID: unknown) ");
00139 for(i=0;i<16;i++)
00140 av_dlog(NULL, " 0x%02x,", (*g)[i]);
00141 av_dlog(NULL, "}\n");
00142 }
00143 #undef PRINT_IF_GUID
00144 #else
00145 #define print_guid(g)
00146 #endif
00147
00148 static int asf_probe(AVProbeData *pd)
00149 {
00150
00151 if (!ff_guidcmp(pd->buf, &ff_asf_header))
00152 return AVPROBE_SCORE_MAX;
00153 else
00154 return 0;
00155 }
00156
00157 static int get_value(AVIOContext *pb, int type){
00158 switch(type){
00159 case 2: return avio_rl32(pb);
00160 case 3: return avio_rl32(pb);
00161 case 4: return avio_rl64(pb);
00162 case 5: return avio_rl16(pb);
00163 default:return INT_MIN;
00164 }
00165 }
00166
00167
00168
00169 static int asf_read_picture(AVFormatContext *s, int len)
00170 {
00171 AVPacket pkt = { 0 };
00172 const CodecMime *mime = ff_id3v2_mime_tags;
00173 enum AVCodecID id = AV_CODEC_ID_NONE;
00174 char mimetype[64];
00175 uint8_t *desc = NULL;
00176 ASFStream *ast = NULL;
00177 AVStream *st = NULL;
00178 int ret, type, picsize, desc_len;
00179
00180
00181 if (len < 1 + 4 + 2 + 2) {
00182 av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
00183 return AVERROR_INVALIDDATA;
00184 }
00185
00186
00187 type = avio_r8(s->pb);
00188 len--;
00189 if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
00190 av_log(s, AV_LOG_WARNING, "Unknown attached picture type: %d.\n", type);
00191 type = 0;
00192 }
00193
00194
00195 picsize = avio_rl32(s->pb);
00196 len -= 4;
00197
00198
00199 len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype));
00200 while (mime->id != AV_CODEC_ID_NONE) {
00201 if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
00202 id = mime->id;
00203 break;
00204 }
00205 mime++;
00206 }
00207 if (id == AV_CODEC_ID_NONE) {
00208 av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
00209 mimetype);
00210 return 0;
00211 }
00212
00213 if (picsize >= len) {
00214 av_log(s, AV_LOG_ERROR, "Invalid attached picture data size: %d >= %d.\n",
00215 picsize, len);
00216 return AVERROR_INVALIDDATA;
00217 }
00218
00219
00220 desc_len = (len - picsize) * 2 + 1;
00221 desc = av_malloc(desc_len);
00222 if (!desc)
00223 return AVERROR(ENOMEM);
00224 len -= avio_get_str16le(s->pb, len - picsize, desc, desc_len);
00225
00226 ret = av_get_packet(s->pb, &pkt, picsize);
00227 if (ret < 0)
00228 goto fail;
00229
00230 st = avformat_new_stream(s, NULL);
00231 ast = av_mallocz(sizeof(*ast));
00232 if (!st || !ast) {
00233 ret = AVERROR(ENOMEM);
00234 goto fail;
00235 }
00236 st->priv_data = ast;
00237
00238 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
00239 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00240 st->codec->codec_id = id;
00241
00242 st->attached_pic = pkt;
00243 st->attached_pic.stream_index = st->index;
00244 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
00245
00246 if (*desc)
00247 av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
00248 else
00249 av_freep(&desc);
00250
00251 av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
00252
00253 return 0;
00254
00255 fail:
00256 av_freep(&ast);
00257 av_freep(&desc);
00258 av_free_packet(&pkt);
00259 return ret;
00260 }
00261
00262 static void get_tag(AVFormatContext *s, const char *key, int type, int len)
00263 {
00264 char *value;
00265 int64_t off = avio_tell(s->pb);
00266
00267 if ((unsigned)len >= (UINT_MAX - 1)/2)
00268 return;
00269
00270 value = av_malloc(2*len+1);
00271 if (!value)
00272 goto finish;
00273
00274 if (type == 0) {
00275 avio_get_str16le(s->pb, len, value, 2*len + 1);
00276 } else if (type == -1) {
00277 avio_read(s->pb, value, len);
00278 value[len]=0;
00279 } else if (type > 1 && type <= 5) {
00280 uint64_t num = get_value(s->pb, type);
00281 snprintf(value, len, "%"PRIu64, num);
00282 } else if (type == 1 && !strcmp(key, "WM/Picture")) {
00283 asf_read_picture(s, len);
00284 goto finish;
00285 } else {
00286 av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key);
00287 goto finish;
00288 }
00289 if (*value)
00290 av_dict_set(&s->metadata, key, value, 0);
00291 finish:
00292 av_freep(&value);
00293 avio_seek(s->pb, off + len, SEEK_SET);
00294 }
00295
00296 static int asf_read_file_properties(AVFormatContext *s, int64_t size)
00297 {
00298 ASFContext *asf = s->priv_data;
00299 AVIOContext *pb = s->pb;
00300
00301 ff_get_guid(pb, &asf->hdr.guid);
00302 asf->hdr.file_size = avio_rl64(pb);
00303 asf->hdr.create_time = avio_rl64(pb);
00304 avio_rl64(pb);
00305 asf->hdr.play_time = avio_rl64(pb);
00306 asf->hdr.send_time = avio_rl64(pb);
00307 asf->hdr.preroll = avio_rl32(pb);
00308 asf->hdr.ignore = avio_rl32(pb);
00309 asf->hdr.flags = avio_rl32(pb);
00310 asf->hdr.min_pktsize = avio_rl32(pb);
00311 asf->hdr.max_pktsize = avio_rl32(pb);
00312 if (asf->hdr.min_pktsize >= (1U<<29))
00313 return AVERROR_INVALIDDATA;
00314 asf->hdr.max_bitrate = avio_rl32(pb);
00315 s->packet_size = asf->hdr.max_pktsize;
00316
00317 return 0;
00318 }
00319
00320 static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
00321 {
00322 ASFContext *asf = s->priv_data;
00323 AVIOContext *pb = s->pb;
00324 AVStream *st;
00325 ASFStream *asf_st;
00326 ff_asf_guid g;
00327 enum AVMediaType type;
00328 int type_specific_size, sizeX;
00329 unsigned int tag1;
00330 int64_t pos1, pos2, start_time;
00331 int test_for_ext_stream_audio, is_dvr_ms_audio=0;
00332
00333 if (s->nb_streams == ASF_MAX_STREAMS) {
00334 av_log(s, AV_LOG_ERROR, "too many streams\n");
00335 return AVERROR(EINVAL);
00336 }
00337
00338 pos1 = avio_tell(pb);
00339
00340 st = avformat_new_stream(s, NULL);
00341 if (!st)
00342 return AVERROR(ENOMEM);
00343 avpriv_set_pts_info(st, 32, 1, 1000);
00344 asf_st = av_mallocz(sizeof(ASFStream));
00345 if (!asf_st)
00346 return AVERROR(ENOMEM);
00347 st->priv_data = asf_st;
00348 start_time = asf->hdr.preroll;
00349
00350 asf_st->stream_language_index = 128;
00351
00352 if(!(asf->hdr.flags & 0x01)) {
00353 st->duration = asf->hdr.play_time /
00354 (10000000 / 1000) - start_time;
00355 }
00356 ff_get_guid(pb, &g);
00357
00358 test_for_ext_stream_audio = 0;
00359 if (!ff_guidcmp(&g, &ff_asf_audio_stream)) {
00360 type = AVMEDIA_TYPE_AUDIO;
00361 } else if (!ff_guidcmp(&g, &ff_asf_video_stream)) {
00362 type = AVMEDIA_TYPE_VIDEO;
00363 } else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) {
00364 type = AVMEDIA_TYPE_VIDEO;
00365 st->codec->codec_id = AV_CODEC_ID_MJPEG;
00366 } else if (!ff_guidcmp(&g, &ff_asf_command_stream)) {
00367 type = AVMEDIA_TYPE_DATA;
00368 } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) {
00369 test_for_ext_stream_audio = 1;
00370 type = AVMEDIA_TYPE_UNKNOWN;
00371 } else {
00372 return -1;
00373 }
00374 ff_get_guid(pb, &g);
00375 avio_skip(pb, 8);
00376 type_specific_size = avio_rl32(pb);
00377 avio_rl32(pb);
00378 st->id = avio_rl16(pb) & 0x7f;
00379
00380 asf->asfid2avid[st->id] = s->nb_streams - 1;
00381
00382 avio_rl32(pb);
00383
00384 if (test_for_ext_stream_audio) {
00385 ff_get_guid(pb, &g);
00386 if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) {
00387 type = AVMEDIA_TYPE_AUDIO;
00388 is_dvr_ms_audio=1;
00389 ff_get_guid(pb, &g);
00390 avio_rl32(pb);
00391 avio_rl32(pb);
00392 avio_rl32(pb);
00393 ff_get_guid(pb, &g);
00394 avio_rl32(pb);
00395 }
00396 }
00397
00398 st->codec->codec_type = type;
00399 if (type == AVMEDIA_TYPE_AUDIO) {
00400 int ret = ff_get_wav_header(pb, st->codec, type_specific_size);
00401 if (ret < 0)
00402 return ret;
00403 if (is_dvr_ms_audio) {
00404
00405
00406 st->request_probe= 1;
00407 st->codec->codec_tag = 0;
00408 }
00409 if (st->codec->codec_id == AV_CODEC_ID_AAC) {
00410 st->need_parsing = AVSTREAM_PARSE_NONE;
00411 } else {
00412 st->need_parsing = AVSTREAM_PARSE_FULL;
00413 }
00414
00415 pos2 = avio_tell(pb);
00416 if (size >= (pos2 + 8 - pos1 + 24)) {
00417 asf_st->ds_span = avio_r8(pb);
00418 asf_st->ds_packet_size = avio_rl16(pb);
00419 asf_st->ds_chunk_size = avio_rl16(pb);
00420 avio_rl16(pb);
00421 avio_r8(pb);
00422 }
00423
00424
00425
00426 if (asf_st->ds_span > 1) {
00427 if (!asf_st->ds_chunk_size
00428 || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
00429 || asf_st->ds_packet_size % asf_st->ds_chunk_size)
00430 asf_st->ds_span = 0;
00431 }
00432 } else if (type == AVMEDIA_TYPE_VIDEO &&
00433 size - (avio_tell(pb) - pos1 + 24) >= 51) {
00434 avio_rl32(pb);
00435 avio_rl32(pb);
00436 avio_r8(pb);
00437 avio_rl16(pb);
00438 sizeX= avio_rl32(pb);
00439 st->codec->width = avio_rl32(pb);
00440 st->codec->height = avio_rl32(pb);
00441
00442 avio_rl16(pb);
00443 st->codec->bits_per_coded_sample = avio_rl16(pb);
00444 tag1 = avio_rl32(pb);
00445 avio_skip(pb, 20);
00446
00447 if (sizeX > 40) {
00448 st->codec->extradata_size = sizeX - 40;
00449 st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
00450 avio_read(pb, st->codec->extradata, st->codec->extradata_size);
00451 }
00452
00453
00454
00455
00456 if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
00457 #if HAVE_BIGENDIAN
00458 int i;
00459 for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
00460 asf_st->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]);
00461 #else
00462 memcpy(asf_st->palette, st->codec->extradata,
00463 FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
00464 #endif
00465 asf_st->palette_changed = 1;
00466 }
00467
00468 st->codec->codec_tag = tag1;
00469 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
00470 if(tag1 == MKTAG('D', 'V', 'R', ' ')){
00471 st->need_parsing = AVSTREAM_PARSE_FULL;
00472
00473 st->codec->width =
00474 st->codec->height = 0;
00475 av_freep(&st->codec->extradata);
00476 st->codec->extradata_size=0;
00477 }
00478 if(st->codec->codec_id == AV_CODEC_ID_H264)
00479 st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
00480 }
00481 pos2 = avio_tell(pb);
00482 avio_skip(pb, size - (pos2 - pos1 + 24));
00483
00484 return 0;
00485 }
00486
00487 static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
00488 {
00489 ASFContext *asf = s->priv_data;
00490 AVIOContext *pb = s->pb;
00491 ff_asf_guid g;
00492 int ext_len, payload_ext_ct, stream_ct, i;
00493 uint32_t leak_rate, stream_num;
00494 unsigned int stream_languageid_index;
00495
00496 avio_rl64(pb);
00497 avio_rl64(pb);
00498 leak_rate = avio_rl32(pb);
00499 avio_rl32(pb);
00500 avio_rl32(pb);
00501 avio_rl32(pb);
00502 avio_rl32(pb);
00503 avio_rl32(pb);
00504 avio_rl32(pb);
00505 avio_rl32(pb);
00506 stream_num = avio_rl16(pb);
00507
00508 stream_languageid_index = avio_rl16(pb);
00509 if (stream_num < 128)
00510 asf->streams[stream_num].stream_language_index = stream_languageid_index;
00511
00512 avio_rl64(pb);
00513 stream_ct = avio_rl16(pb);
00514 payload_ext_ct = avio_rl16(pb);
00515
00516 if (stream_num < 128)
00517 asf->stream_bitrates[stream_num] = leak_rate;
00518
00519 for (i=0; i<stream_ct; i++){
00520 avio_rl16(pb);
00521 ext_len = avio_rl16(pb);
00522 avio_skip(pb, ext_len);
00523 }
00524
00525 for (i=0; i<payload_ext_ct; i++){
00526 ff_get_guid(pb, &g);
00527 avio_skip(pb, 2);
00528 ext_len=avio_rl32(pb);
00529 avio_skip(pb, ext_len);
00530 }
00531
00532 return 0;
00533 }
00534
00535 static int asf_read_content_desc(AVFormatContext *s, int64_t size)
00536 {
00537 AVIOContext *pb = s->pb;
00538 int len1, len2, len3, len4, len5;
00539
00540 len1 = avio_rl16(pb);
00541 len2 = avio_rl16(pb);
00542 len3 = avio_rl16(pb);
00543 len4 = avio_rl16(pb);
00544 len5 = avio_rl16(pb);
00545 get_tag(s, "title" , 0, len1);
00546 get_tag(s, "author" , 0, len2);
00547 get_tag(s, "copyright", 0, len3);
00548 get_tag(s, "comment" , 0, len4);
00549 avio_skip(pb, len5);
00550
00551 return 0;
00552 }
00553
00554 static int asf_read_ext_content_desc(AVFormatContext *s, int64_t size)
00555 {
00556 AVIOContext *pb = s->pb;
00557 ASFContext *asf = s->priv_data;
00558 int desc_count, i, ret;
00559
00560 desc_count = avio_rl16(pb);
00561 for(i=0;i<desc_count;i++) {
00562 int name_len,value_type,value_len;
00563 char name[1024];
00564
00565 name_len = avio_rl16(pb);
00566 if (name_len%2)
00567 name_len += 1;
00568 if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
00569 avio_skip(pb, name_len - ret);
00570 value_type = avio_rl16(pb);
00571 value_len = avio_rl16(pb);
00572 if (!value_type && value_len%2)
00573 value_len += 1;
00578 if (!strcmp(name, "AspectRatioX")){
00579 asf->dar[0].num= get_value(s->pb, value_type);
00580 } else if(!strcmp(name, "AspectRatioY")){
00581 asf->dar[0].den= get_value(s->pb, value_type);
00582 } else
00583 get_tag(s, name, value_type, value_len);
00584 }
00585
00586 return 0;
00587 }
00588
00589 static int asf_read_language_list(AVFormatContext *s, int64_t size)
00590 {
00591 AVIOContext *pb = s->pb;
00592 ASFContext *asf = s->priv_data;
00593 int j, ret;
00594 int stream_count = avio_rl16(pb);
00595 for(j = 0; j < stream_count; j++) {
00596 char lang[6];
00597 unsigned int lang_len = avio_r8(pb);
00598 if ((ret = avio_get_str16le(pb, lang_len, lang, sizeof(lang))) < lang_len)
00599 avio_skip(pb, lang_len - ret);
00600 if (j < 128)
00601 av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages));
00602 }
00603
00604 return 0;
00605 }
00606
00607 static int asf_read_metadata(AVFormatContext *s, int64_t size)
00608 {
00609 AVIOContext *pb = s->pb;
00610 ASFContext *asf = s->priv_data;
00611 int n, stream_num, name_len, value_len, value_num;
00612 int ret, i;
00613 n = avio_rl16(pb);
00614
00615 for(i=0;i<n;i++) {
00616 char name[1024];
00617
00618 avio_rl16(pb);
00619 stream_num= avio_rl16(pb);
00620 name_len= avio_rl16(pb);
00621 avio_skip(pb, 2);
00622 value_len= avio_rl32(pb);
00623
00624 if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
00625 avio_skip(pb, name_len - ret);
00626
00627 value_num= avio_rl16(pb);
00628 avio_skip(pb, value_len - 2);
00629
00630 if(stream_num<128){
00631 if (!strcmp(name, "AspectRatioX")) asf->dar[stream_num].num= value_num;
00632 else if(!strcmp(name, "AspectRatioY")) asf->dar[stream_num].den= value_num;
00633 }
00634 }
00635
00636 return 0;
00637 }
00638
00639 static int asf_read_marker(AVFormatContext *s, int64_t size)
00640 {
00641 AVIOContext *pb = s->pb;
00642 int i, count, name_len, ret;
00643 char name[1024];
00644
00645 avio_rl64(pb);
00646 avio_rl64(pb);
00647 count = avio_rl32(pb);
00648 avio_rl16(pb);
00649 name_len = avio_rl16(pb);
00650 for(i=0;i<name_len;i++){
00651 avio_r8(pb);
00652 }
00653
00654 for(i=0;i<count;i++){
00655 int64_t pres_time;
00656 int name_len;
00657
00658 avio_rl64(pb);
00659 pres_time = avio_rl64(pb);
00660 avio_rl16(pb);
00661 avio_rl32(pb);
00662 avio_rl32(pb);
00663 name_len = avio_rl32(pb);
00664 if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len)
00665 avio_skip(pb, name_len - ret);
00666 avpriv_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
00667 }
00668
00669 return 0;
00670 }
00671
00672 static int asf_read_header(AVFormatContext *s)
00673 {
00674 ASFContext *asf = s->priv_data;
00675 ff_asf_guid g;
00676 AVIOContext *pb = s->pb;
00677 int i;
00678 int64_t gsize;
00679
00680 ff_get_guid(pb, &g);
00681 if (ff_guidcmp(&g, &ff_asf_header))
00682 return AVERROR_INVALIDDATA;
00683 avio_rl64(pb);
00684 avio_rl32(pb);
00685 avio_r8(pb);
00686 avio_r8(pb);
00687 memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
00688 for(;;) {
00689 uint64_t gpos= avio_tell(pb);
00690 ff_get_guid(pb, &g);
00691 gsize = avio_rl64(pb);
00692 av_dlog(s, "%08"PRIx64": ", gpos);
00693 print_guid(&g);
00694 av_dlog(s, " size=0x%"PRIx64"\n", gsize);
00695 if (!ff_guidcmp(&g, &ff_asf_data_header)) {
00696 asf->data_object_offset = avio_tell(pb);
00697
00698 if (!(asf->hdr.flags & 0x01) && gsize >= 100) {
00699 asf->data_object_size = gsize - 24;
00700 } else {
00701 asf->data_object_size = (uint64_t)-1;
00702 }
00703 break;
00704 }
00705 if (gsize < 24)
00706 return AVERROR_INVALIDDATA;
00707 if (!ff_guidcmp(&g, &ff_asf_file_header)) {
00708 int ret = asf_read_file_properties(s, gsize);
00709 if (ret < 0)
00710 return ret;
00711 } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {
00712 asf_read_stream_properties(s, gsize);
00713 } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {
00714 asf_read_content_desc(s, gsize);
00715 } else if (!ff_guidcmp(&g, &ff_asf_language_guid)) {
00716 asf_read_language_list(s, gsize);
00717 } else if (!ff_guidcmp(&g, &ff_asf_extended_content_header)) {
00718 asf_read_ext_content_desc(s, gsize);
00719 } else if (!ff_guidcmp(&g, &ff_asf_metadata_header)) {
00720 asf_read_metadata(s, gsize);
00721 } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_header)) {
00722 asf_read_ext_stream_properties(s, gsize);
00723
00724
00725
00726 continue;
00727 } else if (!ff_guidcmp(&g, &ff_asf_head1_guid)) {
00728 ff_get_guid(pb, &g);
00729 avio_skip(pb, 6);
00730 continue;
00731 } else if (!ff_guidcmp(&g, &ff_asf_marker_header)) {
00732 asf_read_marker(s, gsize);
00733 } else if (url_feof(pb)) {
00734 return AVERROR_EOF;
00735 } else {
00736 if (!s->keylen) {
00737 if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {
00738 unsigned int len;
00739 AVPacket pkt;
00740 av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n");
00741 len= avio_rl32(pb);
00742 av_log(s, AV_LOG_DEBUG, "Secret data:\n");
00743 av_get_packet(pb, &pkt, len); av_hex_dump_log(s, AV_LOG_DEBUG, pkt.data, pkt.size); av_free_packet(&pkt);
00744 len= avio_rl32(pb);
00745 get_tag(s, "ASF_Protection_Type", -1, len);
00746 len= avio_rl32(pb);
00747 get_tag(s, "ASF_Key_ID", -1, len);
00748 len= avio_rl32(pb);
00749 get_tag(s, "ASF_License_URL", -1, len);
00750 } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) {
00751 av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n");
00752 av_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0);
00753 } else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) {
00754 av_log(s, AV_LOG_INFO, "Digital signature detected!\n");
00755 }
00756 }
00757 }
00758 if(avio_tell(pb) != gpos + gsize)
00759 av_log(s, AV_LOG_DEBUG, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", avio_tell(pb)-gpos, gsize);
00760 avio_seek(pb, gpos + gsize, SEEK_SET);
00761 }
00762 ff_get_guid(pb, &g);
00763 avio_rl64(pb);
00764 avio_r8(pb);
00765 avio_r8(pb);
00766 if (url_feof(pb))
00767 return AVERROR_EOF;
00768 asf->data_offset = avio_tell(pb);
00769 asf->packet_size_left = 0;
00770
00771
00772 for(i=0; i<128; i++){
00773 int stream_num= asf->asfid2avid[i];
00774 if(stream_num>=0){
00775 AVStream *st = s->streams[stream_num];
00776 if (!st->codec->bit_rate)
00777 st->codec->bit_rate = asf->stream_bitrates[i];
00778 if (asf->dar[i].num > 0 && asf->dar[i].den > 0){
00779 av_reduce(&st->sample_aspect_ratio.den,
00780 &st->sample_aspect_ratio.num,
00781 asf->dar[i].num, asf->dar[i].den, INT_MAX);
00782 } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) && (st->codec->codec_type==AVMEDIA_TYPE_VIDEO))
00783 av_reduce(&st->sample_aspect_ratio.den,
00784 &st->sample_aspect_ratio.num,
00785 asf->dar[0].num, asf->dar[0].den, INT_MAX);
00786
00787
00788
00789
00790 if (asf->streams[i].stream_language_index < 128) {
00791 const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index];
00792 if (rfc1766 && strlen(rfc1766) > 1) {
00793 const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' };
00794 const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL);
00795 if (iso6392)
00796 av_dict_set(&st->metadata, "language", iso6392, 0);
00797 }
00798 }
00799 }
00800 }
00801
00802 ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv);
00803
00804 return 0;
00805 }
00806
00807 #define DO_2BITS(bits, var, defval) \
00808 switch (bits & 3) \
00809 { \
00810 case 3: var = avio_rl32(pb); rsize += 4; break; \
00811 case 2: var = avio_rl16(pb); rsize += 2; break; \
00812 case 1: var = avio_r8(pb); rsize++; break; \
00813 default: var = defval; break; \
00814 }
00815
00822 static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
00823 {
00824 ASFContext *asf = s->priv_data;
00825 uint32_t packet_length, padsize;
00826 int rsize = 8;
00827 int c, d, e, off;
00828
00829
00830 off= 32768;
00831 if (asf->no_resync_search)
00832 off = 3;
00833 else if (s->packet_size > 0)
00834 off= (avio_tell(pb) - s->data_offset) % s->packet_size + 3;
00835
00836 c=d=e=-1;
00837 while(off-- > 0){
00838 c=d; d=e;
00839 e= avio_r8(pb);
00840 if(c == 0x82 && !d && !e)
00841 break;
00842 }
00843
00844 if (c != 0x82) {
00851 if (pb->error == AVERROR(EAGAIN))
00852 return AVERROR(EAGAIN);
00853 if (!url_feof(pb))
00854 av_log(s, AV_LOG_ERROR, "ff asf bad header %x at:%"PRId64"\n", c, avio_tell(pb));
00855 }
00856 if ((c & 0x8f) == 0x82) {
00857 if (d || e) {
00858 if (!url_feof(pb))
00859 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
00860 return AVERROR_INVALIDDATA;
00861 }
00862 c= avio_r8(pb);
00863 d= avio_r8(pb);
00864 rsize+=3;
00865 }else if(!url_feof(pb)){
00866 avio_seek(pb, -1, SEEK_CUR);
00867 }
00868
00869 asf->packet_flags = c;
00870 asf->packet_property = d;
00871
00872 DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size);
00873 DO_2BITS(asf->packet_flags >> 1, padsize, 0);
00874 DO_2BITS(asf->packet_flags >> 3, padsize, 0);
00875
00876
00877 if(!packet_length || packet_length >= (1U<<29)){
00878 av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, avio_tell(pb));
00879 return AVERROR_INVALIDDATA;
00880 }
00881 if(padsize >= packet_length){
00882 av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));
00883 return AVERROR_INVALIDDATA;
00884 }
00885
00886 asf->packet_timestamp = avio_rl32(pb);
00887 avio_rl16(pb);
00888
00889
00890 if (asf->packet_flags & 0x01) {
00891 asf->packet_segsizetype = avio_r8(pb); rsize++;
00892 asf->packet_segments = asf->packet_segsizetype & 0x3f;
00893 } else {
00894 asf->packet_segments = 1;
00895 asf->packet_segsizetype = 0x80;
00896 }
00897 if (rsize > packet_length - padsize) {
00898 asf->packet_size_left = 0;
00899 av_log(s, AV_LOG_ERROR,
00900 "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n",
00901 rsize, packet_length, padsize, avio_tell(pb));
00902 return AVERROR_INVALIDDATA;
00903 }
00904 asf->packet_size_left = packet_length - padsize - rsize;
00905 if (packet_length < asf->hdr.min_pktsize)
00906 padsize += asf->hdr.min_pktsize - packet_length;
00907 asf->packet_padsize = padsize;
00908 av_dlog(s, "packet: size=%d padsize=%d left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left);
00909 return 0;
00910 }
00911
00916 static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
00917 ASFContext *asf = s->priv_data;
00918 int rsize = 1;
00919 int num = avio_r8(pb);
00920 int64_t ts0, ts1 av_unused;
00921
00922 asf->packet_segments--;
00923 asf->packet_key_frame = num >> 7;
00924 asf->stream_index = asf->asfid2avid[num & 0x7f];
00925
00926 DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
00927 DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
00928 DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
00929
00930 if (rsize+asf->packet_replic_size > asf->packet_size_left) {
00931 av_log(s, AV_LOG_ERROR, "packet_replic_size %d is invalid\n", asf->packet_replic_size);
00932 return AVERROR_INVALIDDATA;
00933 }
00934 if (asf->packet_replic_size >= 8) {
00935 asf->packet_obj_size = avio_rl32(pb);
00936 if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){
00937 av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
00938 return AVERROR_INVALIDDATA;
00939 }
00940 asf->packet_frag_timestamp = avio_rl32(pb);
00941 if(asf->packet_replic_size >= 8+38+4){
00942
00943
00944
00945 avio_skip(pb, 10);
00946 ts0= avio_rl64(pb);
00947 ts1= avio_rl64(pb);
00948 avio_skip(pb, 12);
00949 avio_rl32(pb);
00950 avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4);
00951 if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
00952 else asf->packet_frag_timestamp= AV_NOPTS_VALUE;
00953 }else
00954 avio_skip(pb, asf->packet_replic_size - 8);
00955 rsize += asf->packet_replic_size;
00956 } else if (asf->packet_replic_size==1){
00957
00958 asf->packet_time_start = asf->packet_frag_offset;
00959 asf->packet_frag_offset = 0;
00960 asf->packet_frag_timestamp = asf->packet_timestamp;
00961
00962 asf->packet_time_delta = avio_r8(pb);
00963 rsize++;
00964 }else if(asf->packet_replic_size!=0){
00965 av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
00966 return AVERROR_INVALIDDATA;
00967 }
00968 if (asf->packet_flags & 0x01) {
00969 DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0);
00970 if (rsize > asf->packet_size_left) {
00971 av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
00972 return AVERROR_INVALIDDATA;
00973 } else if(asf->packet_frag_size > asf->packet_size_left - rsize){
00974 if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) {
00975 av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n", asf->packet_size_left, rsize);
00976 return AVERROR_INVALIDDATA;
00977 } else {
00978 int diff = asf->packet_frag_size - (asf->packet_size_left - rsize);
00979 asf->packet_size_left += diff;
00980 asf->packet_padsize -= diff;
00981 }
00982 }
00983
00984 } else {
00985 asf->packet_frag_size = asf->packet_size_left - rsize;
00986
00987 }
00988 if (asf->packet_replic_size == 1) {
00989 asf->packet_multi_size = asf->packet_frag_size;
00990 if (asf->packet_multi_size > asf->packet_size_left)
00991 return AVERROR_INVALIDDATA;
00992 }
00993 asf->packet_size_left -= rsize;
00994
00995
00996 return 0;
00997 }
00998
01008 static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
01009 {
01010 ASFContext *asf = s->priv_data;
01011 ASFStream *asf_st = 0;
01012 for (;;) {
01013 int ret;
01014 if(url_feof(pb))
01015 return AVERROR_EOF;
01016 if (asf->packet_size_left < FRAME_HEADER_SIZE
01017 || asf->packet_segments < 1) {
01018
01019 int ret = asf->packet_size_left + asf->packet_padsize;
01020
01021 assert(ret>=0);
01022
01023 avio_skip(pb, ret);
01024
01025 asf->packet_pos= avio_tell(pb);
01026 if (asf->data_object_size != (uint64_t)-1 &&
01027 (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
01028 return AVERROR_EOF;
01029 return 1;
01030 }
01031 if (asf->packet_time_start == 0) {
01032 if(asf_read_frame_header(s, pb) < 0){
01033 asf->packet_segments= 0;
01034 continue;
01035 }
01036 if (asf->stream_index < 0
01037 || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL
01038 || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)
01039 ) {
01040 asf->packet_time_start = 0;
01041
01042 avio_skip(pb, asf->packet_frag_size);
01043 asf->packet_size_left -= asf->packet_frag_size;
01044 if(asf->stream_index < 0)
01045 av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size);
01046 continue;
01047 }
01048 asf->asf_st = s->streams[asf->stream_index]->priv_data;
01049 }
01050 asf_st = asf->asf_st;
01051
01052 if (asf->packet_replic_size == 1) {
01053
01054 asf->packet_frag_timestamp = asf->packet_time_start;
01055 asf->packet_time_start += asf->packet_time_delta;
01056 asf->packet_obj_size = asf->packet_frag_size = avio_r8(pb);
01057 asf->packet_size_left--;
01058 asf->packet_multi_size--;
01059 if (asf->packet_multi_size < asf->packet_obj_size)
01060 {
01061 asf->packet_time_start = 0;
01062 avio_skip(pb, asf->packet_multi_size);
01063 asf->packet_size_left -= asf->packet_multi_size;
01064 continue;
01065 }
01066 asf->packet_multi_size -= asf->packet_obj_size;
01067
01068 }
01069 if(
01070 asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size
01071 && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){
01072 av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
01073 asf_st->frag_offset, asf->packet_frag_size,
01074 asf->packet_obj_size, asf_st->pkt.size);
01075 asf->packet_obj_size= asf_st->pkt.size;
01076 }
01077
01078 if ( asf_st->pkt.size != asf->packet_obj_size
01079 || asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {
01080 if(asf_st->pkt.data){
01081 av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", asf_st->pkt.size, asf->packet_obj_size);
01082 asf_st->frag_offset = 0;
01083 av_free_packet(&asf_st->pkt);
01084 }
01085
01086 av_new_packet(&asf_st->pkt, asf->packet_obj_size);
01087 asf_st->seq = asf->packet_seq;
01088 asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll;
01089 asf_st->pkt.stream_index = asf->stream_index;
01090 asf_st->pkt.pos =
01091 asf_st->packet_pos= asf->packet_pos;
01092 if (asf_st->pkt.data && asf_st->palette_changed) {
01093 uint8_t *pal;
01094 pal = av_packet_new_side_data(&asf_st->pkt, AV_PKT_DATA_PALETTE,
01095 AVPALETTE_SIZE);
01096 if (!pal) {
01097 av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n");
01098 } else {
01099 memcpy(pal, asf_st->palette, AVPALETTE_SIZE);
01100 asf_st->palette_changed = 0;
01101 }
01102 }
01103
01104
01105
01106 if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
01107 asf->packet_key_frame = 1;
01108 if (asf->packet_key_frame)
01109 asf_st->pkt.flags |= AV_PKT_FLAG_KEY;
01110 }
01111
01112
01113
01114
01115
01116 asf->packet_size_left -= asf->packet_frag_size;
01117 if (asf->packet_size_left < 0)
01118 continue;
01119
01120 if( asf->packet_frag_offset >= asf_st->pkt.size
01121 || asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset){
01122 av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n",
01123 asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size);
01124 continue;
01125 }
01126
01127 ret = avio_read(pb, asf_st->pkt.data + asf->packet_frag_offset,
01128 asf->packet_frag_size);
01129 if (ret != asf->packet_frag_size) {
01130 if (ret < 0 || asf->packet_frag_offset + ret == 0)
01131 return ret < 0 ? ret : AVERROR_EOF;
01132 if (asf_st->ds_span > 1) {
01133
01134
01135
01136 memset(asf_st->pkt.data + asf->packet_frag_offset + ret, 0,
01137 asf->packet_frag_size - ret);
01138 ret = asf->packet_frag_size;
01139 } else
01140
01141 av_shrink_packet(&asf_st->pkt, asf->packet_frag_offset + ret);
01142 }
01143 if (s->key && s->keylen == 20)
01144 ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,
01145 ret);
01146 asf_st->frag_offset += ret;
01147
01148 if (asf_st->frag_offset == asf_st->pkt.size) {
01149
01150 if( s->streams[asf->stream_index]->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO
01151 && asf_st->pkt.size > 100){
01152 int i;
01153 for(i=0; i<asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
01154 if(i == asf_st->pkt.size){
01155 av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
01156 asf_st->frag_offset = 0;
01157 av_free_packet(&asf_st->pkt);
01158 continue;
01159 }
01160 }
01161
01162
01163 if (asf_st->ds_span > 1) {
01164 if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){
01165 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);
01166 }else{
01167
01168 uint8_t *newdata = av_malloc(asf_st->pkt.size + FF_INPUT_BUFFER_PADDING_SIZE);
01169 if (newdata) {
01170 int offset = 0;
01171 memset(newdata + asf_st->pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
01172 while (offset < asf_st->pkt.size) {
01173 int off = offset / asf_st->ds_chunk_size;
01174 int row = off / asf_st->ds_span;
01175 int col = off % asf_st->ds_span;
01176 int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;
01177
01178
01179 assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);
01180 assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
01181 memcpy(newdata + offset,
01182 asf_st->pkt.data + idx * asf_st->ds_chunk_size,
01183 asf_st->ds_chunk_size);
01184 offset += asf_st->ds_chunk_size;
01185 }
01186 av_free(asf_st->pkt.data);
01187 asf_st->pkt.data = newdata;
01188 }
01189 }
01190 }
01191 asf_st->frag_offset = 0;
01192 *pkt= asf_st->pkt;
01193
01194 asf_st->pkt.size = 0;
01195 asf_st->pkt.data = 0;
01196 asf_st->pkt.side_data_elems = 0;
01197 asf_st->pkt.side_data = NULL;
01198 break;
01199 }
01200 }
01201 return 0;
01202 }
01203
01204 static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
01205 {
01206 ASFContext *asf = s->priv_data;
01207
01208 for (;;) {
01209 int ret;
01210
01211
01212 if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
01213 return ret;
01214 if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
01215 assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
01216 asf->packet_time_start = 0;
01217 }
01218 }
01219
01220
01221
01222
01223 static void asf_reset_header(AVFormatContext *s)
01224 {
01225 ASFContext *asf = s->priv_data;
01226 ASFStream *asf_st;
01227 int i;
01228
01229 asf->packet_size_left = 0;
01230 asf->packet_segments = 0;
01231 asf->packet_flags = 0;
01232 asf->packet_property = 0;
01233 asf->packet_timestamp = 0;
01234 asf->packet_segsizetype = 0;
01235 asf->packet_segments = 0;
01236 asf->packet_seq = 0;
01237 asf->packet_replic_size = 0;
01238 asf->packet_key_frame = 0;
01239 asf->packet_padsize = 0;
01240 asf->packet_frag_offset = 0;
01241 asf->packet_frag_size = 0;
01242 asf->packet_frag_timestamp = 0;
01243 asf->packet_multi_size = 0;
01244 asf->packet_obj_size = 0;
01245 asf->packet_time_delta = 0;
01246 asf->packet_time_start = 0;
01247
01248 for(i=0; i<s->nb_streams; i++){
01249 asf_st= s->streams[i]->priv_data;
01250 av_free_packet(&asf_st->pkt);
01251 asf_st->frag_offset=0;
01252 asf_st->seq=0;
01253 }
01254 asf->asf_st= NULL;
01255 }
01256
01257 static int asf_read_close(AVFormatContext *s)
01258 {
01259 asf_reset_header(s);
01260
01261 return 0;
01262 }
01263
01264 static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
01265 {
01266 AVPacket pkt1, *pkt = &pkt1;
01267 ASFStream *asf_st;
01268 int64_t pts;
01269 int64_t pos= *ppos;
01270 int i;
01271 int64_t start_pos[ASF_MAX_STREAMS];
01272
01273 for(i=0; i<s->nb_streams; i++){
01274 start_pos[i]= pos;
01275 }
01276
01277 if (s->packet_size > 0)
01278 pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;
01279 *ppos= pos;
01280 if (avio_seek(s->pb, pos, SEEK_SET) < 0)
01281 return AV_NOPTS_VALUE;
01282
01283
01284 asf_reset_header(s);
01285 for(;;){
01286 if (av_read_frame(s, pkt) < 0){
01287 av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
01288 return AV_NOPTS_VALUE;
01289 }
01290
01291 pts = pkt->dts;
01292
01293 av_free_packet(pkt);
01294 if(pkt->flags&AV_PKT_FLAG_KEY){
01295 i= pkt->stream_index;
01296
01297 asf_st= s->streams[i]->priv_data;
01298
01299
01300 pos= asf_st->packet_pos;
01301
01302 av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
01303 start_pos[i]= asf_st->packet_pos + 1;
01304
01305 if(pkt->stream_index == stream_index)
01306 break;
01307 }
01308 }
01309
01310 *ppos= pos;
01311
01312
01313 return pts;
01314 }
01315
01316 static void asf_build_simple_index(AVFormatContext *s, int stream_index)
01317 {
01318 ff_asf_guid g;
01319 ASFContext *asf = s->priv_data;
01320 int64_t current_pos= avio_tell(s->pb);
01321
01322 if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) {
01323 asf->index_read= -1;
01324 return;
01325 }
01326
01327 ff_get_guid(s->pb, &g);
01328
01329
01330
01331 while (ff_guidcmp(&g, &ff_asf_simple_index_header)) {
01332 int64_t gsize= avio_rl64(s->pb);
01333 if (gsize < 24 || url_feof(s->pb)) {
01334 avio_seek(s->pb, current_pos, SEEK_SET);
01335 asf->index_read= -1;
01336 return;
01337 }
01338 avio_skip(s->pb, gsize-24);
01339 ff_get_guid(s->pb, &g);
01340 }
01341
01342 {
01343 int64_t itime, last_pos=-1;
01344 int pct, ict;
01345 int i;
01346 int64_t av_unused gsize= avio_rl64(s->pb);
01347 ff_get_guid(s->pb, &g);
01348 itime=avio_rl64(s->pb);
01349 pct=avio_rl32(s->pb);
01350 ict=avio_rl32(s->pb);
01351 av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
01352
01353 for (i=0;i<ict;i++){
01354 int pktnum=avio_rl32(s->pb);
01355 int pktct =avio_rl16(s->pb);
01356 int64_t pos = s->data_offset + s->packet_size*(int64_t)pktnum;
01357 int64_t index_pts= FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0);
01358
01359 if(pos != last_pos){
01360 av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d pts: %"PRId64"\n", pktnum, pktct, index_pts);
01361 av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
01362 last_pos=pos;
01363 }
01364 }
01365 asf->index_read= ict > 1;
01366 }
01367 avio_seek(s->pb, current_pos, SEEK_SET);
01368 }
01369
01370 static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
01371 {
01372 ASFContext *asf = s->priv_data;
01373 AVStream *st = s->streams[stream_index];
01374
01375 if (s->packet_size <= 0)
01376 return -1;
01377
01378
01379 if(s->pb) {
01380 int ret = avio_seek_time(s->pb, stream_index, pts, flags);
01381 if(ret >= 0)
01382 asf_reset_header(s);
01383 if (ret != AVERROR(ENOSYS))
01384 return ret;
01385 }
01386
01387 if (!asf->index_read)
01388 asf_build_simple_index(s, stream_index);
01389
01390 if((asf->index_read > 0 && st->index_entries)){
01391 int index= av_index_search_timestamp(st, pts, flags);
01392 if(index >= 0) {
01393
01394 uint64_t pos = st->index_entries[index].pos;
01395
01396
01397 av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
01398 if(avio_seek(s->pb, pos, SEEK_SET) < 0)
01399 return -1;
01400 asf_reset_header(s);
01401 return 0;
01402 }
01403 }
01404
01405 if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0)
01406 return -1;
01407 asf_reset_header(s);
01408 return 0;
01409 }
01410
01411 AVInputFormat ff_asf_demuxer = {
01412 .name = "asf",
01413 .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
01414 .priv_data_size = sizeof(ASFContext),
01415 .read_probe = asf_probe,
01416 .read_header = asf_read_header,
01417 .read_packet = asf_read_packet,
01418 .read_close = asf_read_close,
01419 .read_seek = asf_read_seek,
01420 .read_timestamp = asf_read_pts,
01421 .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
01422 .priv_class = &asf_class,
01423 };