mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avformat/matroskaenc: Remove special code for writing subtitles
Once upon a time, mkv_write_block() only wrote a (Simple)Block, not a BlockGroup which is needed for subtitles to convey the duration. But with the introduction of support for writing BlockAdditions and DiscardPadding (both of which require a BlockGroup), mkv_write_block() can also open and close a BlockGroup of its own. This naturally led to some code duplication which is removed in this commit. This new code leads to one regression: It always uses eight bytes for the BlockGroup's length field, whereas the earlier code usually used the lowest amount of bytes needed. This will be fixed in a future commit. This temporary regression is also the reason for changes to the binsub-mksenc and matroska-zero-length-block fate tests. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
d328467dd3
commit
03d31ef39c
@ -2418,7 +2418,7 @@ static int mkv_reformat_av1(MatroskaMuxContext *mkv, AVIOContext *pb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
||||||
uint32_t blockid, const AVPacket *pkt, int keyframe)
|
const AVPacket *pkt, int keyframe, uint64_t duration)
|
||||||
{
|
{
|
||||||
MatroskaMuxContext *mkv = s->priv_data;
|
MatroskaMuxContext *mkv = s->priv_data;
|
||||||
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
|
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
|
||||||
@ -2428,10 +2428,10 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
int err = 0, offset = 0, size = pkt->size;
|
int err = 0, offset = 0, size = pkt->size;
|
||||||
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
|
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
|
||||||
uint64_t additional_id;
|
uint64_t additional_id;
|
||||||
|
uint32_t blockid = MATROSKA_ID_SIMPLEBLOCK;
|
||||||
int64_t discard_padding = 0;
|
int64_t discard_padding = 0;
|
||||||
unsigned track_number = track->track_num;
|
unsigned track_number = track->track_num;
|
||||||
ebml_master block_group, block_additions, block_more;
|
ebml_master block_group, block_additions, block_more;
|
||||||
int blockgroup_already_opened = blockid == MATROSKA_ID_BLOCK;
|
|
||||||
|
|
||||||
ts += track->ts_offset;
|
ts += track->ts_offset;
|
||||||
|
|
||||||
@ -2466,7 +2466,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
side_data = av_packet_get_side_data(pkt,
|
side_data = av_packet_get_side_data(pkt,
|
||||||
AV_PKT_DATA_SKIP_SAMPLES,
|
AV_PKT_DATA_SKIP_SAMPLES,
|
||||||
&side_data_size);
|
&side_data_size);
|
||||||
if (side_data && side_data_size >= 10 && !blockgroup_already_opened) {
|
if (side_data && side_data_size >= 10) {
|
||||||
discard_padding = av_rescale_q(AV_RL32(side_data + 4),
|
discard_padding = av_rescale_q(AV_RL32(side_data + 4),
|
||||||
(AVRational){1, par->sample_rate},
|
(AVRational){1, par->sample_rate},
|
||||||
(AVRational){1, 1000000000});
|
(AVRational){1, 1000000000});
|
||||||
@ -2477,8 +2477,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
&side_data_size);
|
&side_data_size);
|
||||||
if (side_data) {
|
if (side_data) {
|
||||||
// Only the Codec-specific BlockMore (id == 1) is currently supported.
|
// Only the Codec-specific BlockMore (id == 1) is currently supported.
|
||||||
if (side_data_size < 8 || (additional_id = AV_RB64(side_data)) != 1 ||
|
if (side_data_size < 8 || (additional_id = AV_RB64(side_data)) != 1) {
|
||||||
blockgroup_already_opened) {
|
|
||||||
side_data_size = 0;
|
side_data_size = 0;
|
||||||
} else {
|
} else {
|
||||||
side_data += 8;
|
side_data += 8;
|
||||||
@ -2486,7 +2485,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (side_data_size || discard_padding) {
|
if (side_data_size || discard_padding || duration) {
|
||||||
block_group = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, 0);
|
block_group = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, 0);
|
||||||
blockid = MATROSKA_ID_BLOCK;
|
blockid = MATROSKA_ID_BLOCK;
|
||||||
}
|
}
|
||||||
@ -2502,6 +2501,9 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
avio_write(pb, data + offset, size);
|
avio_write(pb, data + offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (duration)
|
||||||
|
put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
|
||||||
|
|
||||||
if (blockid == MATROSKA_ID_BLOCK && !keyframe)
|
if (blockid == MATROSKA_ID_BLOCK && !keyframe)
|
||||||
put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp - ts);
|
put_ebml_sint(pb, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp - ts);
|
||||||
track->last_timestamp = ts;
|
track->last_timestamp = ts;
|
||||||
@ -2520,7 +2522,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
end_ebml_master(pb, block_more);
|
end_ebml_master(pb, block_more);
|
||||||
end_ebml_master(pb, block_additions);
|
end_ebml_master(pb, block_additions);
|
||||||
}
|
}
|
||||||
if (side_data_size || discard_padding)
|
if (blockid == MATROSKA_ID_BLOCK)
|
||||||
end_ebml_master(pb, block_group);
|
end_ebml_master(pb, block_group);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2697,8 +2699,11 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt)
|
|||||||
AVIOContext *pb;
|
AVIOContext *pb;
|
||||||
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
|
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
|
||||||
mkv_track *track = &mkv->tracks[pkt->stream_index];
|
mkv_track *track = &mkv->tracks[pkt->stream_index];
|
||||||
int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
|
int is_sub = par->codec_type == AVMEDIA_TYPE_SUBTITLE;
|
||||||
int64_t duration = pkt->duration;
|
/* All subtitle blocks are considered to be keyframes. */
|
||||||
|
int keyframe = is_sub || !!(pkt->flags & AV_PKT_FLAG_KEY);
|
||||||
|
int64_t duration = FFMAX(pkt->duration, 0);
|
||||||
|
int64_t write_duration = is_sub ? duration : 0;
|
||||||
int ret;
|
int ret;
|
||||||
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
|
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
|
||||||
int64_t relative_packet_pos;
|
int64_t relative_packet_pos;
|
||||||
@ -2735,9 +2740,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt)
|
|||||||
|
|
||||||
relative_packet_pos = avio_tell(pb);
|
relative_packet_pos = avio_tell(pb);
|
||||||
|
|
||||||
if (par->codec_type != AVMEDIA_TYPE_SUBTITLE ||
|
if (par->codec_id != AV_CODEC_ID_WEBVTT) {
|
||||||
(par->codec_id != AV_CODEC_ID_WEBVTT && duration <= 0)) {
|
ret = mkv_write_block(s, pb, pkt, keyframe, write_duration);
|
||||||
ret = mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (keyframe && IS_SEEKABLE(s->pb, mkv) &&
|
if (keyframe && IS_SEEKABLE(s->pb, mkv) &&
|
||||||
@ -2745,26 +2749,16 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt)
|
|||||||
par->codec_type == AVMEDIA_TYPE_SUBTITLE ||
|
par->codec_type == AVMEDIA_TYPE_SUBTITLE ||
|
||||||
!mkv->have_video && !track->has_cue)) {
|
!mkv->have_video && !track->has_cue)) {
|
||||||
ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts,
|
ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts,
|
||||||
mkv->cluster_pos, relative_packet_pos, 0);
|
mkv->cluster_pos, relative_packet_pos,
|
||||||
|
write_duration);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
track->has_cue = 1;
|
track->has_cue = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (par->codec_id == AV_CODEC_ID_WEBVTT) {
|
|
||||||
ret = mkv_write_vtt_blocks(s, pb, pkt);
|
ret = mkv_write_vtt_blocks(s, pb, pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
|
||||||
ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
|
|
||||||
mkv_blockgroup_size(pkt->size,
|
|
||||||
track->track_num_size));
|
|
||||||
|
|
||||||
/* All subtitle blocks are considered to be keyframes. */
|
|
||||||
mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 1);
|
|
||||||
put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
|
|
||||||
end_ebml_master(pb, blockgroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_SEEKABLE(s->pb, mkv)) {
|
if (IS_SEEKABLE(s->pb, mkv)) {
|
||||||
ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts,
|
ret = mkv_add_cuepoint(mkv, pkt->stream_index, ts,
|
||||||
|
@ -1 +1 @@
|
|||||||
490b1b4beb4a614c06004609039ce779
|
9dd2ff92a3da9fb50405db3d05e41042
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
f37ba7e8a30eaa33c1fd0ef77447fb41 *tests/data/fate/matroska-zero-length-block.matroska
|
c09d3b89ed0795817d671deb041fca1b *tests/data/fate/matroska-zero-length-block.matroska
|
||||||
636 tests/data/fate/matroska-zero-length-block.matroska
|
650 tests/data/fate/matroska-zero-length-block.matroska
|
||||||
#tb 0: 1/1000
|
#tb 0: 1/1000
|
||||||
#media_type 0: subtitle
|
#media_type 0: subtitle
|
||||||
#codec_id 0: subrip
|
#codec_id 0: subrip
|
||||||
|
Loading…
Reference in New Issue
Block a user