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.
This commit is contained in:
Justin Ruggles 2012-01-18 19:50:37 -05:00
parent 9546f331c6
commit 773ff823da

View File

@ -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;