From patchwork Tue Mar 16 08:29:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26409 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 6242F44B21B for ; Tue, 16 Mar 2021 10:30:09 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3DA9A68AF1C; Tue, 16 Mar 2021 10:30:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B955268AEA7 for ; Tue, 16 Mar 2021 10:30:02 +0200 (EET) Received: by mail-ej1-f47.google.com with SMTP id p8so70654799ejb.10 for ; Tue, 16 Mar 2021 01:30:02 -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:reply-to:mime-version :content-transfer-encoding; bh=Y8qAb2FqSGwjN5d3Ry1dt+PBcRjbMYf6dC9vLFP2jf0=; b=CUJu7XNxDNCfymt2GfhJSzF21E+a5nLIV3d7khytahlFrCOcS5/GO+wtPDhbbtqpxZ WRvSxILppyQwwnlBt9OKpZI6QzTlUoEydD1u1SnuZFaMERZwThVNDAgXW42b9HjVF2VQ 4Ns3sP9nOoMCk9VsxnKN7jRw8ynZFpDDn8/HVEtolgbmvH/favhWSeyiObXAPXBcoLOU Rm3qD6tfht9i++MB3Papqf0oreTVNu/hgYlECp2J4t4/5A0zZuHn4DnXTHdjiX51PA++ izN9FIy9vmgChWDp8VwfpmIgSr9lTbEw/YA/IjhYYWoeW9RoNe9vUzwZ+NpRRONHxEl2 oZBA== 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:reply-to :mime-version:content-transfer-encoding; bh=Y8qAb2FqSGwjN5d3Ry1dt+PBcRjbMYf6dC9vLFP2jf0=; b=KtQEJfQp83EV7ylh2yIbS9cC2u9VAydmpWh4AG7eIHCRlKHRfuwy0M/yzQ3f7EZAOf AEn4SYvNIY3JLxvmGRNPIpt72d65SEu3vKF/A58I8vWsKXxIeD9ESr45DuKEvOv4pGgJ h8PEDXXQBYkBlHI3M6rB2Ifb7HiN3GxWTRAtluz7oKa2ZEAzmXSTaAfgeVlmxmzQiGCj ZZ02UI/CUJLOEEr1l/1FVk6LW6B5pAcqxv0qOqnXoAcDCvCUmQCvLHcyQDiHMxSI9seN QpfNuF41uN18DxHUgoNZ4sHiGS+J3PHytF7SaEwNW+juRRKQhkYg2fzMb123A43YSKg+ dJkA== X-Gm-Message-State: AOAM532L0nnIjwkgq86ld1TFQ50FxAeWsKfXIvgEMdzJep37CiMzV+T2 QONTq7wNqxEqfKJG5mYQIu1OqvNI2S1glw== X-Google-Smtp-Source: ABdhPJw33tDsUkzBvnF/65UlECPuC8aFFWby7JZPv1cW8npNpjyS8VazpOw+Wmq+tUYYRYh4st9SWA== X-Received: by 2002:a17:906:b20b:: with SMTP id p11mr28804972ejz.0.1615883401956; Tue, 16 Mar 2021 01:30:01 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc08960.dynamic.kabel-deutschland.de. [188.192.137.96]) by smtp.gmail.com with ESMTPSA id y9sm8882757ejd.110.2021.03.16.01.30.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Mar 2021 01:30:01 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 16 Mar 2021 09:29:52 +0100 Message-Id: <20210316082953.273550-1-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] avformat/matroskaenc: Check chapter ids for duplicates 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" Up until now, there has been no check that each chapter has a unique id; there was only a check for whether a chapter id is zero (this happens often when the chapters originated from a format that lacks the concept of chapter id and simply counts from zero) which is invalid in Matroska. In this case the chapter ids are offset by 1 to make them nonnegative. Yet offsetting won't fix duplicate ids, therefore this is changed to simply create new chapter uids when the input chapter uids don't conform to the requirements of Matroska (in which case it can be presumed that they did not originate from Matroska, so that we don't need to bother to preserve them). Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1749b7fd37..8f29d64e72 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1625,24 +1625,29 @@ static int mkv_write_tags(AVFormatContext *s) return 0; } +static int mkv_new_chapter_ids_needed(const AVFormatContext *s) +{ + for (unsigned i = 0; i < s->nb_chapters; i++) { + if (!s->chapters[i]->id) + return 1; + for (unsigned j = 0; j < i; j++) + if (s->chapters[j]->id == s->chapters[i]->id) + return 1; + } + return 0; +} + static int mkv_write_chapters(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; AVIOContext *dyn_cp = NULL, *dyn_tags = NULL, **tags, *pb = s->pb; ebml_master editionentry; - uint64_t chapter_id_offset = 0; AVRational scale = {1, 1E9}; - int i, ret; + int ret, create_new_ids; if (!s->nb_chapters || mkv->wrote_chapters) return 0; - for (i = 0; i < s->nb_chapters; i++) - if (!s->chapters[i]->id) { - chapter_id_offset = 1; - break; - } - ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; @@ -1656,12 +1661,15 @@ static int mkv_write_chapters(AVFormatContext *s) } else tags = NULL; - for (i = 0; i < s->nb_chapters; i++) { + create_new_ids = mkv_new_chapter_ids_needed(s); + + for (unsigned i = 0; i < s->nb_chapters; i++) { ebml_master chapteratom, chapterdisplay; const AVChapter *c = s->chapters[i]; int64_t chapterstart = av_rescale_q(c->start, c->time_base, scale); int64_t chapterend = av_rescale_q(c->end, c->time_base, scale); const AVDictionaryEntry *t; + uint64_t uid = create_new_ids ? i + 1ULL : (uint32_t)c->id; if (chapterstart < 0 || chapterstart > chapterend || chapterend < 0) { av_log(s, AV_LOG_ERROR, "Invalid chapter start (%"PRId64") or end (%"PRId64").\n", @@ -1671,8 +1679,7 @@ static int mkv_write_chapters(AVFormatContext *s) } chapteratom = start_ebml_master(dyn_cp, MATROSKA_ID_CHAPTERATOM, 0); - put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERUID, - (uint32_t)c->id + chapter_id_offset); + put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERUID, uid); put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMESTART, chapterstart); put_ebml_uint(dyn_cp, MATROSKA_ID_CHAPTERTIMEEND, chapterend); if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { @@ -1685,8 +1692,7 @@ static int mkv_write_chapters(AVFormatContext *s) if (tags && mkv_check_tag(c->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) { ret = mkv_write_tag(mkv, c->metadata, tags, NULL, - MATROSKA_ID_TAGTARGETS_CHAPTERUID, - (uint32_t)c->id + chapter_id_offset); + MATROSKA_ID_TAGTARGETS_CHAPTERUID, uid); if (ret < 0) goto fail; } From patchwork Tue Mar 16 08:29:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26411 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 78D3A44B21B for ; Tue, 16 Mar 2021 10:30:37 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 695F968AFA4; Tue, 16 Mar 2021 10:30:37 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9B4C768AF85 for ; Tue, 16 Mar 2021 10:30:30 +0200 (EET) Received: by mail-ed1-f48.google.com with SMTP id bx7so20430483edb.12 for ; Tue, 16 Mar 2021 01:30:30 -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:reply-to :mime-version:content-transfer-encoding; bh=grsd8UG+jAEJF/fVHah19uBjLLAX9EeeghBq5rgtDrY=; b=Vd7py6i5nLJCq6V4pb+Mx5SDnkGXRkKRRweSKLpsJfLqIP3Ao3xaDFp54AclIy20Q2 YSS0NCKwa0Gca46YbMcE8QQUq6g3pCZT07af8qYBbUMJDkCJNTJAcZeh96GV4ByVpEi5 eO6ofQgZklMKP6wYXdvdLfo8vk6Fim/eYwcNb0HL8Erbs9Qjn6Qia8JtNGUVSi9T1R4a Oj5q30bYw+sR4WwhNcfs6PEjMylmh5+5W8+RZRM46WUcG0e2NLC/ZkJ3yoW07NrYKnVB IvbLPdL8SQAX3dhoEsGmr5UVBXSiOLAzZ2NECu0dcjrOwcuZCi9UMLKEHkLOoQdUtsTt eftw== 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:reply-to:mime-version:content-transfer-encoding; bh=grsd8UG+jAEJF/fVHah19uBjLLAX9EeeghBq5rgtDrY=; b=HiUboIlrPwlSRBxmppwkQbQCKkFczPg5k44HI7SgiNxHDpNcIFEzAW10JdBDNpwEaO rQ8cjDqAiKelsC8l7PWJ2SnzH7dAEp6mEUOGI3KMbJH8mEU5VoAYcVtYsvu5Ltlor8Xh nSbM11nyhroFDckqhYtlYiM3GIvM2wXH8mbBDXGHXnPNUkgN0Y5iHeRsNKaYPAvs6u1X homgB820NbffI3nMjwzqlAQBu+aWCqQdAhuzjpJaPs4zIe+7ATscq9GGMnUZ5ujZ5QR8 xkl7yMXnMKoqrZ8e7qmsFhiVt8N2zLcbLCmaxRlRt+2UmZ3d/4xz0Ix700e6Ebunc83Y e02w== X-Gm-Message-State: AOAM533jpItIn9b2WUwYs8oHHANtugfDDCyOOHFWAJJeAXBWnbANo//r EGFqwblb/tvAdURwgxEsdYMmn/+196iYfg== X-Google-Smtp-Source: ABdhPJweRliMRdveun4hskn8pde1jFqMowV80wygedvKTi2XtyZ73Q6E3uXIwtuAoDTzg7NXXCuGtA== X-Received: by 2002:aa7:da04:: with SMTP id r4mr34758474eds.343.1615883429808; Tue, 16 Mar 2021 01:30:29 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc08960.dynamic.kabel-deutschland.de. [188.192.137.96]) by smtp.gmail.com with ESMTPSA id y9sm8882757ejd.110.2021.03.16.01.30.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Mar 2021 01:30:29 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 16 Mar 2021 09:29:53 +0100 Message-Id: <20210316082953.273550-2-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210316082953.273550-1-andreas.rheinhardt@gmail.com> References: <20210316082953.273550-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avformat: Make AVChapter.id an int64_t on next major bump 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" 64 bits are needed in order to retain the uid values of Matroska chapters; the type is kept signed because the semantics of NUT chapters depend upon whether the id is > 0 or < 0. Signed-off-by: Andreas Rheinhardt --- Apologies for being so late. doc/APIchanges | 4 ++++ libavformat/aadec.c | 2 +- libavformat/avformat.h | 4 ++++ libavformat/internal.h | 4 ++++ libavformat/matroskaenc.c | 4 ++++ libavformat/nutdec.c | 4 ++-- libavformat/utils.c | 4 ++++ libavformat/version.h | 5 ++++- 8 files changed, 27 insertions(+), 4 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index c0d955b1fa..8b93adebe1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2017-10-21 API changes, most recent first: +2021-03-16 - xxxxxxxxxx - lavf 58.75.100 - avformat.h + AVChapter.id will be changed from int to int64_t + on the next major version bump. + 2021-03-12 - xxxxxxxxxx - lavc 58.131.100 - avcodec.h codec.h Add a get_encode_buffer callback to AVCodecContext, similar to get_buffer2 but for encoders. diff --git a/libavformat/aadec.c b/libavformat/aadec.c index e88cdb89df..80ca2c12d7 100644 --- a/libavformat/aadec.c +++ b/libavformat/aadec.c @@ -222,7 +222,7 @@ static int aa_read_header(AVFormatContext *s) c->content_end = start + largest_size; while ((chapter_pos = avio_tell(pb)) >= 0 && chapter_pos < c->content_end) { - int chapter_idx = s->nb_chapters; + unsigned chapter_idx = s->nb_chapters; uint32_t chapter_size = avio_rb32(pb); if (chapter_size == 0 || avio_feof(pb)) break; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index e3bd01ec7f..765bc3b6f5 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1184,7 +1184,11 @@ typedef struct AVProgram { change dynamically at runtime. */ typedef struct AVChapter { +#if FF_API_CHAPTER_ID_INT int id; ///< unique ID to identify the chapter +#else + int64_t id; ///< unique ID to identify the chapter +#endif AVRational time_base; ///< time base in which the start/end timestamps are specified int64_t start, end; ///< chapter start/end time in time_base units AVDictionary *metadata; diff --git a/libavformat/internal.h b/libavformat/internal.h index 0ffdc87b6a..df4918e318 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -554,7 +554,11 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance); * * @return AVChapter or NULL on error */ +#if FF_API_CHAPTER_ID_INT AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, +#else +AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, +#endif int64_t start, int64_t end, const char *title); /** diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 8f29d64e72..02e171593e 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1669,7 +1669,11 @@ static int mkv_write_chapters(AVFormatContext *s) int64_t chapterstart = av_rescale_q(c->start, c->time_base, scale); int64_t chapterend = av_rescale_q(c->end, c->time_base, scale); const AVDictionaryEntry *t; +#if FF_API_CHAPTER_ID_INT uint64_t uid = create_new_ids ? i + 1ULL : (uint32_t)c->id; +#else + uint64_t uid = create_new_ids ? i + 1ULL : c->id; +#endif if (chapterstart < 0 || chapterstart > chapterend || chapterend < 0) { av_log(s, AV_LOG_ERROR, "Invalid chapter start (%"PRId64") or end (%"PRId64").\n", diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index ebb062377d..d1f3496990 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -489,8 +489,8 @@ static int decode_info_header(NUTContext *nut) AVIOContext *bc = s->pb; uint64_t tmp, chapter_start, chapter_len; unsigned int stream_id_plus1, count; - int chapter_id, i, ret = 0; - int64_t value, end; + int i, ret = 0; + int64_t chapter_id, value, end; char name[256], str_value[1024], type_str[256]; const char *type; int *event_flags = NULL; diff --git a/libavformat/utils.c b/libavformat/utils.c index 8573117694..8fb5dbbf9d 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -4611,7 +4611,11 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) return program; } +#if FF_API_CHAPTER_ID_INT AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, +#else +AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, +#endif int64_t start, int64_t end, const char *title) { AVChapter *chapter = NULL; diff --git a/libavformat/version.h b/libavformat/version.h index e43754b069..ca1cd1a920 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 74 +#define LIBAVFORMAT_VERSION_MINOR 75 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -109,6 +109,9 @@ #ifndef FF_API_DEMUXER_OPEN #define FF_API_DEMUXER_OPEN (LIBAVFORMAT_VERSION_MAJOR < 59) #endif +#ifndef FF_API_CHAPTER_ID_INT +#define FF_API_CHAPTER_ID_INT (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif #ifndef FF_API_LAVF_PRIV_OPT #define FF_API_LAVF_PRIV_OPT (LIBAVFORMAT_VERSION_MAJOR < 60) #endif