From patchwork Wed Nov 28 00:24:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 11188 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 C3F2144C240 for ; Wed, 28 Nov 2018 02:31:38 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4DBC568A64E; Wed, 28 Nov 2018 02:31:39 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 092396891D8 for ; Wed, 28 Nov 2018 02:31:33 +0200 (EET) Received: by mail-wm1-f66.google.com with SMTP id 125so820760wmh.0 for ; Tue, 27 Nov 2018 16:31:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cUbANoYCRVrw5H/GD0kZk/lEdYlB2BMsZOjUPV/w6Gc=; b=sIDMqxUUCYKjIea8SO6dxvZXVq4Jx3PpN6axVZuFJy0BF26+lewbfRp+wLWIW8gonC 0I3xozbEzhkNvfBeGlvQqlwW1Rf6ty/X50LuYBDmdSyUQSXXdUGEzb37Q86fW21iboPl qPCNFzdoap3IALsKhIvhVEE9pFKCF8hWfYNr1wU3lFQiLDzZFNvPnC3nEtx1z/BckVg5 saKLmLt76JhlLiNkjLwWe9vq4dtcdLujGX1ifrlRFGDNE+k/nUNr+ruou8Ic5AobjAzH ogpliasyrFDBu1W889jwtkk/y35jAc4J4ctaJ87FqxdDYUu/GLWpKxK8btSTpT89QTa8 zAJg== 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=cUbANoYCRVrw5H/GD0kZk/lEdYlB2BMsZOjUPV/w6Gc=; b=pJznfbSQaEV1f1gszt1+kZ9zF+OpwEn/EnhqToBrGqHRMmx22+ZOwE5xAplSiAG50+ 9CA7RZdDr/3RSFSVCp8OD4Pj6q534Orz3GaZ/yfXOzrncU3+Q0OkCkfZ6wwfxEr+uTVq aqpm5wW2uU9BHDqjOG/2QKZTFvEbCV7/NM+laERxj6WQ16anb8k9YdA25/tqt3oLcz+J a1M/+mpvM7OBgM5ZOMYupcNiRFSWr5sjtIfZCp2tu/ZSP4jxBivYmKtpcWEkpi7Q+0QT nQOz872sMl21ZV/xydPJPoBD24YBH+eCeeKA93xlMuwvdZy6YVBxY3hrHNWEd0u5jElu Z3BQ== X-Gm-Message-State: AA+aEWYagENC/hIa634U8H6xkjoFUUOcwdSMZGeUV4HZqiOjcU4Od9sy NBKS/Gz2reD7xDjlPqV29yOUkq5f X-Google-Smtp-Source: AFSGD/VpKOrWIfHGivw698PkFKhTr66sH+u5Cd4s5+L9oT4Pdtr34006JmtdmMlWgWBhRDn56bobbQ== X-Received: by 2002:a1c:da0c:: with SMTP id r12mr773487wmg.54.1543364699832; Tue, 27 Nov 2018 16:24:59 -0800 (PST) Received: from localhost.localdomain (ipbcc08c44.dynamic.kabel-deutschland.de. [188.192.140.68]) by smtp.googlemail.com with ESMTPSA id e8-v6sm1655323wmf.22.2018.11.27.16.24.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Nov 2018 16:24:59 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Nov 2018 01:24:09 +0100 Message-Id: <20181128002410.2244-2-andreas.rheinhardt@googlemail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <4d7d94d1-2137-4fd9-3204-4af5aea9f27e@jkqxz.net> References: <4d7d94d1-2137-4fd9-3204-4af5aea9f27e@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] h2645_parse: Make ff_h2645_packet_split reference-compatible 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" This is in preparation for a patch for cbs_h2645. Now the packet's rbsp_buffer can be owned by an AVBuffer. Signed-off-by: Andreas Rheinhardt --- libavcodec/cbs_h2645.c | 8 ++--- libavcodec/extract_extradata_bsf.c | 2 +- libavcodec/h2645_parse.c | 53 ++++++++++++++++++++++++++++-- libavcodec/h2645_parse.h | 9 ++++- libavcodec/h264_parse.c | 2 +- libavcodec/h264dec.c | 4 +-- libavcodec/hevc_parse.c | 3 +- libavcodec/hevc_parser.c | 2 +- libavcodec/hevcdec.c | 2 +- 9 files changed, 70 insertions(+), 15 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 666970ed03..574a53a60a 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -612,7 +612,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, err = ff_h2645_packet_split(&priv->read_packet, frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1); + ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, 0); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC SPS array.\n"); return err; @@ -636,7 +636,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, err = ff_h2645_packet_split(&priv->read_packet, frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1); + ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, 0); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC PPS array.\n"); return err; @@ -690,7 +690,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, err = ff_h2645_packet_split(&priv->read_packet, frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 1); + ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 1, 0); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split " "HVCC array %d (%d NAL units of type %d).\n", @@ -709,7 +709,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, frag->data, frag->data_size, ctx->log_ctx, priv->mp4, priv->nal_length_size, - codec_id, 1); + codec_id, 1, 0); if (err < 0) return err; diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index f37427c7e1..17e5deb96b 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -157,7 +157,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, } ret = ff_h2645_packet_split(&s->h2645_pkt, pkt->data, pkt->size, - ctx, 0, 0, ctx->par_in->codec_id, 1); + ctx, 0, 0, ctx->par_in->codec_id, 1, 0); if (ret < 0) return ret; diff --git a/libavcodec/h2645_parse.c b/libavcodec/h2645_parse.c index aaa4b8f443..942f2c5d71 100644 --- a/libavcodec/h2645_parse.c +++ b/libavcodec/h2645_parse.c @@ -343,9 +343,51 @@ static int find_next_start_code(const uint8_t *buf, const uint8_t *next_avc) return i + 3; } +static void alloc_rbsp_buffer(H2645RBSP *rbsp, unsigned int size, int use_ref) +{ + if (size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + goto fail; + size += AV_INPUT_BUFFER_PADDING_SIZE; + + if (rbsp->rbsp_buffer_alloc_size >= size && + (!rbsp->rbsp_buffer_ref || av_buffer_is_writable(rbsp->rbsp_buffer_ref))) + return; + + size = FFMIN(size + size / 16 + 32, INT_MAX); + + if (rbsp->rbsp_buffer_ref) + av_buffer_unref(&rbsp->rbsp_buffer_ref); + else + av_free(rbsp->rbsp_buffer); + + rbsp->rbsp_buffer = av_malloc(size); + if (!rbsp->rbsp_buffer) + goto fail; + rbsp->rbsp_buffer_alloc_size = size; + + if (use_ref) { + rbsp->rbsp_buffer_ref = av_buffer_create(rbsp->rbsp_buffer, size, + NULL, NULL, 0); + if (!rbsp->rbsp_buffer_ref) + goto fail; + } + + return; + +fail: + rbsp->rbsp_buffer_alloc_size = 0; + if (rbsp->rbsp_buffer_ref) { + av_buffer_unref(&rbsp->rbsp_buffer_ref); + rbsp->rbsp_buffer = NULL; + } else + av_freep(&rbsp->rbsp_buffer); + + return; +} + int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int is_nalff, int nal_length_size, - enum AVCodecID codec_id, int small_padding) + enum AVCodecID codec_id, int small_padding, int use_ref) { GetByteContext bc; int consumed, ret = 0; @@ -353,7 +395,8 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, int64_t padding = small_padding ? 0 : MAX_MBPAIR_SIZE; bytestream2_init(&bc, buf, length); - av_fast_padded_malloc(&pkt->rbsp.rbsp_buffer, &pkt->rbsp.rbsp_buffer_alloc_size, length + padding); + alloc_rbsp_buffer(&pkt->rbsp, length + padding, use_ref); + if (!pkt->rbsp.rbsp_buffer) return AVERROR(ENOMEM); @@ -474,6 +517,10 @@ void ff_h2645_packet_uninit(H2645Packet *pkt) } av_freep(&pkt->nals); pkt->nals_allocated = 0; - av_freep(&pkt->rbsp.rbsp_buffer); + if (pkt->rbsp.rbsp_buffer_ref) { + av_buffer_unref(&pkt->rbsp.rbsp_buffer_ref); + pkt->rbsp.rbsp_buffer = NULL; + } else + av_freep(&pkt->rbsp.rbsp_buffer); pkt->rbsp.rbsp_buffer_alloc_size = pkt->rbsp.rbsp_buffer_size = 0; } diff --git a/libavcodec/h2645_parse.h b/libavcodec/h2645_parse.h index 6dbba8fe4a..2c29ca517c 100644 --- a/libavcodec/h2645_parse.h +++ b/libavcodec/h2645_parse.h @@ -23,6 +23,7 @@ #include +#include "libavutil/buffer.h" #include "avcodec.h" #include "get_bits.h" @@ -66,6 +67,7 @@ typedef struct H2645NAL { typedef struct H2645RBSP { uint8_t *rbsp_buffer; + AVBufferRef *rbsp_buffer_ref; int rbsp_buffer_alloc_size; int rbsp_buffer_size; } H2645RBSP; @@ -92,10 +94,15 @@ int ff_h2645_extract_rbsp(const uint8_t *src, int length, H2645RBSP *rbsp, * the data is contained in the input buffer pointed to by buf. * Otherwise, the unescaped data is part of the rbsp_buffer described by the * packet's H2645RBSP. + * + * If the packet's rbsp_buffer_ref is not NULL, the underlying AVBuffer must + * own rbsp_buffer. If not and rbsp_buffer is not NULL, use_ref must be 0. + * If use_ref is set, rbsp_buffer will be reference-counted and owned by + * the underlying AVBuffer of rbsp_buffer_ref. */ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int is_nalff, int nal_length_size, - enum AVCodecID codec_id, int small_padding); + enum AVCodecID codec_id, int small_padding, int use_ref); /** * Free all the allocated memory in the packet. diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 34ffe3b1fe..290ab681a9 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -359,7 +359,7 @@ static int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps, H2645Packet pkt = { 0 }; int i, ret = 0; - ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264, 1); + ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264, 1, 0); if (ret < 0) { ret = 0; goto fail; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 00d922fbe9..837c3b7538 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -622,8 +622,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) h->is_avc = 1; } - ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, - h->nal_length_size, avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST); + ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, h->nal_length_size, + avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error splitting the input into NAL units.\n"); diff --git a/libavcodec/hevc_parse.c b/libavcodec/hevc_parse.c index b1b27eef09..dddb293df6 100644 --- a/libavcodec/hevc_parse.c +++ b/libavcodec/hevc_parse.c @@ -29,7 +29,8 @@ static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets int ret = 0; H2645Packet pkt = { 0 }; - ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx, is_nalff, nal_length_size, AV_CODEC_ID_HEVC, 1); + ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx, is_nalff, + nal_length_size, AV_CODEC_ID_HEVC, 1, 0); if (ret < 0) { goto done; } diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 369d1338d0..35a6b04195 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -194,7 +194,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, ff_hevc_reset_sei(sei); ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx, ctx->is_avc, - ctx->nal_length_size, AV_CODEC_ID_HEVC, 1); + ctx->nal_length_size, AV_CODEC_ID_HEVC, 1, 0); if (ret < 0) return ret; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71..b82e37e367 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3024,7 +3024,7 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) /* split the input packet into NAL units, so we know the upper bound on the * number of slices in the frame */ ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, s->is_nalff, - s->nal_length_size, s->avctx->codec_id, 1); + s->nal_length_size, s->avctx->codec_id, 1, 0); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error splitting the input into NAL units.\n");