From patchwork Sun Apr 19 14:34:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 19086 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 6957E44AD8E for ; Sun, 19 Apr 2020 17:58:08 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 451D168B8C3; Sun, 19 Apr 2020 17:58:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f193.google.com (mail-qt1-f193.google.com [209.85.160.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8254E68B8A6 for ; Sun, 19 Apr 2020 17:58:01 +0300 (EEST) Received: by mail-qt1-f193.google.com with SMTP id o10so6333802qtr.6 for ; Sun, 19 Apr 2020 07:58:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=v8QZJc36wcC6BoHtgmfJs+0gtNDApUDxeLvYcpDQ4hk=; b=cRQnV214UBJqbbXwmzouoeN3TBfn9Z2C9E85hdthgT1f+4ZZA6lex9oOk2Nq03fOC+ DyxQPdx2noJ+BYCF+w5ZKgTFbQdDNOmBH08OF/CaAFXceyQ7MV1TuqXL9dWHIjsT5GFx ZtaWqPDsj8onvuURx0Pxhpuqoqib/erbUqKwM/QGL1us1XvxMHgu/aeCutZg3gFzyO6Z 95zsEuhpbbJD9W0M9R74/hq+s1QRAbpNIEi80HNixbbTSwUQy5zuL61tyERT6QFUqrX5 U4pdMsOFwVdKa7u4lfHh59GZ5JKmIZSXSSulNEoW2EDxyAIGTDEL3Lf3C1vslq9P26Pm FDBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=v8QZJc36wcC6BoHtgmfJs+0gtNDApUDxeLvYcpDQ4hk=; b=YQTQCsRINbHVmaesNRx44BfPdwuvRA0bwWfz7Rf6OzV/urtSr++7gmNdWmyQi5bEw2 C1koawXENyXaqo6vzt2mQ8Cf2gcRhY83+sWnquzzDBdT4riWSILs/kBL8xJEzVeimqKd 7mRWAev16Wl3OYxJZOWtKUvn8yV9CkHIfn55NbIFpqzHQpuA93wisAwY7rgOGWQnL4CE Fy/kC4QAWegHqGnNKwtRybV+KANpZQ1wKAqN+DxNYc64n2afEnSG63OP5tzOktuzKdce eBA6Uax8SWss/HBu6iboOksVUY4KhVtNwYM71aI/rNsePMOA44OE31GDwlx68nQTgCAD mSUA== X-Gm-Message-State: AGi0PuZO985b7RhMv1PskoTYREcYtZnyOuCsZd2rqNwU1fRAm3iDkXuk v6yYwYFq/RFbfgljl1bByhPDtfPzMi4= X-Google-Smtp-Source: APiQypLOK7DPW45iKjcsX7kRlc0275dU9iJtN6wzch1wI6ZbH7WQtxjuhHnwpcnGBgcDSzK/OoCzCA== X-Received: by 2002:ac8:27cb:: with SMTP id x11mr1265049qtx.272.1587306874489; Sun, 19 Apr 2020 07:34:34 -0700 (PDT) Received: from localhost.localdomain ([191.83.215.190]) by smtp.gmail.com with ESMTPSA id t27sm2564320qkg.4.2020.04.19.07.34.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Apr 2020 07:34:34 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sun, 19 Apr 2020 11:34:06 -0300 Message-Id: <20200419143406.10834-1-jamrial@gmail.com> X-Mailer: git-send-email 2.26.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] avcodec/bsf: restructure the internal implementation of the bistream filter API 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Process input data as soon as it's fed to av_bsf_send_packet(), instead of storing a single packet and expecting the user to call av_bsf_receive_packet() in order to trigger the decoding process before they are allowed to feed more data. This puts the bsf API more in line with the decoupled decode API, without breaking existing using it. Signed-off-by: James Almer --- Now without creating a new reference for the input packet, and behaving the exact same as before for current users that were following the doxy right down to the letter. Also didn't rename buffer_pkt to reduce the size of the diff and easily find the actual changes and additions. libavcodec/avcodec.h | 6 +----- libavcodec/bsf.c | 42 +++++++++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b79b025e53..af2a1b0e90 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4735,10 +4735,6 @@ int av_bsf_init(AVBSFContext *ctx); /** * Submit a packet for filtering. * - * After sending each packet, the filter must be completely drained by calling - * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or - * AVERROR_EOF. - * * @param pkt the packet to filter. The bitstream filter will take ownership of * the packet and reset the contents of pkt. pkt is not touched if an error occurs. * If pkt is empty (i.e. NULL, or pkt->data is NULL and pkt->side_data_elems zero), @@ -4770,7 +4766,7 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt); * an error occurs. * * @note one input packet may result in several output packets, so after sending - * a packet with av_bsf_send_packet(), this function needs to be called + * a packet with av_bsf_send_packet(), this function may need to be called * repeatedly until it stops returning 0. It is also possible for a filter to * output fewer packets than were sent to it, so this function may return * AVERROR(EAGAIN) immediately after a successful av_bsf_send_packet() call. diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c index b9fc771a88..c79a8ebbdf 100644 --- a/libavcodec/bsf.c +++ b/libavcodec/bsf.c @@ -30,6 +30,7 @@ struct AVBSFInternal { AVPacket *buffer_pkt; + AVPacket *out_pkt; int eof; }; @@ -46,8 +47,10 @@ void av_bsf_free(AVBSFContext **pctx) if (ctx->filter->priv_class && ctx->priv_data) av_opt_free(ctx->priv_data); - if (ctx->internal) + if (ctx->internal) { av_packet_free(&ctx->internal->buffer_pkt); + av_packet_free(&ctx->internal->out_pkt); + } av_freep(&ctx->internal); av_freep(&ctx->priv_data); @@ -112,7 +115,8 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) ctx->internal = bsfi; bsfi->buffer_pkt = av_packet_alloc(); - if (!bsfi->buffer_pkt) { + bsfi->out_pkt = av_packet_alloc(); + if (!bsfi->buffer_pkt || !bsfi->out_pkt) { ret = AVERROR(ENOMEM); goto fail; } @@ -185,6 +189,7 @@ void av_bsf_flush(AVBSFContext *ctx) bsfi->eof = 0; av_packet_unref(bsfi->buffer_pkt); + av_packet_unref(bsfi->out_pkt); if (ctx->filter->flush) ctx->filter->flush(ctx); @@ -205,10 +210,21 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) return AVERROR(EINVAL); } + if (!bsfi->buffer_pkt->data && + !bsfi->buffer_pkt->side_data_elems) + goto end; + + if (!bsfi->out_pkt->data && !bsfi->out_pkt->side_data_elems) { + ret = ctx->filter->filter(ctx, bsfi->out_pkt); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } + if (bsfi->buffer_pkt->data || bsfi->buffer_pkt->side_data_elems) return AVERROR(EAGAIN); +end: ret = av_packet_make_refcounted(pkt); if (ret < 0) return ret; @@ -219,7 +235,17 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt) { - return ctx->filter->filter(ctx, pkt); + AVBSFInternal *bsfi = ctx->internal; + int ret; + + if (!bsfi->out_pkt->data && !bsfi->out_pkt->side_data_elems) { + ret = ctx->filter->filter(ctx, bsfi->out_pkt); + if (ret < 0) + return ret; + } + av_packet_move_ref(pkt, bsfi->out_pkt); + + return 0; } int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) @@ -227,12 +253,9 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) AVBSFInternal *bsfi = ctx->internal; AVPacket *tmp_pkt; - if (bsfi->eof) - return AVERROR_EOF; - if (!bsfi->buffer_pkt->data && !bsfi->buffer_pkt->side_data_elems) - return AVERROR(EAGAIN); + return bsfi->eof ? AVERROR_EOF : AVERROR(EAGAIN); tmp_pkt = av_packet_alloc(); if (!tmp_pkt) @@ -248,12 +271,9 @@ int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt) { AVBSFInternal *bsfi = ctx->internal; - if (bsfi->eof) - return AVERROR_EOF; - if (!bsfi->buffer_pkt->data && !bsfi->buffer_pkt->side_data_elems) - return AVERROR(EAGAIN); + return bsfi->eof ? AVERROR_EOF : AVERROR(EAGAIN); av_packet_move_ref(pkt, bsfi->buffer_pkt);