From patchwork Wed Mar 29 14:12:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ronald S. Bultje" X-Patchwork-Id: 3171 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.44.195 with SMTP id s186csp1111255vss; Wed, 29 Mar 2017 07:12:47 -0700 (PDT) X-Received: by 10.28.131.65 with SMTP id f62mr1042764wmd.4.1490796766949; Wed, 29 Mar 2017 07:12:46 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id v130si7337353wmv.161.2017.03.29.07.12.46; Wed, 29 Mar 2017 07:12:46 -0700 (PDT) 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; dkim=neutral (body hash did not verify) header.i=@gmail.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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E7259689AEF; Wed, 29 Mar 2017 17:12:14 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk0-f181.google.com (mail-qk0-f181.google.com [209.85.220.181]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A63A8689A72 for ; Wed, 29 Mar 2017 17:12:07 +0300 (EEST) Received: by mail-qk0-f181.google.com with SMTP id r142so13790348qke.2 for ; Wed, 29 Mar 2017 07:12:30 -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; bh=iqIup5lWPVV3MDgAbCFk5taT2voPJ92BLyGZC7jj4nA=; b=fSxrBpHc6YuHScpEc3U/aJmQ3JgXqXMKYa1QOyGZX3STyzcrCzrJZozA9iK1wBun80 OQS1UCI0kXtlAxtBJLfmKzxxLdcVn9pDwBl1bs0ed246SZWJAEgFREI5o5aAc7OQqce5 KIHCT/JaD+5arf3TcLDKpiL7Yh/58ej9wN5T51vY+NJ4AZCz7Ssu5P5SRzQdlSmBQJ33 nEQbWChKF8+p+ngdts6lCrZmQfJGwTfzjOHxyWfPiacvbuP56V5wgOTJW/1f5/1EvHMD 0nynuZHFsj2Pq8iRBmnVaGrb2XXj5c0BZZU4c/RSASJEwjW+5YC1pnIJuYSlDXU/7vJA +Ztg== 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; bh=iqIup5lWPVV3MDgAbCFk5taT2voPJ92BLyGZC7jj4nA=; b=QSZTrI/PzaNTpEDsyS3MsWoVMLaq3JCQVESz/0H+LwfHXlYYTsDrGmtj2+ZJiYpTfb mSTv+rnDczydivg2KZbD6HUAjTZegiOmMqiMOM88A9OkDf09rE3ldHdtMBWDq3aL0eXC ssgQFXuxYPV9fxKIb5HlCyI8aCEOG09V4Y1ZbbqEGmRDISrwmVvFWjl05Ko9Xe3phXN2 BfL/Ucru3KyyvO6bNOMPdJfoFewSPFN5NoBDmyH9lcSbNPAMuoEVpZQD4IrQRZ3zGVGx E7PROxC/cd8Wq/fp4k8EyOykL9wwvSsvL0egoAZS7sepohakz8maaJRMk2Lc79/blBAF wMAg== X-Gm-Message-State: AFeK/H1FDI9Hjn7ntrt2AlXrGBeiN+7uEe7ndgR+MAqjgmCDiAX0cks4qFYkAE5YEYjUww== X-Received: by 10.55.27.71 with SMTP id b68mr697563qkb.69.1490796749128; Wed, 29 Mar 2017 07:12:29 -0700 (PDT) Received: from localhost.localdomain ([65.206.95.146]) by smtp.gmail.com with ESMTPSA id u63sm4976197qkh.45.2017.03.29.07.12.28 (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 29 Mar 2017 07:12:28 -0700 (PDT) From: "Ronald S. Bultje" To: ffmpeg-devel@ffmpeg.org Date: Wed, 29 Mar 2017 10:12:20 -0400 Message-Id: <1490796744-76454-2-git-send-email-rsbultje@gmail.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1490796744-76454-1-git-send-email-rsbultje@gmail.com> References: <1490796744-76454-1-git-send-email-rsbultje@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/6] pthread_frame: allow per-field ThreadFrame owners. 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: "Ronald S. Bultje" MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This tries to handle cases where separate invocations of decode_frame() (each running in separate threads) write to respective fields in the same AVFrame->data[]. Having per-field owners makes interaction between readers (the referencing thread) and writers (the decoding thread) slightly more optimal if both accesses are field-based, since they will use the respective producer's thread objects (mutex/cond) instead of sharing the thread objects of the first field's producer. --- libavcodec/h264_slice.c | 8 +++++--- libavcodec/pthread_frame.c | 18 ++++++++++-------- libavcodec/thread.h | 2 +- libavcodec/utils.c | 7 ++++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index fa1e9ae..d4d31cc 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1423,14 +1423,14 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, * We have to do that before the "dummy" in-between frame allocation, * since that can modify h->cur_pic_ptr. */ if (h->first_field) { + int last_field = last_pic_structure == PICT_BOTTOM_FIELD; av_assert0(h->cur_pic_ptr); av_assert0(h->cur_pic_ptr->f->buf[0]); assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF); /* Mark old field/frame as completed */ - if (h->cur_pic_ptr->tf.owner == h->avctx) { - ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, - last_pic_structure == PICT_BOTTOM_FIELD); + if (h->cur_pic_ptr->tf.owner[last_field] == h->avctx) { + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, last_field); } /* figure out if we have a complementary field pair */ @@ -1568,7 +1568,9 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, return AVERROR_INVALIDDATA; } } else { + int field = h->picture_structure == PICT_BOTTOM_FIELD; release_unused_pictures(h, 0); + h->cur_pic_ptr->tf.owner[field] = h->avctx; } /* Some macroblocks can be accessed before they're available in case * of lost slices, MBAFF or threading. */ diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 295763a..34c36d8 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -568,10 +568,11 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) atomic_load_explicit(&progress[field], memory_order_relaxed) >= n) return; - p = f->owner->internal->thread_ctx; + p = f->owner[field]->internal->thread_ctx; - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); + if (f->owner[field]->debug&FF_DEBUG_THREADS) + av_log(f->owner[field], AV_LOG_DEBUG, + "%p finished %d field %d\n", progress, n, field); pthread_mutex_lock(&p->progress_mutex); @@ -590,10 +591,11 @@ void ff_thread_await_progress(ThreadFrame *f, int n, int field) atomic_load_explicit(&progress[field], memory_order_acquire) >= n) return; - p = f->owner->internal->thread_ctx; + p = f->owner[field]->internal->thread_ctx; - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); + if (f->owner[field]->debug&FF_DEBUG_THREADS) + av_log(f->owner[field], AV_LOG_DEBUG, + "thread awaiting %d field %d from %p\n", n, field, progress); pthread_mutex_lock(&p->progress_mutex); while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) @@ -886,7 +888,7 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int PerThreadContext *p = avctx->internal->thread_ctx; int err; - f->owner = avctx; + f->owner[0] = f->owner[1] = avctx; ff_init_buffer_info(avctx, f->f); @@ -990,7 +992,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); av_buffer_unref(&f->progress); - f->owner = NULL; + f->owner[0] = f->owner[1] = NULL; if (can_direct_free) { av_frame_unref(f->f); diff --git a/libavcodec/thread.h b/libavcodec/thread.h index c848d7a..90864b5 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -34,7 +34,7 @@ typedef struct ThreadFrame { AVFrame *f; - AVCodecContext *owner; + AVCodecContext *owner[2]; // progress->data is an array of 2 ints holding progress for top/bottom // fields AVBufferRef *progress; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 365ee26..3e826e8 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3974,7 +3974,8 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) { int ret; - dst->owner = src->owner; + dst->owner[0] = src->owner[0]; + dst->owner[1] = src->owner[1]; ret = av_frame_ref(dst->f, src->f); if (ret < 0) @@ -3984,7 +3985,7 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) if (src->progress && !(dst->progress = av_buffer_ref(src->progress))) { - ff_thread_release_buffer(dst->owner, dst); + ff_thread_release_buffer(dst->owner[0], dst); return AVERROR(ENOMEM); } @@ -4000,7 +4001,7 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { - f->owner = avctx; + f->owner[0] = f->owner[1] = avctx; return ff_get_buffer(avctx, f->f, flags); }