Mercurial > libavformat.hg
changeset 4704:2b641c55e83e libavformat
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).
author | reimar |
---|---|
date | Thu, 12 Mar 2009 11:47:50 +0000 |
parents | 901ceeb9ab2d |
children | 492dd0722ee1 |
files | idroq.c |
diffstat | 1 files changed, 25 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/idroq.c Wed Mar 11 08:05:18 2009 +0000 +++ b/idroq.c Thu Mar 12 11:47:50 2009 +0000 @@ -73,9 +73,6 @@ 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 @@ /* init private context parameters */ roq->width = roq->height = roq->audio_channels = roq->video_pts = roq->audio_frame_count = 0; - - /* 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; + roq->audio_stream_index = -1; - 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 @@ 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 @@ 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 @@ 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))