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 <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2021-04-09 01:00:51 +02:00
parent 85709a90c3
commit b972dab39d
1 changed files with 8 additions and 5 deletions

View File

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