On Sat Apr 4 09:29:20 EEST 2020, Andreas Rheinhardt <andreas.rheinha...@gmail.com> wrote: > Are you running into this limitation?
Yes. > If so, do the files that you > create with this patch that have more than 127 tracks work? They > shouldn't. The reason for this (and the reason that I didn't remove this > limit altogether in 65ef74f74900590f134b4a130e8f56e5272d1925) lies in > the way the TrackNumber is encoded in the (Simple)Blocks: They are > encoded as variable-length numbers, so that encoding small TrackNumbers > takes up less bytes than encoding bigger TrackNumbers. More precisely, > TrackNumbers in the range 1..127 are encodable on one byte. And the way > they are written in mkv_write_block() and mkv_write_vtt_blocks() relies > on this. If you simply remove said limit, the tracks with TrackNumbers > > 127 will not have any (Simple)Blocks associated with them; instead the > encoded TrackNumber will be the desired TrackNumber modulo 128 and the > (Simple)Block will appear to belong to the track with the encoded > TrackNumber (if one exists).** The results will of course be catastrophic. I skimmed through libmatroska's code in src/KaxBlock.cpp and their limit is 0x4000-1, which is way more reasonable. > Notice that I have sent a patchset that slightly increases the number of > allowed tracks (without fixing the root cause though, because I didn't > know if there are really people who run into this): [1] makes > attachments no longer count towards the limit; [2] increases the limit > to 127. I will resend said patchset soon. > > - Andreas > > [1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2019-November/253452.html > [2]: https://ffmpeg.org/pipermail/ffmpeg-devel/2019-November/252563.html > > *: The reason for setting MAX_TRACKS to 126 instead of 127 is probably > that the encoding corresponding to the number 127 is special when > encoding lengths (which use the same variable-length number scheme): > Here it denotes an unknown length instead of a length of 127. But there > are no such values with a special meaning for encoded TrackNumbers. Indeed, libmatroska allows 0x80-1 (127) per byte. Your second patch should have been merged. > **: Notice that a TrackNumber of 0 is invalid, so any (Simple)Block that > ought to belong to the tracks with TrackNumber 128, 256, 384, ... will > have no matching track at all. FFmpeg's Matroska demuxer treats > encountering such (Simple)Blocks as a sign of invalid data and it will > try to resync to the next level 1 element (typically the next Cluster). > Similar things can happen if you use attachments (in this case there may > be gaps in the used TrackNumbers). I have included a new patch, which writes the track_number using put_ebml_num(), which should work perhaps?
From 477d1ee08115e09f2f61f75dd70ce7bc882d2c34 Mon Sep 17 00:00:00 2001 From: Jan Chren (rindeal) <dev.rind...@gmail.com> Date: Sat, 4 Apr 2020 00:00:00 +0000 Subject: [PATCH] avformat/matroskaenc: remove track limit Strictly speaking, ebml_num_size() wastes one bit here. Employing new ebml_num_size() and put_ebml_num() just for track_number would solve this. --- libavformat/matroskaenc.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 5dae53026d..30132a53e8 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -117,10 +117,6 @@ typedef struct mkv_attachments { #define MODE_MATROSKAv2 0x01 #define MODE_WEBM 0x02 -/** Maximum number of tracks allowed in a Matroska file (with track numbers in - * range 1 to 126 (inclusive) */ -#define MAX_TRACKS 126 - typedef struct MatroskaMuxContext { const AVClass *class; int mode; @@ -2089,9 +2085,8 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb, } put_ebml_id(pb, blockid); - put_ebml_num(pb, size + 4, 0); - // this assumes stream_index is less than 126 - avio_w8(pb, 0x80 | track_number); + put_ebml_num(pb, size + ebml_num_size(track_number) + 2 + 1, 0); + put_ebml_num(track_number, 0); avio_wb16(pb, ts - mkv->cluster_pts); avio_w8(pb, (blockid == MATROSKA_ID_SIMPLEBLOCK && keyframe) ? (1 << 7) : 0); avio_write(pb, data + offset, size); @@ -2155,8 +2150,8 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size)); put_ebml_id(pb, MATROSKA_ID_BLOCK); - put_ebml_num(pb, size + 4, 0); - avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 + put_ebml_num(pb, size + ebml_num_size(pkt->stream_index + 1) + 2 + 1, 0); + put_ebml_num(pkt->stream_index + 1, 0); avio_wb16(pb, ts - mkv->cluster_pts); avio_w8(pb, flags); avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, pkt->size, pkt->data); @@ -2604,13 +2599,6 @@ static int mkv_init(struct AVFormatContext *s) { int i; - if (s->nb_streams > MAX_TRACKS) { - av_log(s, AV_LOG_ERROR, - "At most %d streams are supported for muxing in Matroska\n", - MAX_TRACKS); - return AVERROR(EINVAL); - } - for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_ATRAC3 || s->streams[i]->codecpar->codec_id == AV_CODEC_ID_COOK || -- 2.26.0
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".