diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 53c2fe7eac..3b5e5c4413 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -49,6 +49,7 @@ typedef struct AVIIentry { typedef struct AVIIndex { int64_t indx_start; + int64_t audio_strm_offset; int entry; int ents_allocated; AVIIentry** cluster; @@ -66,6 +67,7 @@ typedef struct AVIStream { int packet_count; int entry; int max_size; + int sample_requested; int64_t last_dts; @@ -91,6 +93,7 @@ static int64_t avi_start_new_riff(AVFormatContext *s, AVIOContext *pb, avi->riff_id++; for (i = 0; i < s->nb_streams; i++) { AVIStream *avist = s->streams[i]->priv_data; + avist->indexes.audio_strm_offset = avist->audio_strm_length; avist->indexes.entry = 0; } @@ -476,6 +479,7 @@ static int avi_write_ix(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVIStream *avist = s->streams[i]->priv_data; int64_t ix, pos; + int au_byterate, au_ssize, au_scale; avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type); ix_tag[3] = '0' + i; @@ -511,7 +515,16 @@ static int avi_write_ix(AVFormatContext *s) avio_skip(pb, 16 * avi->riff_id); avio_wl64(pb, ix); /* qwOffset */ avio_wl32(pb, pos - ix); /* dwSize */ - avio_wl32(pb, avist->indexes.entry); /* dwDuration */ + ff_parse_specific_params(s->streams[i], &au_byterate, &au_ssize, &au_scale); + if (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && au_ssize > 0) { + uint32_t audio_segm_size = (avist->audio_strm_length - avist->indexes.audio_strm_offset); + if ((audio_segm_size % au_ssize > 0) && !avist->sample_requested) { + avpriv_request_sample(s, "OpenDML index duration for audio packets with partial frames"); + avist->sample_requested = 1; + } + avio_wl32(pb, audio_segm_size / au_ssize); /* dwDuration (sample count) */ + } else + avio_wl32(pb, avist->indexes.entry); /* dwDuration (packet count) */ avio_seek(pb, pos, SEEK_SET); }