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