From 773ff823dac3da733c251b4cb1cc95b3b7e03001 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 19:50:37 -0500 Subject: bethsoftvid: add audio stream only after getting the first audio packet This avoids initializing a stream with dummy values or when the file does not contain audio. Also set duration for audio packets, using the sample rate as the time base. --- libavformat/bethsoftvid.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index 10be7d2521..1092299874 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -34,14 +34,18 @@ #define BVID_PALETTE_SIZE 3 * 256 +#define DEFAULT_SAMPLE_RATE 11111 + typedef struct BVID_DemuxContext { int nframes; + int sample_rate; /**< audio sample rate */ /** delay value between frames, added to individual frame delay. * custom units, which will be added to other custom units (~=16ms according * to free, unofficial documentation) */ int bethsoft_global_delay; - + int video_index; /**< video stream index */ + int audio_index; /**< audio stream index */ uint8_t *palette; int is_finished; @@ -73,6 +77,7 @@ static int vid_read_header(AVFormatContext *s) stream = avformat_new_stream(s, NULL); if (!stream) return AVERROR(ENOMEM); + vid->video_index = stream->index; stream->start_time = 0; avpriv_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; @@ -83,16 +88,9 @@ static int vid_read_header(AVFormatContext *s) vid->bethsoft_global_delay = avio_rl16(pb); avio_rl16(pb); - // done with video codec, set up audio codec - stream = avformat_new_stream(s, NULL); - if (!stream) - return AVERROR(ENOMEM); - stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - stream->codec->codec_id = CODEC_ID_PCM_U8; - stream->codec->channels = 1; - stream->codec->sample_rate = 11025; - stream->codec->bits_per_coded_sample = 8; - stream->codec->bit_rate = stream->codec->channels * stream->codec->sample_rate * stream->codec->bits_per_coded_sample; + // wait until the first audio packet to create the audio stream + vid->audio_index = -1; + s->ctx_flags |= AVFMTCTX_NOHEADER; return 0; } @@ -168,7 +166,7 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, av_free(vidbuf_start); pkt->pos = position; - pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream + pkt->stream_index = vid->video_index; pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; @@ -219,9 +217,22 @@ static int vid_read_packet(AVFormatContext *s, case FIRST_AUDIO_BLOCK: avio_rl16(pb); // soundblaster DAC used for sample rate, as on specification page (link above) - s->streams[1]->codec->sample_rate = 1000000 / (256 - avio_r8(pb)); - s->streams[1]->codec->bit_rate = s->streams[1]->codec->channels * s->streams[1]->codec->sample_rate * s->streams[1]->codec->bits_per_coded_sample; + vid->sample_rate = 1000000 / (256 - avio_r8(pb)); case AUDIO_BLOCK: + if (vid->audio_index < 0) { + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + vid->audio_index = st->index; + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_PCM_U8; + st->codec->channels = 1; + st->codec->bits_per_coded_sample = 8; + st->codec->sample_rate = vid->sample_rate; + st->codec->bit_rate = 8 * st->codec->sample_rate; + st->start_time = 0; + avpriv_set_pts_info(st, 64, 1, vid->sample_rate); + } audio_length = avio_rl16(pb); if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) { if (ret_value < 0) @@ -229,7 +240,8 @@ static int vid_read_packet(AVFormatContext *s, av_log(s, AV_LOG_ERROR, "incomplete audio block\n"); return AVERROR(EIO); } - pkt->stream_index = 1; + pkt->stream_index = vid->audio_index; + pkt->duration = audio_length; pkt->flags |= AV_PKT_FLAG_KEY; return 0; -- cgit v1.2.3