From 15969b55d150212d2b1c5dbd6a2054e54ddd4d57 Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Thu, 12 Mar 2009 11:47:50 +0000 Subject: Set video width/height and create audio stream in read_packet instead of pre-parsing the file in read_header. This avoids some code duplication and seeking, and also avoids an IO error for small video-only files (as created during e.g. the FATE encoder test). Originally committed as revision 17945 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/idroq.c | 98 ++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 73 deletions(-) (limited to 'libavformat/idroq.c') diff --git a/libavformat/idroq.c b/libavformat/idroq.c index 7cf3808e22..8ab3eda14e 100644 --- a/libavformat/idroq.c +++ b/libavformat/idroq.c @@ -73,9 +73,6 @@ static int roq_read_header(AVFormatContext *s, ByteIOContext *pb = s->pb; AVStream *st; unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; - int i; - unsigned int chunk_size; - unsigned int chunk_type; /* get the main header */ if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != @@ -87,58 +84,8 @@ static int roq_read_header(AVFormatContext *s, /* init private context parameters */ roq->width = roq->height = roq->audio_channels = roq->video_pts = roq->audio_frame_count = 0; + roq->audio_stream_index = -1; - /* scan the first n chunks searching for A/V parameters */ - for (i = 0; i < RoQ_CHUNKS_TO_SCAN; i++) { - if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - - chunk_type = AV_RL16(&preamble[0]); - chunk_size = AV_RL32(&preamble[2]); - - switch (chunk_type) { - - case RoQ_INFO: - /* fetch the width and height; reuse the preamble bytes */ - if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - roq->width = AV_RL16(&preamble[0]); - roq->height = AV_RL16(&preamble[2]); - break; - - case RoQ_QUAD_CODEBOOK: - case RoQ_QUAD_VQ: - /* ignore during this scan */ - url_fseek(pb, chunk_size, SEEK_CUR); - break; - - case RoQ_SOUND_MONO: - roq->audio_channels = 1; - url_fseek(pb, chunk_size, SEEK_CUR); - break; - - case RoQ_SOUND_STEREO: - roq->audio_channels = 2; - url_fseek(pb, chunk_size, SEEK_CUR); - break; - - default: - av_log(s, AV_LOG_ERROR, " unknown RoQ chunk type (%04X)\n", AV_RL16(&preamble[0])); - return AVERROR_INVALIDDATA; - break; - } - - /* if all necessary parameters have been gathered, exit early */ - if ((roq->width && roq->height) && roq->audio_channels) - break; - } - - /* seek back to the first chunk */ - url_fseek(pb, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_SET); - - /* initialize the decoders */ st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); @@ -148,25 +95,6 @@ static int roq_read_header(AVFormatContext *s, st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_ROQ; st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = roq->width; - st->codec->height = roq->height; - - if (roq->audio_channels) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, 90000); - roq->audio_stream_index = st->index; - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ROQ_DPCM; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = roq->audio_channels; - st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE; - st->codec->bits_per_coded_sample = 16; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - } return 0; } @@ -202,6 +130,14 @@ static int roq_read_packet(AVFormatContext *s, switch (chunk_type) { case RoQ_INFO: + if (!roq->width || !roq->height) { + AVStream *st = s->streams[roq->video_stream_index]; + if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) + return AVERROR(EIO); + st->codec->width = roq->width = AV_RL16(preamble); + st->codec->height = roq->height = AV_RL16(preamble + 2); + break; + } /* don't care about this chunk anymore */ url_fseek(pb, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_CUR); break; @@ -233,6 +169,22 @@ static int roq_read_packet(AVFormatContext *s, case RoQ_SOUND_MONO: case RoQ_SOUND_STEREO: + if (roq->audio_stream_index == -1) { + AVStream *st = av_new_stream(s, 1); + if (!st) + return AVERROR(ENOMEM); + av_set_pts_info(st, 33, 1, 90000); + roq->audio_stream_index = st->index; + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_ROQ_DPCM; + st->codec->codec_tag = 0; /* no tag */ + st->codec->channels = roq->audio_channels = chunk_type == RoQ_SOUND_STEREO ? 2 : 1; + st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE; + st->codec->bits_per_coded_sample = 16; + st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * + st->codec->bits_per_coded_sample; + st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; + } case RoQ_QUAD_VQ: /* load up the packet */ if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE)) -- cgit v1.2.3