From patchwork Wed Nov 21 18:34:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 11111 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 76F3A44C4B6 for ; Wed, 21 Nov 2018 20:35:52 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 023CC689F0A; Wed, 21 Nov 2018 20:35:53 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A29BE689EE0 for ; Wed, 21 Nov 2018 20:35:46 +0200 (EET) Received: by mail-wr1-f45.google.com with SMTP id x10so6748570wrs.8 for ; Wed, 21 Nov 2018 10:35:49 -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=Ps9Wotgz0G0MwCTtYJ24B9ND5zWLikAQQxW8x3NLDP8=; b=RcOkQZ27a5ztJDKx5KR7zilms3tDC0hgBgtclcJ3TgJkI28uxVBUMO+I/1XLTRLuzZ nExC9PeIEetRBrnIg1IB0fAux+7SX4ZnQm+c6XYpICNykbu2hPPOHK0V7x5SGeMmk5I+ GkxvsmvjzZFC/UJC16DoTBc5TgnaVn7ShNNG6gxo+KY8Uqa/a5GrmHd6YAmm+wD/DU1R YGx0o0eU72H0pfwfSIqFBhcfXXBBk8f7N+Hzrn8BZPZOg8Skj9JxTSlxpVzXImQnWbP5 3/RshTzq+yHXhMStZlAT/qa22PAJ5e3y7g0yLPuvnIkKrU4nndaUdUQaTSQThmefeWgi 5ZqA== 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=Ps9Wotgz0G0MwCTtYJ24B9ND5zWLikAQQxW8x3NLDP8=; b=GovSfUmLwRDaxXMU2TCgJBG2RmkaO0GWS7mE2wP0dwaGNE2+NwRVYyoR7UgKEv7mIY XHZoMfaRfeUPJ+VlQtXNGJ2tdUc4+ivP1Ad2UDkWC59xhsbKCYb/lep5sFRRneUWbs5K IPGBG1UouJTt8fecmjfl7ylHXlL926xUgRqSxFKbTCdnGO1pm5Z2Ur0eZcFQsqQ8KzlY oIHDiDCr7mL3ySw3Kp5Li7FRn9LaMgNXjiplhTy340JVTsVFhT+A18PHpYYcwO3mpBY5 iKI4wGeJiwD2qpdCqmGx91Czrz/RdXJjHmOfGNZOLOvNXzm3sAwK40MqDYMK7WuKfgfE 0XIA== X-Gm-Message-State: AA+aEWbBo+xremTkmGcORy/BlxZWy0HgVtm570nyw+O0abV6Mc4z1Z97 Gxkn5ZMqGACqJr5+n0OJ8fLMwitf X-Google-Smtp-Source: AFSGD/VqYVLQQLGgD16OeKYLWNnnZsOX2wDj7aj/5ZSNCP17oMMMANMfj09zIzUqS6AvZ8uJjovoig== X-Received: by 2002:a5d:44d1:: with SMTP id z17mr6726379wrr.271.1542825348551; Wed, 21 Nov 2018 10:35:48 -0800 (PST) Received: from localhost.localdomain (ipbcc08c44.dynamic.kabel-deutschland.de. [188.192.140.68]) by smtp.googlemail.com with ESMTPSA id x79sm3207524wmd.42.2018.11.21.10.35.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Nov 2018 10:35:48 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Wed, 21 Nov 2018 19:34:30 +0100 Message-Id: <20181121183431.6404-3-andreas.rheinhardt@googlemail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181121183431.6404-1-andreas.rheinhardt@googlemail.com> References: <20181121183431.6404-1-andreas.rheinhardt@googlemail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/3] 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 | 12 ++++----- libavcodec/extract_extradata_bsf.c | 4 +-- libavcodec/h2645_parse.c | 43 +++++++++++++++++++++++++++--- libavcodec/h2645_parse.h | 10 +++++-- libavcodec/h264_parse.c | 4 +-- libavcodec/h264dec.c | 6 ++--- libavcodec/hevc_parse.c | 5 ++-- libavcodec/hevc_parser.c | 4 +-- libavcodec/hevcdec.c | 4 +-- 9 files changed, 67 insertions(+), 25 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 6846cad0bb..df2b5f3f5e 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -611,7 +611,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, NULL); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC SPS array.\n"); return err; @@ -635,7 +635,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, NULL); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC PPS array.\n"); return err; @@ -689,7 +689,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, NULL); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split " "HVCC array %d (%d NAL units of type %d).\n", @@ -708,7 +708,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, NULL); if (err < 0) return err; @@ -1510,7 +1510,7 @@ static void cbs_h264_close(CodedBitstreamContext *ctx) CodedBitstreamH264Context *h264 = ctx->priv_data; int i; - ff_h2645_packet_uninit(&h264->common.read_packet); + ff_h2645_packet_uninit(&h264->common.read_packet, NULL); av_freep(&h264->common.write_buffer); @@ -1525,7 +1525,7 @@ static void cbs_h265_close(CodedBitstreamContext *ctx) CodedBitstreamH265Context *h265 = ctx->priv_data; int i; - ff_h2645_packet_uninit(&h265->common.read_packet); + ff_h2645_packet_uninit(&h265->common.read_packet, NULL); av_freep(&h265->common.write_buffer); diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index f37427c7e1..5598064eb3 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, NULL); if (ret < 0) return ret; @@ -393,7 +393,7 @@ static void extract_extradata_close(AVBSFContext *ctx) { ExtractExtradataContext *s = ctx->priv_data; ff_av1_packet_uninit(&s->av1_pkt); - ff_h2645_packet_uninit(&s->h2645_pkt); + ff_h2645_packet_uninit(&s->h2645_pkt, NULL); } static const enum AVCodecID codec_ids[] = { diff --git a/libavcodec/h2645_parse.c b/libavcodec/h2645_parse.c index aaa4b8f443..ad5d04f0a4 100644 --- a/libavcodec/h2645_parse.c +++ b/libavcodec/h2645_parse.c @@ -343,9 +343,37 @@ static int find_next_start_code(const uint8_t *buf, const uint8_t *next_avc) return i + 3; } +static void handle_ref_buffer(H2645RBSP *rbsp, AVBufferRef **ref, int size) +{ + if (size + AV_INPUT_BUFFER_PADDING_SIZE <= 0) + goto fail; + + size += AV_INPUT_BUFFER_PADDING_SIZE; + + if (*ref && (*ref)->size >= size && av_buffer_is_writable(*ref)) + return; + + av_buffer_unref(ref); + + size = FFMAX(size + (size >> 4) + 32, size); + + *ref = av_buffer_alloc(size); + if (*ref) { + rbsp->rbsp_buffer = (*ref)->data; + rbsp->rbsp_buffer_alloc_size = size; + return; + } + +fail: + av_buffer_unref(ref); + rbsp->rbsp_buffer = NULL; + rbsp->rbsp_buffer_alloc_size = 0; + 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, AVBufferRef **ref) { GetByteContext bc; int consumed, ret = 0; @@ -353,7 +381,11 @@ 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); + if (!ref) + av_fast_padded_malloc(&pkt->rbsp.rbsp_buffer, &pkt->rbsp.rbsp_buffer_alloc_size, length + padding); + else + handle_ref_buffer(&pkt->rbsp, ref, length + padding); + if (!pkt->rbsp.rbsp_buffer) return AVERROR(ENOMEM); @@ -466,7 +498,7 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, return 0; } -void ff_h2645_packet_uninit(H2645Packet *pkt) +void ff_h2645_packet_uninit(H2645Packet *pkt, AVBufferRef *ref) { int i; for (i = 0; i < pkt->nals_allocated; i++) { @@ -474,6 +506,9 @@ void ff_h2645_packet_uninit(H2645Packet *pkt) } av_freep(&pkt->nals); pkt->nals_allocated = 0; - av_freep(&pkt->rbsp.rbsp_buffer); + if (!ref) + av_freep(&pkt->rbsp.rbsp_buffer); + else + pkt->rbsp.rbsp_buffer = NULL; 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 a0a5ca5868..bdd8a32466 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" @@ -91,15 +92,20 @@ 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 ref is not NULL, *ref must either be NULL in which case pkt's underlying + * rbsp_buffer must be NULL, too, or (*ref)->buffer owns rbsp_buffer. In both + * cases, rbsp_buffer will be owned by **ref afterwards. */ 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, AVBufferRef **ref); /** * Free all the allocated memory in the packet. + * If ref is supplied, the underlying AVBuffer is supposed to own the packet's + * rbsp_buffer. */ -void ff_h2645_packet_uninit(H2645Packet *pkt); +void ff_h2645_packet_uninit(H2645Packet *pkt, AVBufferRef *ref); static inline int get_nalsize(int nal_length_size, const uint8_t *buf, int buf_size, int *buf_index, void *logctx) diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 34ffe3b1fe..57f0e8692e 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, NULL); if (ret < 0) { ret = 0; goto fail; @@ -387,7 +387,7 @@ static int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps, } fail: - ff_h2645_packet_uninit(&pkt); + ff_h2645_packet_uninit(&pkt, NULL); return ret; } diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 00d922fbe9..62a25eda31 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -377,7 +377,7 @@ static av_cold int h264_decode_end(AVCodecContext *avctx) ff_h264_sei_uninit(&h->sei); ff_h264_ps_uninit(&h->ps); - ff_h2645_packet_uninit(&h->pkt); + ff_h2645_packet_uninit(&h->pkt, NULL); ff_h264_unref_picture(h, &h->cur_pic); av_frame_free(&h->cur_pic.f); @@ -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, NULL); 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..3cf9e3757e 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, NULL); if (ret < 0) { goto done; } @@ -67,7 +68,7 @@ static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets } done: - ff_h2645_packet_uninit(&pkt); + ff_h2645_packet_uninit(&pkt, NULL); if (err_recognition & AV_EF_EXPLODE) return ret; diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 369d1338d0..51c240069d 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, NULL); if (ret < 0) return ret; @@ -363,7 +363,7 @@ static void hevc_parser_close(AVCodecParserContext *s) HEVCParserContext *ctx = s->priv_data; ff_hevc_ps_uninit(&ctx->ps); - ff_h2645_packet_uninit(&ctx->pkt); + ff_h2645_packet_uninit(&ctx->pkt, NULL); ff_hevc_reset_sei(&ctx->sei); av_freep(&ctx->pc.buffer); diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71..42fdb090ec 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, NULL); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error splitting the input into NAL units.\n"); @@ -3305,7 +3305,7 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) s->HEVClc = NULL; av_freep(&s->HEVClcList[0]); - ff_h2645_packet_uninit(&s->pkt); + ff_h2645_packet_uninit(&s->pkt, NULL); return 0; }