From patchwork Thu Apr 23 03:07:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 19187 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 25A6A44BA43 for ; Thu, 23 Apr 2020 06:08:25 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 130DB68BE35; Thu, 23 Apr 2020 06:08:25 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6596E68BE07 for ; Thu, 23 Apr 2020 06:08:17 +0300 (EEST) Received: by mail-wr1-f66.google.com with SMTP id i10so5014668wrv.10 for ; Wed, 22 Apr 2020 20:08:17 -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=qT6PWn0C4ftmVNFnQ8F0fUsqJ8Nv+sMyzzP3xGGaaZI=; b=W96K4yEtlH6FhWXLNpb/053aqcNuUKbdl0mbogqVjpGdV+S5Ch26csYM5AgHcl/oHc NzXSAXhAWaOYvf5jPvuxhv7Lfv39rOu1ZznxOJ3lRL/E5BvCnIH2ayPlVBTRMQgi0XQa Tg+14o79C7/Z1rKvmuFP8jNMMwXNx87xFgAZr3gBGd4WSO82cgu3S7fZ6pJT6gBcCzd4 ix2adXbd2cf7q3NgzGgurhj8sdTgyzWMlt++dECZEwfyl7+Q6a8oHFtxlQzhOeSl2C+w 70r9flpx8axGNEmcW38PJaZIY2PQ2RQ78tsbYEk9AlapGLVYxNeBvxpAs8ICYW3Hrdpa I1Vw== 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=qT6PWn0C4ftmVNFnQ8F0fUsqJ8Nv+sMyzzP3xGGaaZI=; b=TWa7bnLhtNMk9S1/XXIfiyzJBBNdq/nw35SUaEBJTuSpVpJTPANzwPfj8EBiEqPCM2 y6TR3zQO+8geBcVz3UrG3sxgc7IPFCHbidABxrLPKbQrCh8wBtkM43WE90wsdOoX1aW7 8sRYibL/hzbHHpM+av3nwRXpnzrcw7iP+8XrcgQJXSbMALY41y4p3mcq0B8Mzk0pMnpa PsHe1Dt948wa6X3fqoXsGAXXUTPn8G886dCyDASEvZaparaTc+WxE7BmsmHu0k6cGqUY h2p2/TzG+HnJUafxpOUA06CzFKPdldiIznyl/mQtvtWrQy4ZgM94JV3LKW23RfXHrqkz +KJw== X-Gm-Message-State: AGi0PuY3mZDpGANWH2IXfKwqC8kAumS9Shcd26mS5mvn0pXdVvLhucsD NcecPsAbqX8e5mpMRog8ygLB7MDT X-Google-Smtp-Source: APiQypJ+1fitzxxvEGivR292DJk76cTNA2kWMfIPFVet0rPk54GigFAEeMw8ciLabt7dt9+1iPlOEQ== X-Received: by 2002:adf:fa03:: with SMTP id m3mr2359197wrr.68.1587611296455; Wed, 22 Apr 2020 20:08:16 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc1ab57.dynamic.kabel-deutschland.de. [188.193.171.87]) by smtp.gmail.com with ESMTPSA id m1sm1497733wro.64.2020.04.22.20.08.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Apr 2020 20:08:15 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 Apr 2020 05:07:40 +0200 Message-Id: <20200423030741.12158-10-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200423030741.12158-1-andreas.rheinhardt@gmail.com> References: <20200423030741.12158-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/11] avformat/matroskadec: Support ContentCompression for all codecs 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 demuxer has three functions for creating packets out of the data read: One for certain RealAudio codecs (ATRAC3, cook, sipr, RealAudio 28.8), one for WebVTT (actually, the WebM flavour of it) and one for all the others. Only the last function supported Matroska's ContentCompression (e.g. it reversed zlib compression or added the removed headers to the packets). But in Matroska, all tracks are allowed to be compressed. This commit adds support for this. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskadec.c | 79 ++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 9e3e98e9c0..c16e18cb22 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -3192,10 +3192,11 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, } /* reconstruct full wavpack blocks from mangled matroska ones */ -static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src, - uint8_t **pdst, int *size) +static int matroska_parse_wavpack(MatroskaTrack *track, + uint8_t **data, int *size) { uint8_t *dst = NULL; + uint8_t *src = *data; int dstlen = 0; int srclen = *size; uint32_t samples; @@ -3265,7 +3266,7 @@ static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src, memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE); - *pdst = dst; + *data = dst; *size = dstlen; return 0; @@ -3275,8 +3276,8 @@ fail: return ret; } -static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src, - uint8_t **pdst, int *size) +static int matroska_parse_prores(MatroskaTrack *track, + uint8_t **data, int *size) { uint8_t *dst; int dstlen = *size + 8; @@ -3287,10 +3288,10 @@ static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src, AV_WB32(dst, dstlen); AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f')); - memcpy(dst + 8, src, dstlen - 8); + memcpy(dst + 8, *data, dstlen - 8); memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE); - *pdst = dst; + *data = dst; *size = dstlen; return 0; @@ -3413,54 +3414,46 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, static int matroska_parse_frame(MatroskaDemuxContext *matroska, MatroskaTrack *track, AVStream *st, - AVBufferRef *buf, uint8_t *data, int pkt_size, + AVBufferRef *buf, uint8_t **data, int pkt_size, uint64_t timecode, uint64_t lace_duration, int64_t pos, int is_keyframe, uint8_t *additional, uint64_t additional_id, int additional_size, int64_t discard_padding) { - uint8_t *pkt_data = data; + uint8_t *pkt_data = *data; int res = 0; AVPacket pktl, *pkt = &pktl; - if (track->needs_decoding) { - res = matroska_decode_buffer(&pkt_data, &pkt_size, track); - if (res < 0) - return res; - } - if (st->codecpar->codec_id == AV_CODEC_ID_WAVPACK) { - uint8_t *wv_data; - res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size); + res = matroska_parse_wavpack(track, &pkt_data, &pkt_size); if (res < 0) { av_log(matroska->ctx, AV_LOG_ERROR, "Error parsing a wavpack block.\n"); goto fail; } - if (pkt_data != data) - av_freep(&pkt_data); - pkt_data = wv_data; + if (!buf) + av_freep(data); + buf = NULL; } if (st->codecpar->codec_id == AV_CODEC_ID_PRORES && AV_RB32(pkt_data + 4) != MKBETAG('i', 'c', 'p', 'f')) { - uint8_t *pr_data; - res = matroska_parse_prores(track, pkt_data, &pr_data, &pkt_size); + res = matroska_parse_prores(track, &pkt_data, &pkt_size); if (res < 0) { av_log(matroska->ctx, AV_LOG_ERROR, "Error parsing a prores block.\n"); goto fail; } - if (pkt_data != data) - av_freep(&pkt_data); - pkt_data = pr_data; + if (!buf) + av_freep(data); + buf = NULL; } if (!pkt_size && !additional_size) goto no_output; av_init_packet(pkt); - if (pkt_data != data) + if (!buf) pkt->buf = av_buffer_create(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE, NULL, NULL, 0); else @@ -3531,8 +3524,8 @@ FF_ENABLE_DEPRECATION_WARNINGS no_output: fail: - if (pkt_data != data) - av_freep(&pkt_data); + if (!buf) + av_freep(data); return res; } @@ -3634,25 +3627,41 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf for (n = 0; n < laces; n++) { int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces; + uint8_t *out_data = data; + int out_size = lace_size[n]; + + if (track->needs_decoding) { + res = matroska_decode_buffer(&out_data, &out_size, track); + if (res < 0) + return res; + /* Given that we are here means that out_data is no longer + * owned by buf, so set it to NULL. This depends upon + * zero-length header removal compression being ignored. */ + av_assert1(out_data != data); + buf = NULL; + } if (track->audio.buf) { - res = matroska_parse_rm_audio(matroska, track, st, data, - lace_size[n], + res = matroska_parse_rm_audio(matroska, track, st, + out_data, out_size, timecode, pos); + if (!buf) + av_free(out_data); if (res) return res; - } else if (st->codecpar->codec_id == AV_CODEC_ID_WEBVTT) { res = matroska_parse_webvtt(matroska, track, st, - data, lace_size[n], + out_data, out_size, timecode, lace_duration, pos); + if (!buf) + av_free(out_data); if (res) return res; } else { - res = matroska_parse_frame(matroska, track, st, buf, data, lace_size[n], - timecode, lace_duration, pos, - !n ? is_keyframe : 0, + res = matroska_parse_frame(matroska, track, st, buf, &out_data, + out_size, timecode, lace_duration, + pos, !n ? is_keyframe : 0, additional, additional_id, additional_size, discard_padding); if (res)