From patchwork Sun Jan 29 09:17:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas George X-Patchwork-Id: 2355 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp979872vsb; Sun, 29 Jan 2017 01:17:17 -0800 (PST) X-Received: by 10.223.141.229 with SMTP id o92mr16086177wrb.22.1485681437493; Sun, 29 Jan 2017 01:17:17 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id w77si9197774wmw.30.2017.01.29.01.17.16; Sun, 29 Jan 2017 01:17:17 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5695B68A72D; Sun, 29 Jan 2017 11:17:12 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from nef2.ens.fr (nef2.ens.fr [129.199.96.40]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B322768A3C9 for ; Sun, 29 Jan 2017 11:17:05 +0200 (EET) Received: from phare.normalesup.org (phare.normalesup.org [129.199.129.80]) by nef2.ens.fr (8.13.6/1.01.28121999) with ESMTP id v0T9H6vM033180 for ; Sun, 29 Jan 2017 10:17:07 +0100 (CET) Received: by phare.normalesup.org (Postfix, from userid 1001) id E8E5AE00FD; Sun, 29 Jan 2017 10:17:06 +0100 (CET) From: Nicolas George To: ffmpeg-devel@ffmpeg.org Date: Sun, 29 Jan 2017 10:17:03 +0100 Message-Id: <20170129091703.16745-1-george@nsup.org> X-Mailer: git-send-email 2.11.0 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (nef2.ens.fr [129.199.96.32]); Sun, 29 Jan 2017 10:17:07 +0100 (CET) Subject: [FFmpeg-devel] [PATCH] lavfi: make ff_framequeue_skip_samples() more useful. 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Instead of just updating statistics, have it actually do the work instead of leaving that job to the call site. Also: skip the samples by updating the frame data pointers instead of moving the samples. More efficient and avoid writing into shared frames. Found-By: Muhammad Faiz Signed-off-by: Nicolas George --- libavfilter/avfilter.c | 8 +------- libavfilter/framequeue.c | 27 +++++++++++++++++++++++++++ libavfilter/framequeue.h | 11 +++++------ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index c12d4912a8..b431990edc 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1235,13 +1235,7 @@ static int take_samples(AVFilterLink *link, unsigned min, unsigned max, frame = ff_framequeue_peek(&link->fifo, 0); av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, link->channels, link->format); - frame->nb_samples -= n; - av_samples_copy(frame->extended_data, frame->extended_data, 0, n, - frame->nb_samples, link->channels, link->format); - if (frame->pts != AV_NOPTS_VALUE) - frame->pts += av_rescale_q(n, av_make_q(1, link->sample_rate), link->time_base); - ff_framequeue_update_peeked(&link->fifo, 0); - ff_framequeue_skip_samples(&link->fifo, n); + ff_framequeue_skip_samples(&link->fifo, n, link->time_base); } *rframe = buf; diff --git a/libavfilter/framequeue.c b/libavfilter/framequeue.c index a4ffa86c95..26bfa49967 100644 --- a/libavfilter/framequeue.c +++ b/libavfilter/framequeue.c @@ -121,3 +121,30 @@ AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx) check_consistency(fq); return b->frame; } + +void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base) +{ + FFFrameBucket *b; + size_t bytes; + int planar, planes, i; + + check_consistency(fq); + av_assert1(fq->queued); + b = bucket(fq, 0); + av_assert1(samples < b->frame->nb_samples); + planar = av_sample_fmt_is_planar(b->frame->format); + planes = planar ? b->frame->channels : 1; + bytes = samples * av_get_bytes_per_sample(b->frame->format); + if (!planar) + bytes *= b->frame->channels; + if (b->frame->pts != AV_NOPTS_VALUE) + b->frame->pts += av_rescale_q(samples, av_make_q(1, b->frame->sample_rate), time_base); + b->frame->nb_samples -= samples; + b->frame->linesize[0] -= bytes; + for (i = 0; i < planes; i++) + b->frame->extended_data[i] += bytes; + for (i = 0; i < planes && i < AV_NUM_DATA_POINTERS; i++) + b->frame->data[i] = b->frame->extended_data[i]; + fq->total_samples_tail += samples; + ff_framequeue_update_peeked(fq, 0); +} diff --git a/libavfilter/framequeue.h b/libavfilter/framequeue.h index f5ef744638..5aa2c725a7 100644 --- a/libavfilter/framequeue.h +++ b/libavfilter/framequeue.h @@ -161,14 +161,13 @@ static inline void ff_framequeue_update_peeked(FFFrameQueue *fq, size_t idx) } /** - * Update the sample count in the queue. + * Skip samples from the first frame in the queue. * * This function must be used when the first frame was accessed using - * ff_framequeue_peek() and samples were removed from it. + * ff_framequeue_peek() and samples were consumed from it. + * It adapts the data pointers and timestamps of the head frame to account + * for the skipped samples. */ -static inline void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t n) -{ - fq->total_samples_tail += n; -} +void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base); #endif /* AVFILTER_FRAMEQUEUE_H */