Skip to content

Commit

Permalink
libavformat/matroskadec: set fixed duration for subtitles
Browse files Browse the repository at this point in the history
The matroska specification states the start time and duration of
subtitle entries are encoded in the block TimeStamp
and BlockDuration. Furthermore, for all subtitle formats except
S_HDMV/PGS the BlockDuration must always be defined and have an
absolute value even if it is simply 0. ffmpeg assumes that a duration
of 0 means the duration is still unknown and tries to adjust based on
the next packet pts. This is wrong for all formats except S_HDMV/PGS.
Since changing the semantics of duration 0 is not an option (touches
too many parts of the code) this change introduces
AV_PKT_FLAG_FIXED_DURATION flag which decoders might use to flag the
duration of a given packet should not be changed.

Signed-off-by: Miguel Borges de Freitas <enen92@kodi.tv>
  • Loading branch information
enen92 committed Jan 10, 2023
1 parent 94aa70d commit 30cd632
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 1 deletion.
5 changes: 5 additions & 0 deletions libavcodec/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,11 @@ typedef struct AVPacketList {
* be discarded by the decoder. I.e. Non-reference frames.
*/
#define AV_PKT_FLAG_DISPOSABLE 0x0010
/**
* Flag is used to indicate packets in which the duration is absolute
* and should not be changed.
*/
#define AV_PKT_FLAG_FIXED_DURATION 0x0020

enum AVSideDataParamChangeFlags {
#if FF_API_OLD_CHANNEL_LAYOUT
Expand Down
3 changes: 2 additions & 1 deletion libavformat/demux.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,8 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st,
pktl->pkt.dts = cur_dts;
if (!sti->avctx->has_b_frames)
pktl->pkt.pts = cur_dts;
pktl->pkt.duration = duration;
if ((pktl->pkt.flags & AV_PKT_FLAG_FIXED_DURATION) != AV_PKT_FLAG_FIXED_DURATION)
pktl->pkt.duration = duration;
} else
break;
cur_dts = pktl->pkt.dts + pktl->pkt.duration;
Expand Down
4 changes: 4 additions & 0 deletions libavformat/matroskadec.c
Original file line number Diff line number Diff line change
Expand Up @@ -3673,6 +3673,10 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
pkt->pos = pos;
pkt->duration = lace_duration;

if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
st->codecpar->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE)
pkt->flags |= AV_PKT_FLAG_FIXED_DURATION;

res = avpriv_packet_list_put(&matroska->queue, pkt, NULL, 0);
if (res < 0) {
av_packet_unref(pkt);
Expand Down

0 comments on commit 30cd632

Please sign in to comment.