From b972dab39d81d5f291cea4b9a042beb63386e768 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Fri, 9 Apr 2021 01:00:51 +0200 Subject: avformat/matroskaenc: Put subtitles without duration into SimpleBlocks The value zero for AVPacket.duration means that the duration is unknown, which in practice means "play this subtitle until overridden by the next subtitle". Yet for Matroska a BlockGroup with duration zero means that the subtitle really has a duration zero. "Display until overridden" is achieved by not setting a duration on the container level at all and this is achieved by using a SimpleBlock or a BlockGroup without duration. This commit implements this. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index c2848fdcd2..3649ac25a2 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -585,7 +585,7 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, put_ebml_uint(cuepoint, MATROSKA_ID_CUETRACK , tracks[idx].track_num); put_ebml_uint(cuepoint, MATROSKA_ID_CUECLUSTERPOSITION , entry->cluster_pos); put_ebml_uint(cuepoint, MATROSKA_ID_CUERELATIVEPOSITION, entry->relative_pos); - if (entry->duration != -1) + if (entry->duration > 0) put_ebml_uint(cuepoint, MATROSKA_ID_CUEDURATION , entry->duration); end_ebml_master(cuepoint, track_positions); } while (++entry < end && entry->pts == pts); @@ -2308,7 +2308,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; mkv_track *track = &mkv->tracks[pkt->stream_index]; int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY); - int duration = pkt->duration; + int64_t duration = pkt->duration; int ret; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; int64_t relative_packet_pos; @@ -2345,14 +2345,17 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) relative_packet_pos = avio_tell(pb); - if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) { + if (par->codec_type != AVMEDIA_TYPE_SUBTITLE || + (par->codec_id != AV_CODEC_ID_WEBVTT && duration <= 0)) { ret = mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); if (ret < 0) return ret; if (keyframe && IS_SEEKABLE(s->pb, mkv) && - (par->codec_type == AVMEDIA_TYPE_VIDEO || !mkv->have_video && !track->has_cue)) { + (par->codec_type == AVMEDIA_TYPE_VIDEO || + par->codec_type == AVMEDIA_TYPE_SUBTITLE || + !mkv->have_video && !track->has_cue)) { ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts, - mkv->cluster_pos, relative_packet_pos, -1); + mkv->cluster_pos, relative_packet_pos, 0); if (ret < 0) return ret; track->has_cue = 1; -- cgit v1.2.3