From patchwork Mon Mar 16 15:26:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210605 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FFF7C18E5B for ; Mon, 16 Mar 2020 15:27:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2454B20663 for ; Mon, 16 Mar 2020 15:27:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731853AbgCPP06 (ORCPT ); Mon, 16 Mar 2020 11:26:58 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:34989 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731713AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lE-GK; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-000551-IR; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 04/18] media: allegro: remove unknown39 field from create_channel Date: Mon, 16 Mar 2020 16:26:24 +0100 Message-Id: <20200316152638.19457-5-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The subframe_latency and lda_control_mode fields directly follow freq_golden_ref field and there is no unknown field in between. The unknown field it at the end of the message. Reorder the fields accordingly. This further allows to drop the hard coded value from the lda_control_mode field and set the mode to 0. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: None --- drivers/staging/media/allegro-dvt/allegro-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index 6e3f28e637af..d67f84bf38d3 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -397,10 +397,9 @@ struct mcu_msg_create_channel { u8 num_b; u8 freq_golden_ref; - u32 unknown39; - u32 subframe_latency; u32 lda_control_mode; + u32 unknown41; } __attribute__ ((__packed__)); struct mcu_msg_create_channel_response { @@ -1121,7 +1120,6 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev, msg.gdr_mode = 0x00000000; msg.gop_length = channel->gop_size; msg.subframe_latency = 0x00000000; - msg.lda_control_mode = 0x700d0000; allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg)); allegro_mcu_interrupt(dev); From patchwork Mon Mar 16 15:26:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210610 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5831BC18E5B for ; Mon, 16 Mar 2020 15:26:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 39CEA2051A for ; Mon, 16 Mar 2020 15:26:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731816AbgCPP0t (ORCPT ); Mon, 16 Mar 2020 11:26:49 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:48135 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731658AbgCPP0o (ORCPT ); Mon, 16 Mar 2020 11:26:44 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lG-Iz; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-000557-JM; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 06/18] media: allegro: fix calculation of CPB size Date: Mon, 16 Mar 2020 16:26:26 +0100 Message-Id: <20200316152638.19457-7-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The cpb_size is given in kilobytes, but the bitrate is given in bits per second. Therefore, the calculation of the initial removal delay and the cpb size for the firmware were wrong. Convert the bitrate to kilobytes before calculating the cpb size in 90 kHz units for sending it to the firmware. Also reuse the result for the initial removal delay, to make it obvious that we are setting the initial removal delay to the maximum value. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - Add separate function for calculating CPB for mcu --- .../staging/media/allegro-dvt/allegro-core.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index cbe79bc216fd..87592419ec84 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -5,6 +5,7 @@ * Allegro DVT video encoder driver */ +#include #include #include #include @@ -1053,6 +1054,22 @@ v4l2_bitrate_mode_to_mcu_mode(enum v4l2_mpeg_video_bitrate_mode mode) } } +static u32 v4l2_cpb_size_to_mcu(unsigned int cpb_size, unsigned int bitrate) +{ + unsigned int cpb_size_kbit; + unsigned int bitrate_kbps; + + /* + * The mcu expects the CPB size in units of a 90 kHz clock, but the + * channel follows the V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE and stores + * the CPB size in kilobytes. + */ + cpb_size_kbit = cpb_size * BITS_PER_BYTE; + bitrate_kbps = bitrate / 1000; + + return (cpb_size_kbit * 90000) / bitrate_kbps; +} + static int allegro_mcu_send_create_channel(struct allegro_dev *dev, struct allegro_channel *channel) { @@ -1094,12 +1111,10 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev, msg.rate_control_mode = v4l2_bitrate_mode_to_mcu_mode(channel->bitrate_mode); + msg.cpb_size = v4l2_cpb_size_to_mcu(channel->cpb_size, + channel->bitrate_peak); /* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */ - msg.initial_rem_delay = - ((channel->cpb_size * 1000) / channel->bitrate_peak) * 90000; - /* Encoder expects cpb_size in units of a 90 kHz clock. */ - msg.cpb_size = - ((channel->cpb_size * 1000) / channel->bitrate_peak) * 90000; + msg.initial_rem_delay = msg.cpb_size; msg.framerate = 25; msg.clk_ratio = 1000; msg.target_bitrate = channel->bitrate; From patchwork Mon Mar 16 15:26:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC164C3F2CE for ; Mon, 16 Mar 2020 15:26:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CD1B120663 for ; Mon, 16 Mar 2020 15:26:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731800AbgCPP0o (ORCPT ); Mon, 16 Mar 2020 11:26:44 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:56901 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731762AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lI-Nk; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055D-La; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 08/18] media: allegro: extract mcu and codec address calculation Date: Mon, 16 Mar 2020 16:26:28 +0100 Message-Id: <20200316152638.19457-9-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The mcu and the codec use 32 bit addresses which are sent via the firmware messages. Add helper functions for this address calculation to make it obvious which address is used in the message. As the mcu and the codec have a limited address space, print warnings if the addresses are outside the respective address space. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: None --- .../staging/media/allegro-dvt/allegro-core.c | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index de50405ba907..6c2237d4a674 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -532,6 +532,29 @@ union mcu_msg_response { struct mcu_msg_encode_frame_response encode_frame; }; +static inline u32 to_mcu_addr(struct allegro_dev *dev, dma_addr_t phys) +{ + if (upper_32_bits(phys) || (lower_32_bits(phys) & MCU_CACHE_OFFSET)) + v4l2_warn(&dev->v4l2_dev, + "address %pad is outside mcu window\n", &phys); + + return lower_32_bits(phys) | MCU_CACHE_OFFSET; +} + +static inline u32 to_mcu_size(struct allegro_dev *dev, size_t size) +{ + return lower_32_bits(size); +} + +static inline u32 to_codec_addr(struct allegro_dev *dev, dma_addr_t phys) +{ + if (upper_32_bits(phys)) + v4l2_warn(&dev->v4l2_dev, + "address %pad cannot be used by codec\n", &phys); + + return lower_32_bits(phys); +} + /* Helper functions for channel and user operations */ static unsigned long allegro_next_user_id(struct allegro_dev *dev) @@ -947,8 +970,8 @@ static void allegro_mcu_send_init(struct allegro_dev *dev, msg.header.type = MCU_MSG_TYPE_INIT; msg.header.length = sizeof(msg) - sizeof(msg.header); - msg.suballoc_dma = lower_32_bits(suballoc_dma) | MCU_CACHE_OFFSET; - msg.suballoc_size = suballoc_size; + msg.suballoc_dma = to_mcu_addr(dev, suballoc_dma); + msg.suballoc_size = to_mcu_size(dev, suballoc_size); /* disable L2 cache */ msg.l2_cache[0] = -1; @@ -1173,8 +1196,8 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev, msg.header.length = sizeof(msg) - sizeof(msg.header); msg.channel_id = channel->mcu_channel_id; - msg.dma_addr = paddr; - msg.mcu_addr = paddr | MCU_CACHE_OFFSET; + msg.dma_addr = to_codec_addr(dev, paddr); + msg.mcu_addr = to_mcu_addr(dev, paddr); msg.size = size; msg.offset = ENCODER_STREAM_OFFSET; msg.stream_id = 0; /* copied to mcu_msg_encode_frame_response */ @@ -1201,11 +1224,11 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev, msg.pps_qp = 26; /* qp are relative to 26 */ msg.user_param = 0; /* copied to mcu_msg_encode_frame_response */ msg.src_handle = 0; /* copied to mcu_msg_encode_frame_response */ - msg.src_y = src_y; - msg.src_uv = src_uv; + msg.src_y = to_codec_addr(dev, src_y); + msg.src_uv = to_codec_addr(dev, src_uv); msg.stride = channel->stride; msg.ep2 = 0x0; - msg.ep2_v = msg.ep2 | MCU_CACHE_OFFSET; + msg.ep2_v = to_mcu_addr(dev, msg.ep2); allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg)); allegro_mcu_interrupt(dev); @@ -1264,10 +1287,9 @@ static int allegro_mcu_push_buffer_internal(struct allegro_channel *channel, buffer = msg->buffer; list_for_each_entry(al_buffer, list, head) { - buffer->dma_addr = lower_32_bits(al_buffer->paddr); - buffer->mcu_addr = - lower_32_bits(al_buffer->paddr) | MCU_CACHE_OFFSET; - buffer->size = al_buffer->size; + buffer->dma_addr = to_codec_addr(dev, al_buffer->paddr); + buffer->mcu_addr = to_mcu_addr(dev, al_buffer->paddr); + buffer->size = to_mcu_size(dev, al_buffer->size); buffer++; } From patchwork Mon Mar 16 15:26:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A6DDC4CECE for ; Mon, 16 Mar 2020 15:26:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DE36E2051A for ; Mon, 16 Mar 2020 15:26:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731797AbgCPP0o (ORCPT ); Mon, 16 Mar 2020 11:26:44 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:42799 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731698AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lJ-OX; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055G-Mq; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 09/18] media: allegro: warn if response message has an unexpected size Date: Mon, 16 Mar 2020 16:26:29 +0100 Message-Id: <20200316152638.19457-10-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The driver uses structs to parse the responses from the VCU and expects a certain size of the responses. However, the size and format of the mails is not stable across firmware versions. Therefore, print a warning if the size does not match the expected size to warn the user that strange things might happen. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - Fix checkpatch warnings about lines over 80 characters --- drivers/staging/media/allegro-dvt/allegro-core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index 6c2237d4a674..2392867b4270 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -1711,6 +1711,12 @@ allegro_handle_create_channel(struct allegro_dev *dev, struct allegro_channel *channel; int err = 0; + if (msg->header.length != sizeof(*msg) - sizeof(msg->header)) + v4l2_warn(&dev->v4l2_dev, + "received message has %d bytes, but expected %zu\n", + msg->header.length, + sizeof(*msg) - sizeof(msg->header)); + channel = allegro_find_channel_by_user_id(dev, msg->user_id); if (IS_ERR(channel)) { v4l2_warn(&dev->v4l2_dev, @@ -1804,6 +1810,12 @@ allegro_handle_encode_frame(struct allegro_dev *dev, { struct allegro_channel *channel; + if (msg->header.length != sizeof(*msg) - sizeof(msg->header)) + v4l2_warn(&dev->v4l2_dev, + "received message has %d bytes, but expected %zu\n", + msg->header.length, + sizeof(*msg) - sizeof(msg->header)); + channel = allegro_find_channel_by_channel_id(dev, msg->channel_id); if (IS_ERR(channel)) { v4l2_err(&dev->v4l2_dev, From patchwork Mon Mar 16 15:26:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3545CC5ACBF for ; Mon, 16 Mar 2020 15:26:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0F02920674 for ; Mon, 16 Mar 2020 15:26:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731819AbgCPP0v (ORCPT ); Mon, 16 Mar 2020 11:26:51 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:58555 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731778AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lK-QP; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055J-NY; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 10/18] media: allegro: skip filler data if possible Date: Mon, 16 Mar 2020 16:26:30 +0100 Message-Id: <20200316152638.19457-11-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The driver instructs the firmware to leave some space space in front of the coded frame data for SPS/PPS data. If the driver receives an IDR, it writes the SPS/PPS into that free space and fills the rest with filler data. However, if there is no additional data, the driver can use the plane offset to skip this space instead of adding filler data. As the size of the SPS/PPS is only available after writing it, keep the filler data between the SPS/PPS and the coded frame data. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - Fix indentation of messages --- .../staging/media/allegro-dvt/allegro-core.c | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index 2392867b4270..4a87647749f3 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -1652,17 +1652,22 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel, channel->mcu_channel_id, len); } - len = nal_h264_write_filler(&dev->plat_dev->dev, curr, free); - if (len < 0) { - v4l2_err(&dev->v4l2_dev, - "failed to write %zd filler data\n", free); - goto err; + if (msg->slice_type != AL_ENC_SLICE_TYPE_I && !msg->is_idr) { + dst_buf->vb2_buf.planes[0].data_offset = free; + free = 0; + } else { + len = nal_h264_write_filler(&dev->plat_dev->dev, curr, free); + if (len < 0) { + v4l2_err(&dev->v4l2_dev, + "failed to write %zd filler data\n", free); + goto err; + } + curr += len; + free -= len; + v4l2_dbg(2, debug, &dev->v4l2_dev, + "channel %d: wrote %zd bytes filler nal unit\n", + channel->mcu_channel_id, len); } - curr += len; - free -= len; - v4l2_dbg(2, debug, &dev->v4l2_dev, - "channel %d: wrote %zd bytes filler nal unit\n", - channel->mcu_channel_id, len); if (free != 0) { v4l2_err(&dev->v4l2_dev, From patchwork Mon Mar 16 15:26:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210606 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE74BC2BB1D for ; Mon, 16 Mar 2020 15:26:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 986F42051A for ; Mon, 16 Mar 2020 15:26:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731832AbgCPP0x (ORCPT ); Mon, 16 Mar 2020 11:26:53 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:59851 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731763AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lL-Pm; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055M-O8; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 11/18] media: allegro: make frame rate configurable Date: Mon, 16 Mar 2020 16:26:31 +0100 Message-Id: <20200316152638.19457-12-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The allegro dvt codec adjust the encoding speed according to a configured frame rate. Furthermore, the frame rate is written into the coded stream. Ensure that the coded video data has the correct frame rate by implementing s_parm for setting the frame rate from user space. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - Fix indentation - Fix trailing semicolon and complex value in macro --- .../staging/media/allegro-dvt/allegro-core.c | 63 +++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index 4a87647749f3..be4cc957439e 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,8 @@ #define ALLEGRO_HEIGHT_DEFAULT 1080 #define ALLEGRO_HEIGHT_MAX 2160 +#define ALLEGRO_FRAMERATE_DEFAULT ((struct v4l2_fract) { 30, 1 }) + #define ALLEGRO_GOP_SIZE_DEFAULT 25 #define ALLEGRO_GOP_SIZE_MAX 1000 @@ -177,6 +180,7 @@ struct allegro_channel { unsigned int width; unsigned int height; unsigned int stride; + struct v4l2_fract framerate; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; @@ -1138,8 +1142,9 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev, channel->bitrate_peak); /* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */ msg.initial_rem_delay = msg.cpb_size; - msg.framerate = 25; - msg.clk_ratio = 1000; + msg.framerate = DIV_ROUND_UP(channel->framerate.numerator, + channel->framerate.denominator); + msg.clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000; msg.target_bitrate = channel->bitrate; msg.max_bitrate = channel->bitrate_peak; msg.initial_qp = 25; @@ -1448,9 +1453,11 @@ static ssize_t allegro_h264_write_sps(struct allegro_channel *channel, sps->vui.chroma_loc_info_present_flag = 1; sps->vui.chroma_sample_loc_type_top_field = 0; sps->vui.chroma_sample_loc_type_bottom_field = 0; + sps->vui.timing_info_present_flag = 1; - sps->vui.num_units_in_tick = 1; - sps->vui.time_scale = 50; + sps->vui.num_units_in_tick = channel->framerate.denominator; + sps->vui.time_scale = 2 * channel->framerate.numerator; + sps->vui.fixed_frame_rate_flag = 1; sps->vui.nal_hrd_parameters_present_flag = 0; sps->vui.vcl_hrd_parameters_present_flag = 1; @@ -2117,7 +2124,9 @@ static int allegro_create_channel(struct allegro_channel *channel) v4l2_dbg(1, debug, &dev->v4l2_dev, "user %d: creating channel (%4.4s, %dx%d@%d)\n", channel->user_id, - (char *)&channel->codec, channel->width, channel->height, 25); + (char *)&channel->codec, channel->width, channel->height, + DIV_ROUND_UP(channel->framerate.numerator, + channel->framerate.denominator)); min_level = select_minimum_h264_level(channel->width, channel->height); if (channel->level < min_level) { @@ -2163,6 +2172,7 @@ static void allegro_set_default_params(struct allegro_channel *channel) channel->width = ALLEGRO_WIDTH_DEFAULT; channel->height = ALLEGRO_HEIGHT_DEFAULT; channel->stride = round_up(channel->width, 32); + channel->framerate = ALLEGRO_FRAMERATE_DEFAULT; channel->colorspace = V4L2_COLORSPACE_REC709; channel->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; @@ -2769,6 +2779,46 @@ static int allegro_ioctl_streamon(struct file *file, void *priv, return v4l2_m2m_streamon(file, fh->m2m_ctx, type); } +static int allegro_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + struct allegro_channel *channel = fh_to_channel(fh); + struct v4l2_fract *timeperframe; + + if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; + timeperframe = &a->parm.output.timeperframe; + timeperframe->numerator = channel->framerate.denominator; + timeperframe->denominator = channel->framerate.numerator; + + return 0; +} + +static int allegro_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + struct allegro_channel *channel = fh_to_channel(fh); + struct v4l2_fract *timeperframe; + int div; + + if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; + timeperframe = &a->parm.output.timeperframe; + + if (timeperframe->numerator == 0 || timeperframe->denominator == 0) + return allegro_g_parm(file, fh, a); + + div = gcd(timeperframe->denominator, timeperframe->numerator); + channel->framerate.numerator = timeperframe->denominator / div; + channel->framerate.denominator = timeperframe->numerator / div; + + return 0; +} + static int allegro_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) { @@ -2807,6 +2857,9 @@ static const struct v4l2_ioctl_ops allegro_ioctl_ops = { .vidioc_encoder_cmd = allegro_encoder_cmd, .vidioc_enum_framesizes = allegro_enum_framesizes, + .vidioc_g_parm = allegro_g_parm, + .vidioc_s_parm = allegro_s_parm, + .vidioc_subscribe_event = allegro_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; From patchwork Mon Mar 16 15:26:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210608 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54B8CC5ACC0 for ; Mon, 16 Mar 2020 15:26:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 36DDF20736 for ; Mon, 16 Mar 2020 15:26:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731702AbgCPP0u (ORCPT ); Mon, 16 Mar 2020 11:26:50 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:34929 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731776AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrdZ-0000lP-Sv; Mon, 16 Mar 2020 16:26:41 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055V-RZ; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 14/18] media: allegro: handle dependency of bitrate and bitrate_peak Date: Mon, 16 Mar 2020 16:26:34 +0100 Message-Id: <20200316152638.19457-15-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The peak bitrate must not be smaller than the configured bitrate. Update the other control whenever one of the controls changes to reflect this dependency. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - Use control cluster --- .../staging/media/allegro-dvt/allegro-core.c | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index 6a492de52987..820fb21ab0f1 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -211,9 +211,11 @@ struct allegro_channel { struct v4l2_ctrl *mpeg_video_h264_p_frame_qp; struct v4l2_ctrl *mpeg_video_h264_b_frame_qp; struct v4l2_ctrl *mpeg_video_frame_rc_enable; - struct v4l2_ctrl *mpeg_video_bitrate_mode; - struct v4l2_ctrl *mpeg_video_bitrate; - struct v4l2_ctrl *mpeg_video_bitrate_peak; + struct { /* video bitrate mode control cluster */ + struct v4l2_ctrl *mpeg_video_bitrate_mode; + struct v4l2_ctrl *mpeg_video_bitrate; + struct v4l2_ctrl *mpeg_video_bitrate_peak; + }; struct v4l2_ctrl *mpeg_video_cpb_size; struct v4l2_ctrl *mpeg_video_gop_size; @@ -2404,6 +2406,34 @@ static int allegro_clamp_qp(struct allegro_channel *channel, return allegro_clamp_qp(channel, next_ctrl); } +static int allegro_clamp_bitrate(struct allegro_channel *channel, + struct v4l2_ctrl *ctrl) +{ + struct v4l2_ctrl *ctrl_bitrate = channel->mpeg_video_bitrate; + struct v4l2_ctrl *ctrl_bitrate_peak = channel->mpeg_video_bitrate_peak; + + if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && + ctrl_bitrate_peak->val < ctrl_bitrate->val) + ctrl_bitrate_peak->val = ctrl_bitrate->val; + + return 0; +} + +static int allegro_try_ctrl(struct v4l2_ctrl *ctrl) +{ + struct allegro_channel *channel = container_of(ctrl->handler, + struct allegro_channel, + ctrl_handler); + + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + allegro_clamp_bitrate(channel, ctrl); + break; + } + + return 0; +} + static int allegro_s_ctrl(struct v4l2_ctrl *ctrl) { struct allegro_channel *channel = container_of(ctrl->handler, @@ -2421,11 +2451,11 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: channel->frame_rc_enable = ctrl->val; break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - channel->bitrate = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - channel->bitrate_peak = ctrl->val; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + channel->bitrate = channel->mpeg_video_bitrate->val; + channel->bitrate_peak = channel->mpeg_video_bitrate_peak->val; + v4l2_ctrl_activate(channel->mpeg_video_bitrate_peak, + ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); break; case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: channel->cpb_size = ctrl->val; @@ -2444,6 +2474,7 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl) } static const struct v4l2_ctrl_ops allegro_ctrl_ops = { + .try_ctrl = allegro_try_ctrl, .s_ctrl = allegro_s_ctrl, }; @@ -2547,6 +2578,8 @@ static int allegro_open(struct file *file) channel->fh.ctrl_handler = handler; + v4l2_ctrl_cluster(3, &channel->mpeg_video_bitrate_mode); + channel->mcu_channel_id = -1; channel->user_id = -1; From patchwork Mon Mar 16 15:26:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210611 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DEFCC5ACC0 for ; Mon, 16 Mar 2020 15:26:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E67F920663 for ; Mon, 16 Mar 2020 15:26:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731814AbgCPP0p (ORCPT ); Mon, 16 Mar 2020 11:26:45 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:40829 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731764AbgCPP0o (ORCPT ); Mon, 16 Mar 2020 11:26:44 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrda-0000lR-0t; Mon, 16 Mar 2020 16:26:42 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055b-St; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 16/18] media: allegro: pass buffers through firmware Date: Mon, 16 Mar 2020 16:26:36 +0100 Message-Id: <20200316152638.19457-17-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org As we know which buffers are processed by the codec from the address in the ENCODE_FRAME response, we can queue multiple buffers in the firmware and retrieve the buffer from the response of the firmware. This enables the firmware to use the internal scheduling the codec and avoids round trips through the driver when fetching the next frame. Remove buffers that have been passed to the firmware from the m2m buffer queue and put them into a shadow queue for tracking the buffer in the driver. When we receive a ENCODE_FRAME response from the firmware, get the buffer from the shadow queue and finish the buffer. Furthermore, it is necessary to finish the job straight after passing the buffer to the firmware to allow the V4L2 framework to send further buffers to the driver. Signed-off-by: Michael Tretter --- Changelog v1 -> v2: - Search buffer in entire shadow buffer queue - Fix error handling if firmware reports wrong buffer handles - Fix warnings about lines longer than 80 characters - Set LAST flag on last buffer instead of last but one buffer --- .../staging/media/allegro-dvt/allegro-core.c | 124 +++++++++++++++--- 1 file changed, 103 insertions(+), 21 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index 45e0d2c2fc44..1554beebea88 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -228,6 +228,11 @@ struct allegro_channel { struct list_head buffers_reference; struct list_head buffers_intermediate; + struct list_head source_shadow_list; + struct list_head stream_shadow_list; + /* protect shadow lists of buffers passed to firmware */ + struct mutex shadow_list_lock; + struct list_head list; struct completion completion; @@ -249,6 +254,14 @@ allegro_get_state(struct allegro_channel *channel) return channel->state; } +struct allegro_m2m_buffer { + struct v4l2_m2m_buffer buf; + struct list_head head; +}; + +#define to_allegro_m2m_buffer(__buf) \ + container_of(__buf, struct allegro_m2m_buffer, buf) + struct fw_info { unsigned int id; unsigned int id_codec; @@ -1567,8 +1580,11 @@ static bool allegro_channel_is_at_eos(struct allegro_channel *channel) break; case ALLEGRO_STATE_DRAIN: case ALLEGRO_STATE_WAIT_FOR_BUFFER: - if (v4l2_m2m_num_src_bufs_ready(channel->fh.m2m_ctx) == 0) + mutex_lock(&channel->shadow_list_lock); + if (v4l2_m2m_num_src_bufs_ready(channel->fh.m2m_ctx) == 0 && + list_empty(&channel->source_shadow_list)) is_at_eos = true; + mutex_unlock(&channel->shadow_list_lock); break; default: break; @@ -1595,6 +1611,41 @@ static void allegro_channel_buf_done(struct allegro_channel *channel, v4l2_m2m_buf_done(buf, state); } +static u64 allegro_put_buffer(struct allegro_channel *channel, + struct list_head *list, + struct vb2_v4l2_buffer *buffer) +{ + struct v4l2_m2m_buffer *b = container_of(buffer, + struct v4l2_m2m_buffer, vb); + struct allegro_m2m_buffer *shadow = to_allegro_m2m_buffer(b); + + mutex_lock(&channel->shadow_list_lock); + list_add_tail(&shadow->head, list); + mutex_unlock(&channel->shadow_list_lock); + + return ptr_to_u64(buffer); +} + +static struct vb2_v4l2_buffer * +allegro_get_buffer(struct allegro_channel *channel, + struct list_head *list, u64 handle) +{ + struct allegro_m2m_buffer *shadow, *tmp; + struct vb2_v4l2_buffer *buffer = NULL; + + mutex_lock(&channel->shadow_list_lock); + list_for_each_entry_safe(shadow, tmp, list, head) { + if (handle == ptr_to_u64(&shadow->buf.vb)) { + buffer = &shadow->buf.vb; + list_del_init(&shadow->head); + break; + } + } + mutex_unlock(&channel->shadow_list_lock); + + return buffer; +} + static void allegro_channel_finish_frame(struct allegro_channel *channel, struct mcu_msg_encode_frame_response *msg) { @@ -1610,17 +1661,22 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel, ssize_t len; ssize_t free; - src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx); - if (ptr_to_u64(src_buf) != msg->src_handle) + src_buf = allegro_get_buffer(channel, &channel->source_shadow_list, + msg->src_handle); + if (!src_buf) v4l2_warn(&dev->v4l2_dev, - "channel %d: invalid source buffer (0x%llx)\n", - channel->mcu_channel_id, msg->src_handle); + "channel %d: invalid source buffer\n", + channel->mcu_channel_id); - dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx); - if (ptr_to_u64(dst_buf) != msg->stream_id) + dst_buf = allegro_get_buffer(channel, &channel->stream_shadow_list, + msg->stream_id); + if (!dst_buf) v4l2_warn(&dev->v4l2_dev, - "channel %d: invalid stream buffer (0x%llx)\n", - channel->mcu_channel_id, msg->stream_id); + "channel %d: invalid stream buffer\n", + channel->mcu_channel_id); + + if (!src_buf || !dst_buf) + goto err; dst_buf->sequence = channel->csequence++; @@ -1744,11 +1800,11 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel, msg->qp, partition->size); err: - v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); + if (src_buf) + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); - allegro_channel_buf_done(channel, dst_buf, state); - - v4l2_m2m_job_finish(dev->m2m_dev, channel->fh.m2m_ctx); + if (dst_buf) + allegro_channel_buf_done(channel, dst_buf, state); } static int allegro_handle_init(struct allegro_dev *dev, @@ -2344,16 +2400,33 @@ static void allegro_stop_streaming(struct vb2_queue *q) struct allegro_channel *channel = vb2_get_drv_priv(q); struct allegro_dev *dev = channel->dev; struct vb2_v4l2_buffer *buffer; + struct allegro_m2m_buffer *shadow, *tmp; v4l2_dbg(2, debug, &dev->v4l2_dev, "%s: stop streaming\n", V4L2_TYPE_IS_OUTPUT(q->type) ? "output" : "capture"); if (V4L2_TYPE_IS_OUTPUT(q->type)) { + mutex_lock(&channel->shadow_list_lock); + list_for_each_entry_safe(shadow, tmp, + &channel->source_shadow_list, head) { + list_del(&shadow->head); + v4l2_m2m_buf_done(&shadow->buf.vb, VB2_BUF_STATE_ERROR); + } + mutex_unlock(&channel->shadow_list_lock); + allegro_set_state(channel, ALLEGRO_STATE_STOPPED); while ((buffer = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx))) v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_ERROR); } else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_lock(&channel->shadow_list_lock); + list_for_each_entry_safe(shadow, tmp, + &channel->stream_shadow_list, head) { + list_del(&shadow->head); + v4l2_m2m_buf_done(&shadow->buf.vb, VB2_BUF_STATE_ERROR); + } + mutex_unlock(&channel->shadow_list_lock); + allegro_destroy_channel(channel); while ((buffer = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx))) v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_ERROR); @@ -2384,7 +2457,7 @@ static int allegro_queue_init(void *priv, src_vq->drv_priv = channel; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->ops = &allegro_queue_ops; - src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->buf_struct_size = sizeof(struct allegro_m2m_buffer); src_vq->lock = &channel->dev->lock; err = vb2_queue_init(src_vq); if (err) @@ -2397,7 +2470,7 @@ static int allegro_queue_init(void *priv, dst_vq->drv_priv = channel; dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->ops = &allegro_queue_ops; - dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->buf_struct_size = sizeof(struct allegro_m2m_buffer); dst_vq->lock = &channel->dev->lock; err = vb2_queue_init(dst_vq); if (err) @@ -2510,6 +2583,9 @@ static int allegro_open(struct file *file) return -ENOMEM; init_completion(&channel->completion); + INIT_LIST_HEAD(&channel->source_shadow_list); + INIT_LIST_HEAD(&channel->stream_shadow_list); + mutex_init(&channel->shadow_list_lock); channel->dev = dev; @@ -3039,20 +3115,26 @@ static void allegro_device_run(void *priv) dma_addr_t src_uv; dma_addr_t dst_addr; unsigned long dst_size; + u64 src_handle; + u64 dst_handle; - dst_buf = v4l2_m2m_next_dst_buf(channel->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx); dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); dst_size = vb2_plane_size(&dst_buf->vb2_buf, 0); + dst_handle = allegro_put_buffer(channel, &channel->stream_shadow_list, + dst_buf); allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, - ptr_to_u64(dst_buf)); + dst_handle); - src_buf = v4l2_m2m_next_src_buf(channel->fh.m2m_ctx); + src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx); src_buf->sequence = channel->osequence++; - src_y = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); src_uv = src_y + (channel->stride * channel->height); - allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv, - ptr_to_u64(src_buf)); + src_handle = allegro_put_buffer(channel, &channel->source_shadow_list, + src_buf); + allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv, src_handle); + + v4l2_m2m_job_finish(dev->m2m_dev, channel->fh.m2m_ctx); } static const struct v4l2_m2m_ops allegro_m2m_ops = { From patchwork Mon Mar 16 15:26:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Tretter X-Patchwork-Id: 210612 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A13F7C2BB1D for ; Mon, 16 Mar 2020 15:26:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7459220736 for ; Mon, 16 Mar 2020 15:26:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731803AbgCPP0o (ORCPT ); Mon, 16 Mar 2020 11:26:44 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:33467 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731770AbgCPP0n (ORCPT ); Mon, 16 Mar 2020 11:26:43 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jDrda-0000lT-1l; Mon, 16 Mar 2020 16:26:42 +0100 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jDrdY-00055h-V1; Mon, 16 Mar 2020 16:26:40 +0100 From: Michael Tretter To: linux-media@vger.kernel.org Cc: hverkuil-cisco@xs4all.nl, kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 18/18] media: allegro: create new struct for channel parameters Date: Mon, 16 Mar 2020 16:26:38 +0100 Message-Id: <20200316152638.19457-19-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200316152638.19457-1-m.tretter@pengutronix.de> References: <20200316152638.19457-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a new struct for the channel parameters that is contained in the CREATE_CHANNEL message. This is in preparation for newer firmwares that pass the channel parameters in a dedicated buffer instead of embedding the parameters into the CREATE_CHANNEL message. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - Fix checkpatch warnings --- .../staging/media/allegro-dvt/allegro-core.c | 134 ++++++++++-------- .../staging/media/allegro-dvt/allegro-mail.h | 10 +- 2 files changed, 80 insertions(+), 64 deletions(-) diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index ed5e9a33b7f9..6bba296dfc40 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -859,80 +859,92 @@ static s16 get_qp_delta(int minuend, int subtrahend) return minuend - subtrahend; } -static int allegro_mcu_send_create_channel(struct allegro_dev *dev, - struct allegro_channel *channel) +static int fill_create_channel_param(struct allegro_channel *channel, + struct create_channel_param *param) { - struct mcu_msg_create_channel msg; int i_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_i_frame_qp); int p_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp); int b_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_b_frame_qp); int bitrate_mode = v4l2_ctrl_g_ctrl(channel->mpeg_video_bitrate_mode); + param->width = channel->width; + param->height = channel->height; + param->format = v4l2_pixelformat_to_mcu_format(channel->pixelformat); + param->colorspace = + v4l2_colorspace_to_mcu_colorspace(channel->colorspace); + param->src_mode = 0x0; + param->profile = v4l2_profile_to_mcu_profile(channel->profile); + param->constraint_set_flags = BIT(1); + param->codec = v4l2_pixelformat_to_mcu_codec(channel->codec); + param->level = v4l2_level_to_mcu_level(channel->level); + param->tier = 0; + param->sps_param = BIT(20) | 0x4a; + param->pps_param = BIT(2); + param->enc_option = AL_OPT_RDO_COST_MODE | AL_OPT_LF_X_TILE | + AL_OPT_LF_X_SLICE | AL_OPT_LF; + param->beta_offset = -1; + param->tc_offset = -1; + param->num_slices = 1; + param->me_range[0] = 8; + param->me_range[1] = 8; + param->me_range[2] = 16; + param->me_range[3] = 16; + param->max_cu_size = ilog2(SIZE_MACROBLOCK); + param->min_cu_size = ilog2(8); + param->max_tu_size = 2; + param->min_tu_size = 2; + param->max_transfo_depth_intra = 1; + param->max_transfo_depth_inter = 1; + + param->prefetch_auto = 0; + param->prefetch_mem_offset = 0; + param->prefetch_mem_size = 0; + + param->rate_control_mode = channel->frame_rc_enable ? + v4l2_bitrate_mode_to_mcu_mode(bitrate_mode) : 0; + + param->cpb_size = v4l2_cpb_size_to_mcu(channel->cpb_size, + channel->bitrate_peak); + /* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */ + param->initial_rem_delay = param->cpb_size; + param->framerate = DIV_ROUND_UP(channel->framerate.numerator, + channel->framerate.denominator); + param->clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000; + param->target_bitrate = channel->bitrate; + param->max_bitrate = channel->bitrate_peak; + param->initial_qp = i_frame_qp; + param->min_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_min_qp); + param->max_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_max_qp); + param->ip_delta = get_qp_delta(i_frame_qp, p_frame_qp); + param->pb_delta = get_qp_delta(p_frame_qp, b_frame_qp); + param->golden_ref = 0; + param->golden_delta = 2; + param->golden_ref_frequency = 10; + param->rate_control_option = 0x00000000; + + param->gop_ctrl_mode = 0x00000000; + param->freq_idr = channel->gop_size; + param->freq_lt = 0; + param->gdr_mode = 0x00000000; + param->gop_length = channel->gop_size; + param->subframe_latency = 0x00000000; + + return 0; +} + +static int allegro_mcu_send_create_channel(struct allegro_dev *dev, + struct allegro_channel *channel) +{ + struct mcu_msg_create_channel msg; + memset(&msg, 0, sizeof(msg)); msg.header.type = MCU_MSG_TYPE_CREATE_CHANNEL; msg.header.length = sizeof(msg) - sizeof(msg.header); msg.user_id = channel->user_id; - msg.width = channel->width; - msg.height = channel->height; - msg.format = v4l2_pixelformat_to_mcu_format(channel->pixelformat); - msg.colorspace = v4l2_colorspace_to_mcu_colorspace(channel->colorspace); - msg.src_mode = 0x0; - msg.profile = v4l2_profile_to_mcu_profile(channel->profile); - msg.constraint_set_flags = BIT(1); - msg.codec = v4l2_pixelformat_to_mcu_codec(channel->codec); - msg.level = v4l2_level_to_mcu_level(channel->level); - msg.tier = 0; - msg.sps_param = BIT(20) | 0x4a; - msg.pps_param = BIT(2); - msg.enc_option = AL_OPT_RDO_COST_MODE | AL_OPT_LF_X_TILE | - AL_OPT_LF_X_SLICE | AL_OPT_LF; - msg.beta_offset = -1; - msg.tc_offset = -1; - msg.num_slices = 1; - msg.me_range[0] = 8; - msg.me_range[1] = 8; - msg.me_range[2] = 16; - msg.me_range[3] = 16; - msg.max_cu_size = ilog2(SIZE_MACROBLOCK); - msg.min_cu_size = ilog2(8); - msg.max_tu_size = 2; - msg.min_tu_size = 2; - msg.max_transfo_depth_intra = 1; - msg.max_transfo_depth_inter = 1; - - if (channel->frame_rc_enable) - msg.rate_control_mode = - v4l2_bitrate_mode_to_mcu_mode(bitrate_mode); - else - msg.rate_control_mode = 0; - msg.cpb_size = v4l2_cpb_size_to_mcu(channel->cpb_size, - channel->bitrate_peak); - /* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */ - msg.initial_rem_delay = msg.cpb_size; - msg.framerate = DIV_ROUND_UP(channel->framerate.numerator, - channel->framerate.denominator); - msg.clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000; - msg.target_bitrate = channel->bitrate; - msg.max_bitrate = channel->bitrate_peak; - msg.initial_qp = i_frame_qp; - msg.min_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_min_qp); - msg.max_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_max_qp); - msg.ip_delta = get_qp_delta(i_frame_qp, p_frame_qp); - msg.pb_delta = get_qp_delta(p_frame_qp, b_frame_qp); - msg.golden_ref = 0; - msg.golden_delta = 2; - msg.golden_ref_frequency = 10; - msg.rate_control_option = 0x00000000; - - msg.gop_ctrl_mode = 0x00000000; - msg.freq_idr = channel->gop_size; - msg.freq_lt = 0; - msg.gdr_mode = 0x00000000; - msg.gop_length = channel->gop_size; - msg.subframe_latency = 0x00000000; + fill_create_channel_param(channel, &msg.param); allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg)); allegro_mcu_interrupt(dev); diff --git a/drivers/staging/media/allegro-dvt/allegro-mail.h b/drivers/staging/media/allegro-dvt/allegro-mail.h index 4a50c595720a..1fd36f65be78 100644 --- a/drivers/staging/media/allegro-dvt/allegro-mail.h +++ b/drivers/staging/media/allegro-dvt/allegro-mail.h @@ -40,9 +40,7 @@ struct mcu_msg_init_response { u32 reserved0; } __attribute__ ((__packed__)); -struct mcu_msg_create_channel { - struct mcu_msg_header header; - u32 user_id; +struct create_channel_param { u16 width; u16 height; u32 format; @@ -131,6 +129,12 @@ struct mcu_msg_create_channel { u32 unknown41; } __attribute__ ((__packed__)); +struct mcu_msg_create_channel { + struct mcu_msg_header header; + u32 user_id; + struct create_channel_param param; +} __attribute__ ((__packed__)); + struct mcu_msg_create_channel_response { struct mcu_msg_header header; u32 channel_id;