From 8bf6db1b29f3766732e2bb2bdd2681318fd8e215 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 9 Feb 2011 21:55:57 +0100 Subject: asfdec: split reading stream properties out of asf_read_header() This contains a rename from gsize->size Signed-off-by: Ronald S. Bultje --- libavformat/asfdec.c | 362 ++++++++++++++++++++++++++------------------------- 1 file changed, 186 insertions(+), 176 deletions(-) (limited to 'libavformat') diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 0ee6667a27..8e712a6c5b 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -206,6 +206,191 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size) return 0; } +static int asf_read_stream_properties(AVFormatContext *s, int64_t size) +{ + ASFContext *asf = s->priv_data; + ByteIOContext *pb = s->pb; + AVStream *st; + ASFStream *asf_st; + ff_asf_guid g; + enum AVMediaType type; + int type_specific_size, sizeX; + uint64_t total_size; + unsigned int tag1; + int64_t pos1, pos2, start_time; + int test_for_ext_stream_audio, is_dvr_ms_audio=0; + + if (s->nb_streams == ASF_MAX_STREAMS) { + av_log(s, AV_LOG_ERROR, "too many streams\n"); + return AVERROR(EINVAL); + } + + pos1 = url_ftell(pb); + + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ + asf_st = av_mallocz(sizeof(ASFStream)); + if (!asf_st) + return AVERROR(ENOMEM); + st->priv_data = asf_st; + start_time = asf->hdr.preroll; + + asf_st->stream_language_index = 128; // invalid stream index means no language info + + if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... + st->duration = asf->hdr.play_time / + (10000000 / 1000) - start_time; + } + ff_get_guid(pb, &g); + + test_for_ext_stream_audio = 0; + if (!ff_guidcmp(&g, &ff_asf_audio_stream)) { + type = AVMEDIA_TYPE_AUDIO; + } else if (!ff_guidcmp(&g, &ff_asf_video_stream)) { + type = AVMEDIA_TYPE_VIDEO; + } else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) { + type = AVMEDIA_TYPE_VIDEO; + st->codec->codec_id = CODEC_ID_MJPEG; + } else if (!ff_guidcmp(&g, &ff_asf_command_stream)) { + type = AVMEDIA_TYPE_DATA; + } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) { + test_for_ext_stream_audio = 1; + type = AVMEDIA_TYPE_UNKNOWN; + } else { + return -1; + } + ff_get_guid(pb, &g); + total_size = get_le64(pb); + type_specific_size = get_le32(pb); + get_le32(pb); + st->id = get_le16(pb) & 0x7f; /* stream id */ + // mapping of asf ID to AV stream ID; + asf->asfid2avid[st->id] = s->nb_streams - 1; + + get_le32(pb); + + if (test_for_ext_stream_audio) { + ff_get_guid(pb, &g); + if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) { + type = AVMEDIA_TYPE_AUDIO; + is_dvr_ms_audio=1; + ff_get_guid(pb, &g); + get_le32(pb); + get_le32(pb); + get_le32(pb); + ff_get_guid(pb, &g); + get_le32(pb); + } + } + + st->codec->codec_type = type; + if (type == AVMEDIA_TYPE_AUDIO) { + ff_get_wav_header(pb, st->codec, type_specific_size); + if (is_dvr_ms_audio) { + // codec_id and codec_tag are unreliable in dvr_ms + // files. Set them later by probing stream. + st->codec->codec_id = CODEC_ID_PROBE; + st->codec->codec_tag = 0; + } + if (st->codec->codec_id == CODEC_ID_AAC) { + st->need_parsing = AVSTREAM_PARSE_NONE; + } else { + st->need_parsing = AVSTREAM_PARSE_FULL; + } + /* We have to init the frame size at some point .... */ + pos2 = url_ftell(pb); + if (size >= (pos2 + 8 - pos1 + 24)) { + asf_st->ds_span = get_byte(pb); + asf_st->ds_packet_size = get_le16(pb); + asf_st->ds_chunk_size = get_le16(pb); + get_le16(pb); //ds_data_size + get_byte(pb); //ds_silence_data + } + //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", + // asf_st->ds_packet_size, asf_st->ds_chunk_size, + // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); + if (asf_st->ds_span > 1) { + if (!asf_st->ds_chunk_size + || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1) + || asf_st->ds_packet_size % asf_st->ds_chunk_size) + asf_st->ds_span = 0; // disable descrambling + } + switch (st->codec->codec_id) { + case CODEC_ID_MP3: + st->codec->frame_size = MPA_FRAME_SIZE; + break; + case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_U16LE: + case CODEC_ID_PCM_U16BE: + case CODEC_ID_PCM_S8: + case CODEC_ID_PCM_U8: + case CODEC_ID_PCM_ALAW: + case CODEC_ID_PCM_MULAW: + st->codec->frame_size = 1; + break; + default: + /* This is probably wrong, but it prevents a crash later */ + st->codec->frame_size = 1; + break; + } + } else if (type == AVMEDIA_TYPE_VIDEO && + size - (url_ftell(pb) - pos1 + 24) >= 51) { + get_le32(pb); + get_le32(pb); + get_byte(pb); + get_le16(pb); /* size */ + sizeX= get_le32(pb); /* size */ + st->codec->width = get_le32(pb); + st->codec->height = get_le32(pb); + /* not available for asf */ + get_le16(pb); /* panes */ + st->codec->bits_per_coded_sample = get_le16(pb); /* depth */ + tag1 = get_le32(pb); + url_fskip(pb, 20); + // av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX); + if (sizeX > 40) { + st->codec->extradata_size = sizeX - 40; + st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + get_buffer(pb, st->codec->extradata, st->codec->extradata_size); + } + + /* Extract palette from extradata if bpp <= 8 */ + /* This code assumes that extradata contains only palette */ + /* This is true for all paletted codecs implemented in ffmpeg */ + if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { + st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); +#if HAVE_BIGENDIAN + for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) + st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); +#else + memcpy(st->codec->palctrl->palette, st->codec->extradata, + FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); +#endif + st->codec->palctrl->palette_changed = 1; + } + + st->codec->codec_tag = tag1; + st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); + if(tag1 == MKTAG('D', 'V', 'R', ' ')){ + st->need_parsing = AVSTREAM_PARSE_FULL; + // issue658 containse wrong w/h and MS even puts a fake seq header with wrong w/h in extradata while a correct one is in te stream. maximum lameness + st->codec->width = + st->codec->height = 0; + av_freep(&st->codec->extradata); + st->codec->extradata_size=0; + } + if(st->codec->codec_id == CODEC_ID_H264) + st->need_parsing = AVSTREAM_PARSE_FULL_ONCE; + } + pos2 = url_ftell(pb); + url_fskip(pb, size - (pos2 - pos1 + 24)); + + return 0; +} + static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size) { ASFContext *asf = s->priv_data; @@ -396,8 +581,6 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) ASFContext *asf = s->priv_data; ff_asf_guid g; ByteIOContext *pb = s->pb; - AVStream *st; - ASFStream *asf_st; int i; int64_t gsize; @@ -431,180 +614,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (!ff_guidcmp(&g, &ff_asf_file_header)) { asf_read_file_properties(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) { - enum AVMediaType type; - int type_specific_size, sizeX; - uint64_t total_size; - unsigned int tag1; - int64_t pos1, pos2, start_time; - int test_for_ext_stream_audio, is_dvr_ms_audio=0; - - if (s->nb_streams == ASF_MAX_STREAMS) { - av_log(s, AV_LOG_ERROR, "too many streams\n"); - return AVERROR(EINVAL); - } - - pos1 = url_ftell(pb); - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ - asf_st = av_mallocz(sizeof(ASFStream)); - if (!asf_st) - return AVERROR(ENOMEM); - st->priv_data = asf_st; - start_time = asf->hdr.preroll; - - asf_st->stream_language_index = 128; // invalid stream index means no language info - - if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... - st->duration = asf->hdr.play_time / - (10000000 / 1000) - start_time; - } - ff_get_guid(pb, &g); - - test_for_ext_stream_audio = 0; - if (!ff_guidcmp(&g, &ff_asf_audio_stream)) { - type = AVMEDIA_TYPE_AUDIO; - } else if (!ff_guidcmp(&g, &ff_asf_video_stream)) { - type = AVMEDIA_TYPE_VIDEO; - } else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) { - type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MJPEG; - } else if (!ff_guidcmp(&g, &ff_asf_command_stream)) { - type = AVMEDIA_TYPE_DATA; - } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) { - test_for_ext_stream_audio = 1; - type = AVMEDIA_TYPE_UNKNOWN; - } else { - return -1; - } - ff_get_guid(pb, &g); - total_size = get_le64(pb); - type_specific_size = get_le32(pb); - get_le32(pb); - st->id = get_le16(pb) & 0x7f; /* stream id */ - // mapping of asf ID to AV stream ID; - asf->asfid2avid[st->id] = s->nb_streams - 1; - - get_le32(pb); - - if (test_for_ext_stream_audio) { - ff_get_guid(pb, &g); - if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) { - type = AVMEDIA_TYPE_AUDIO; - is_dvr_ms_audio=1; - ff_get_guid(pb, &g); - get_le32(pb); - get_le32(pb); - get_le32(pb); - ff_get_guid(pb, &g); - get_le32(pb); - } - } - - st->codec->codec_type = type; - if (type == AVMEDIA_TYPE_AUDIO) { - ff_get_wav_header(pb, st->codec, type_specific_size); - if (is_dvr_ms_audio) { - // codec_id and codec_tag are unreliable in dvr_ms - // files. Set them later by probing stream. - st->codec->codec_id = CODEC_ID_PROBE; - st->codec->codec_tag = 0; - } - if (st->codec->codec_id == CODEC_ID_AAC) { - st->need_parsing = AVSTREAM_PARSE_NONE; - } else { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - /* We have to init the frame size at some point .... */ - pos2 = url_ftell(pb); - if (gsize >= (pos2 + 8 - pos1 + 24)) { - asf_st->ds_span = get_byte(pb); - asf_st->ds_packet_size = get_le16(pb); - asf_st->ds_chunk_size = get_le16(pb); - get_le16(pb); //ds_data_size - get_byte(pb); //ds_silence_data - } - //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", - // asf_st->ds_packet_size, asf_st->ds_chunk_size, - // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); - if (asf_st->ds_span > 1) { - if (!asf_st->ds_chunk_size - || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1) - || asf_st->ds_packet_size % asf_st->ds_chunk_size) - asf_st->ds_span = 0; // disable descrambling - } - switch (st->codec->codec_id) { - case CODEC_ID_MP3: - st->codec->frame_size = MPA_FRAME_SIZE; - break; - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - st->codec->frame_size = 1; - break; - default: - /* This is probably wrong, but it prevents a crash later */ - st->codec->frame_size = 1; - break; - } - } else if (type == AVMEDIA_TYPE_VIDEO && - gsize - (url_ftell(pb) - pos1 + 24) >= 51) { - get_le32(pb); - get_le32(pb); - get_byte(pb); - get_le16(pb); /* size */ - sizeX= get_le32(pb); /* size */ - st->codec->width = get_le32(pb); - st->codec->height = get_le32(pb); - /* not available for asf */ - get_le16(pb); /* panes */ - st->codec->bits_per_coded_sample = get_le16(pb); /* depth */ - tag1 = get_le32(pb); - url_fskip(pb, 20); -// av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX); - if (sizeX > 40) { - st->codec->extradata_size = sizeX - 40; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - get_buffer(pb, st->codec->extradata, st->codec->extradata_size); - } - - /* Extract palette from extradata if bpp <= 8 */ - /* This code assumes that extradata contains only palette */ - /* This is true for all paletted codecs implemented in ffmpeg */ - if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { - st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); -#if HAVE_BIGENDIAN - for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) - st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); -#else - memcpy(st->codec->palctrl->palette, st->codec->extradata, - FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); -#endif - st->codec->palctrl->palette_changed = 1; - } - - st->codec->codec_tag = tag1; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); - if(tag1 == MKTAG('D', 'V', 'R', ' ')){ - st->need_parsing = AVSTREAM_PARSE_FULL; - // issue658 containse wrong w/h and MS even puts a fake seq header with wrong w/h in extradata while a correct one is in te stream. maximum lameness - st->codec->width = - st->codec->height = 0; - av_freep(&st->codec->extradata); - st->codec->extradata_size=0; - } - if(st->codec->codec_id == CODEC_ID_H264) - st->need_parsing = AVSTREAM_PARSE_FULL_ONCE; - } - pos2 = url_ftell(pb); - url_fskip(pb, gsize - (pos2 - pos1 + 24)); + asf_read_stream_properties(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) { asf_read_content_desc(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_language_guid)) { -- cgit v1.2.3