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