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:
parent
9546f331c6
commit
773ff823da
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user