From patchwork Mon Dec 9 12:20:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 11279287 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B6C0F6C1 for ; Mon, 9 Dec 2019 12:20:54 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 74C7F2080D for ; Mon, 9 Dec 2019 12:20:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="FINEooG2"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="je6fVmXR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 74C7F2080D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=UaLrHR2hyR+ZDE7Pouk4uFv3l+k/FghzpnCmZA7O9Yc=; b=FINEooG2u/Ko3X zo/Yvl6L+rDf+97HSjFkzsKmCYAB4lnw2+jsM8QedPes+fWlIThdjSVf4tATtOtEXvKn3J7Zk0VYw 3pEwxMnXfw9KFk05ddM2qaV6gNY2pgHX2hY9BXU8LrtaZGsBUdizMcoBH3AHqaWYIyz3f77W7GizN nLKQMiKzmev27O7Dh6EBbz4qO6a1s1GID9Pzpp/KskuwpRsF8EwQsLQvFwV0tNNLvqK9HRijqsC7j iz5p81QSDo3iAjTUaCg+ve2JmU2VJG3R4/tdaeYlG/aXgmEQ1ICBaJIPJ4N0xV3PoFDu7BJ4I5aLq mSCI9iL74unTzj3Km6sw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ieI1y-0004xD-Bm; Mon, 09 Dec 2019 12:20:50 +0000 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ieI1i-0004e5-ME for linux-arm-kernel@lists.infradead.org; Mon, 09 Dec 2019 12:20:38 +0000 Received: by mail-wm1-x341.google.com with SMTP id p9so15232009wmc.2 for ; Mon, 09 Dec 2019 04:20:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6O33bazV0D/HL/rWD7a2aB0z7qlA5D8z3BxegqrjqrE=; b=je6fVmXRkGD/74Y+pA+i03hMy1KTkQsEPQhLioisonmyOx3/E0sDKVzqli2AkTeHrK E24yQmRevOgDYd9d/ryyAsT6+CFiepOrx+eydMG2xSb2rRlYebSyrEwVo0lKY/nHT7NP JPe+YeUiQCDQw4ns/0ThAriILSYsb5eQk+Sp6IHVWSIOSGCsdMtGE2syB65Z1Gky+dOe vkTI7I0Ze1rUA/1MpZ5zgaJXKP8r0GcfUvuNL2J4FrPTzni7ZCXU++07heIisKn4P5b6 mwpzqd7jhKRtOblHOpQWQAWpcTj5RZGNNUM0kEEQMaEx1Cd5XBf42Brim/8pjgxbx+/H HQ5A== 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=6O33bazV0D/HL/rWD7a2aB0z7qlA5D8z3BxegqrjqrE=; b=DfhRvwJ4csPrOutccDhxhE39nF8B8XGWXjKlwgb/lBssycFyYAqzZWOFUV6lJRrjKG 1mIZnDXolMz9AeMJMnugvlEOSqPbgixkjXDWqndwZssp7bIy4jeMMEJQpb9tIM3KbGvO yq6Xzu2zDsIN6pXWpqrlFZodUagRsT0cXpyDoXXGwX6jZlSGD9p6ZOoLBxqOpGBqsuTm xWl22VfJpcLfbz3gbG+mGCKdjzvEtEwwtWRxv2SR7wf2qsd3XO7Q2wWsn45Vw7aErJbR Y84So4iGJV6USRbYrB/IiKTElP9ijNcW2rWlxnQ18tpm0KyWxzeurWJITl74P+xq9Ayc AOiA== X-Gm-Message-State: APjAAAWSxsGtlTaFuc62k0gNh0qpwP7sjmDhl9bU1JOSExFLmKs/mOoZ pV5ozTjHFGWLwt8a7IoUA0nq/w== X-Google-Smtp-Source: APXvYqyXwrxsrJO0WeI3S94iV7g79KWjCPyc6AbuoDXoWQM6mDl+tkUwi2U9Z3x5LoX167JEWAZx1w== X-Received: by 2002:a1c:3d8a:: with SMTP id k132mr24396542wma.144.1575894032959; Mon, 09 Dec 2019 04:20:32 -0800 (PST) Received: from bender.baylibre.local (wal59-h01-176-150-251-154.dsl.sta.abo.bbox.fr. [176.150.251.154]) by smtp.gmail.com with ESMTPSA id u18sm27066949wrt.26.2019.12.09.04.20.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Dec 2019 04:20:32 -0800 (PST) From: Neil Armstrong To: mchehab@kernel.org, hans.verkuil@cisco.com Subject: [PATCH v3 2/4] media: vicodec: use v4l2-mem2mem draining, stopped and next-buf-is-last states handling Date: Mon, 9 Dec 2019 13:20:26 +0100 Message-Id: <20191209122028.13714-3-narmstrong@baylibre.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20191209122028.13714-1-narmstrong@baylibre.com> References: <20191209122028.13714-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191209_042034_727299_5F6D398D X-CRM114-Status: GOOD ( 16.61 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2a00:1450:4864:20:0:0:0:341 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Maxime Jourdan , Neil Armstrong , linux-kernel@vger.kernel.org, Hans Verkuil , linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Use the previously introduced v4l2-mem2mem core APIs to handle the drainig, stopped and next-buf-is-last states. With these changes, the v4l2-compliance still passes with the following commands : # v4l2-ctl --stream-mmap --stream-out-mmap --stream-to-hdr out.comp --stream-from in.yuv >>>><><><><><><><><><><><><><><><><>< 15.53 fps 15.53 fps ><><><><><><><><><><><><>< 13.99 fps 13.99 fps ><><><><><><><><><><><>< 13.52 fps 13.52 fps ><><><><><><><><><><><><>< 13.41 fps 13.41 fps ><><><><><><><><><><><><>< 13.21 fps 13.21 fps ><><><><><><><><><><><>< 13.09 fps 13.09 fps ><><><><><><>< STOP ENCODER <<< EOS EVENT # v4l2-compliance --stream-from in.yuv -s v4l2-compliance SHA: 7ead0e1856b89f2e19369af452bb03fd0cd16793, 64 bits [...] Total for vicodec device /dev/video0: 50, Succeeded: 50, Failed: 0, Warnings: 0 The full output is available at [1] # v4l2-compliance -d1 --stream-from-hdr out.comp -s v4l2-compliance SHA: 7ead0e1856b89f2e19369af452bb03fd0cd16793, 64 bits [...] Total for vicodec device /dev/video1: 50, Succeeded: 50, Failed: 0, Warnings: 0 The full output is available at [2] No functional changes should be noticed. [1] https://termbin.com/25nn [2] https://termbin.com/dza4 Suggested-by: Hans Verkuil Suggested-by: Maxime Jourdan Signed-off-by: Neil Armstrong --- drivers/media/platform/vicodec/vicodec-core.c | 154 +++++------------- 1 file changed, 44 insertions(+), 110 deletions(-) diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c index 82350097503e..5606dbd7cf4d 100644 --- a/drivers/media/platform/vicodec/vicodec-core.c +++ b/drivers/media/platform/vicodec/vicodec-core.c @@ -117,15 +117,10 @@ struct vicodec_ctx { struct vicodec_dev *dev; bool is_enc; bool is_stateless; - bool is_draining; - bool next_is_last; - bool has_stopped; spinlock_t *lock; struct v4l2_ctrl_handler hdl; - struct vb2_v4l2_buffer *last_src_buf; - /* Source and destination queue data */ struct vicodec_q_data q_data[2]; struct v4l2_fwht_state state; @@ -431,11 +426,11 @@ static void device_run(void *priv) v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false); spin_lock(ctx->lock); - if (!ctx->comp_has_next_frame && src_buf == ctx->last_src_buf) { + if (!ctx->comp_has_next_frame && + v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { dst_buf->flags |= V4L2_BUF_FLAG_LAST; v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event); - ctx->is_draining = false; - ctx->has_stopped = true; + v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); } if (ctx->is_enc || ctx->is_stateless) { src_buf->sequence = q_src->sequence++; @@ -586,8 +581,6 @@ static int job_ready(void *priv) unsigned int max_to_copy; unsigned int comp_frame_size; - if (ctx->has_stopped) - return 0; if (ctx->source_changed) return 0; if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame) @@ -607,7 +600,8 @@ static int job_ready(void *priv) if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) { state = get_next_header(ctx, &p, p_src + sz - p); if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) { - if (ctx->is_draining && src_buf == ctx->last_src_buf) + if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, + src_buf)) return 1; job_remove_src_buf(ctx, state); goto restart; @@ -636,7 +630,8 @@ static int job_ready(void *priv) p += copy; ctx->comp_size += copy; if (ctx->comp_size < max_to_copy) { - if (ctx->is_draining && src_buf == ctx->last_src_buf) + if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, + src_buf)) return 1; job_remove_src_buf(ctx, state); goto restart; @@ -1219,41 +1214,6 @@ static int vidioc_s_selection(struct file *file, void *priv, return 0; } -static int vicodec_mark_last_buf(struct vicodec_ctx *ctx) -{ - struct vb2_v4l2_buffer *next_dst_buf; - int ret = 0; - - spin_lock(ctx->lock); - if (ctx->is_draining) { - ret = -EBUSY; - goto unlock; - } - if (ctx->has_stopped) - goto unlock; - - ctx->last_src_buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx); - ctx->is_draining = true; - if (ctx->last_src_buf) - goto unlock; - - next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - if (!next_dst_buf) { - ctx->next_is_last = true; - goto unlock; - } - - next_dst_buf->flags |= V4L2_BUF_FLAG_LAST; - vb2_buffer_done(&next_dst_buf->vb2_buf, VB2_BUF_STATE_DONE); - ctx->is_draining = false; - ctx->has_stopped = true; - v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event); - -unlock: - spin_unlock(ctx->lock); - return ret; -} - static int vicodec_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *ec) { @@ -1268,18 +1228,15 @@ static int vicodec_encoder_cmd(struct file *file, void *fh, !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) return 0; - if (ec->cmd == V4L2_ENC_CMD_STOP) - return vicodec_mark_last_buf(ctx); - ret = 0; - spin_lock(ctx->lock); - if (ctx->is_draining) { - ret = -EBUSY; - } else if (ctx->has_stopped) { - ctx->has_stopped = false; + ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec); + if (ret < 0) + return ret; + + if (ec->cmd == V4L2_ENC_CMD_START && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q); - } - spin_unlock(ctx->lock); - return ret; + + return 0; } static int vicodec_decoder_cmd(struct file *file, void *fh, @@ -1296,18 +1253,15 @@ static int vicodec_decoder_cmd(struct file *file, void *fh, !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) return 0; - if (dc->cmd == V4L2_DEC_CMD_STOP) - return vicodec_mark_last_buf(ctx); - ret = 0; - spin_lock(ctx->lock); - if (ctx->is_draining) { - ret = -EBUSY; - } else if (ctx->has_stopped) { - ctx->has_stopped = false; + ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc); + if (ret < 0) + return ret; + + if (dc->cmd == V4L2_DEC_CMD_START && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q); - } - spin_unlock(ctx->lock); - return ret; + + return 0; } static int vicodec_enum_framesizes(struct file *file, void *fh, @@ -1480,23 +1434,21 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, }; - if (vb2_is_streaming(vq_cap)) { - if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) && - ctx->next_is_last) { - unsigned int i; + if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) && + vb2_is_streaming(vb->vb2_queue) && + v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { + unsigned int i; - for (i = 0; i < vb->num_planes; i++) - vb->planes[i].bytesused = 0; - vbuf->flags = V4L2_BUF_FLAG_LAST; - vbuf->field = V4L2_FIELD_NONE; - vbuf->sequence = get_q_data(ctx, vb->vb2_queue->type)->sequence++; - vb2_buffer_done(vb, VB2_BUF_STATE_DONE); - ctx->is_draining = false; - ctx->has_stopped = true; - ctx->next_is_last = false; - v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event); - return; - } + for (i = 0; i < vb->num_planes; i++) + vb->planes[i].bytesused = 0; + + vbuf->field = V4L2_FIELD_NONE; + vbuf->sequence = + get_q_data(ctx, vb->vb2_queue->type)->sequence++; + + v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); + v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event); + return; } /* buf_queue handles only the first source change event */ @@ -1609,8 +1561,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, chroma_div = info->width_div * info->height_div; q_data->sequence = 0; - if (V4L2_TYPE_IS_OUTPUT(q->type)) - ctx->last_src_buf = NULL; + v4l2_m2m_start_streaming(ctx->fh.m2m_ctx, q); state->gop_cnt = 0; @@ -1689,29 +1640,12 @@ static void vicodec_stop_streaming(struct vb2_queue *q) vicodec_return_bufs(q, VB2_BUF_STATE_ERROR); - if (V4L2_TYPE_IS_OUTPUT(q->type)) { - if (ctx->is_draining) { - struct vb2_v4l2_buffer *next_dst_buf; - - spin_lock(ctx->lock); - ctx->last_src_buf = NULL; - next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - if (!next_dst_buf) { - ctx->next_is_last = true; - } else { - next_dst_buf->flags |= V4L2_BUF_FLAG_LAST; - vb2_buffer_done(&next_dst_buf->vb2_buf, VB2_BUF_STATE_DONE); - ctx->is_draining = false; - ctx->has_stopped = true; - v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event); - } - spin_unlock(ctx->lock); - } - } else { - ctx->is_draining = false; - ctx->has_stopped = false; - ctx->next_is_last = false; - } + v4l2_m2m_stop_streaming(ctx->fh.m2m_ctx, q); + + if (V4L2_TYPE_IS_OUTPUT(q->type) && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) + v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event); + if (!ctx->is_enc && V4L2_TYPE_IS_OUTPUT(q->type)) ctx->first_source_change_sent = false;