From patchwork Thu Apr 16 23:54:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 19016 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A563B448684 for ; Fri, 17 Apr 2020 02:54:57 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 911D068BCFF; Fri, 17 Apr 2020 02:54:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C9ACA68BCEA for ; Fri, 17 Apr 2020 02:54:49 +0300 (EEST) Received: by mail-wm1-f67.google.com with SMTP id x4so977393wmj.1 for ; Thu, 16 Apr 2020 16:54:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7iBYA/F2iUVHXLVj5V75jek6mP1QST5h80855jnMQTk=; b=hbrw/P7s/gPopEQTMX+qiMXNx2U7xyJgQUjmQ+aRG76mFUOB2hAkc51QimW7xJd6yO hIPwfofuBEXJIf17ZhJrB5eBxaDzpjjY5qiITDa0RlgYxoPid1dIag0fNZk+iKLLfOus KJ4loErEOOQ1hT+mFMv7QcBxg+JPa359qqe3ivaVnkddBOBVoCKdx6OkgzaIBCwWxcL8 qCa6ZpQdtDgWw6hADEWakbie/Jnmy9Ay9YKP7yZemAHwLR2QSglF+ITcKYkP+UdzaMbr lm3J1SpE7Kpustc2r6ajjv5Ps+4pDaCxYboteFBAl3RE1fyaH7Zup0GKMNHLwr8t/wSB xiVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7iBYA/F2iUVHXLVj5V75jek6mP1QST5h80855jnMQTk=; b=T2nCYuJln7nldRPs9BLLFntlYYJbvmr4lli/cvsthDyN9PCdafiDIZrpuRuwOimJqE 5FAP+17O+s3HfFYzrCyQ6xr5fRucIRfdUvCdqEsTbwwj09tHmHMKwyFDSvsTHPfRZmU6 Vb73Ci632HJp06bbH7mEpsfJh1x8vczbWV8BQBLaU5wOekvVd2pOEyKJgOK+EoU71znc Fydiwo/BQiv35Eo52dSoZB45dTJfyl01nZ9qm4ny8DskuNpkxOYY+f2Th652KWNtUpIu PD28vX+uA+Nc8SWWBlcDVtlTcmH5F8rOFngHNx0Ga7eymVrjksgjOuDfa741B8BaGBC+ K74g== X-Gm-Message-State: AGi0PubQFH/wHsXxMgRuMpTPF4l0i9QwD2OFoYF9tPCDbNoZbYYCmpBx bhmBzMUUtpa9lB8BkoLTvGdmSUeD X-Google-Smtp-Source: APiQypI1737lfSThty5Jaw2mBcdZqffLhN0KqRm0NYSTa0EAcf7yfSQ4YmkWSz4btr+QLIvwl1LHVA== X-Received: by 2002:a7b:cc88:: with SMTP id p8mr378363wma.108.1587081288739; Thu, 16 Apr 2020 16:54:48 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc1ab57.dynamic.kabel-deutschland.de. [188.193.171.87]) by smtp.gmail.com with ESMTPSA id i17sm5603488wml.23.2020.04.16.16.54.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2020 16:54:48 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Fri, 17 Apr 2020 01:54:35 +0200 Message-Id: <20200416235435.20409-3-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200415210614.29152-1-andreas.rheinhardt@gmail.com> References: <20200415210614.29152-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/5] avformat/matroskaenc: Remove limit on the number of tracks X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The Matroska file format has practically no limit on the number of tracks (the current limit is 2^56 - 1); yet because they are encoded in a variable length format in (Simple)Blocks this muxer has simply imposed a limit on the number of tracks in order to ensure that they can always be written on one byte in order to simplify the muxing process. This commit removes said limit. Also, zero is an invalid TrackNumber, so disallow this value in the dash_track_number option. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 92cd819312..fcca4c2e87 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -93,6 +93,7 @@ typedef struct mkv_track { int has_cue; uint64_t uid; unsigned track_num; + int track_num_size; int sample_rate; int64_t sample_rate_offset; int64_t last_timestamp; @@ -105,10 +106,6 @@ typedef struct mkv_track { #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; @@ -1905,9 +1902,9 @@ static int mkv_write_header(AVFormatContext *s) return 0; } -static int mkv_blockgroup_size(int pkt_size) +static int mkv_blockgroup_size(int pkt_size, int track_num_size) { - int size = pkt_size + 4; + int size = pkt_size + track_num_size + 3; size += ebml_length_size(size); size += 2; // EBML ID for block and block duration size += 9; // max size of block duration incl. length field @@ -2047,9 +2044,8 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb, } put_ebml_id(pb, blockid); - put_ebml_length(pb, size + 4, 0); - // this assumes stream_index is less than 126 - avio_w8(pb, 0x80 | track_number); + put_ebml_length(pb, size + track->track_num_size + 3, 0); + put_ebml_num(pb, track_number, track->track_num_size); avio_wb16(pb, ts - mkv->cluster_pts); avio_w8(pb, (blockid == MATROSKA_ID_SIMPLEBLOCK && keyframe) ? (1 << 7) : 0); avio_write(pb, data + offset, size); @@ -2112,11 +2108,12 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p size, pkt->pts, pkt->dts, pkt->duration, avio_tell(pb), mkv->cluster_pos, track->track_num, 1); - blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size)); + blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, + mkv_blockgroup_size(size, track->track_num_size)); put_ebml_id(pb, MATROSKA_ID_BLOCK); - put_ebml_length(pb, size + 4, 0); - avio_w8(pb, 0x80 | track->track_num); // this assumes track_num is less than 126 + put_ebml_length(pb, size + track->track_num_size + 3, 0); + put_ebml_num(pb, track->track_num, track->track_num_size); 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); @@ -2290,7 +2287,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ duration = mkv_write_vtt_blocks(s, pb, pkt); } else { ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, - mkv_blockgroup_size(pkt->size)); + mkv_blockgroup_size(pkt->size, + track->track_num_size)); #if FF_API_CONVERGENCE_DURATION FF_DISABLE_DEPRECATION_WARNINGS @@ -2652,13 +2650,7 @@ static int mkv_init(struct AVFormatContext *s) nb_tracks++; track->track_num = mkv->is_dash ? mkv->dash_track_number : nb_tracks; - } - - if (nb_tracks > MAX_TRACKS) { - av_log(s, AV_LOG_ERROR, - "%u > "AV_STRINGIFY(MAX_TRACKS)" tracks (excluding attachments)" - " not supported for muxing in Matroska\n", nb_tracks); - return AVERROR(EINVAL); + track->track_num_size = ebml_num_size(track->track_num); } return 0; @@ -2716,7 +2708,7 @@ static const AVOption options[] = { { "cluster_size_limit", "Store at most the provided amount of bytes in a cluster. ", OFFSET(cluster_size_limit), AV_OPT_TYPE_INT , { .i64 = -1 }, -1, INT_MAX, FLAGS }, { "cluster_time_limit", "Store at most the provided number of milliseconds in a cluster.", OFFSET(cluster_time_limit), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS }, { "dash", "Create a WebM file conforming to WebM DASH specification", OFFSET(is_dash), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, - { "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 127, FLAGS }, + { "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, FLAGS }, { "live", "Write files assuming it is a live stream.", OFFSET(is_live), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "allow_raw_vfw", "allow RAW VFW mode", OFFSET(allow_raw_vfw), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "write_crc32", "write a CRC32 element inside every Level 1 element", OFFSET(write_crc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },