* [PATCH 00/18] media: allegro: fixes and new features
@ 2020-02-17 15:13 Michael Tretter
2020-02-17 15:13 ` [PATCH 01/18] media: allegro: print message on mcu error Michael Tretter
` (18 more replies)
0 siblings, 19 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
Hello,
these are a several patches for the allegro-dvt driver that have piled up over
the last few month while I was improving my understanding of the codec.
Patches 1 to 9 fix errors in the interaction with the mcu. This includes
better interpretation of return values from the firmware, wrong fields in the
mails, wrong values in the fields and an error when resetting the mcu.
Patches 10 to 14 wire up more controls and allow user space applications to
control the framerate and the quality of the codec.
Patches 15 and 16 enable the firmware to take care of the buffer scheduling
and allow more parallelism inside the firmware. Please have a close look at
patch 16, because it changes the behavior of the driver to finish the m2m_job
before the driver returns the v4l2_buffers.
Patches 17 and 18 start work to restructure how to create the mails that are
sent to the firmware, because different firmware versions expect different
mail formats and, thus, I need additional code to generate mails if I want to
support different firmware versions.
This is the v4l-compliance test result:
v4l2-compliance SHA: b62d322d4401e6b6e5cbd78cedad9eb69dac1324, 64 bits, 64-bit time_t
Compliance test for allegro device /dev/video3:
Driver Info:
Driver name : allegro
Card type : Allegro DVT Video Encoder
Bus info : platform:a0009000.video-codec
Driver version : 5.6.0
Capabilities : 0x84208000
Video Memory-to-Memory
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04208000
Video Memory-to-Memory
Streaming
Extended Pix Format
Detected Stateful Encoder
Required ioctls:
test VIDIOC_QUERYCAP: OK
Allow for multiple opens:
test second /dev/video3 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
test invalid ioctls: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 16 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
warn: v4l2-test-formats.cpp(1329): S_PARM is supported for buftype 2, but not for ENUM_FRAMEINTERVALS
test VIDIOC_G/S_PARM: OK
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)
Test input 0:
Streaming ioctls:
test read/write: OK (Not Supported)
test blocking wait: OK
Video Capture: Captured 59 buffers
test MMAP (select): OK
Video Capture: Captured 59 buffers
test MMAP (epoll): OK
test USERPTR (select): OK (Not Supported)
test DMABUF: Cannot test, specify --expbuf-device
Total for allegro device /dev/video3: 50, Succeeded: 50, Failed: 0, Warnings: 1
Michael
Michael Tretter (18):
media: allegro: print message on mcu error
media: allegro: fail encoding only on actual errors
media: allegro: fix type of gop_length in channel_create message
media: allegro: remove unknown39 field from create_channel
media: allegro: start a GOP with an IDR frame
media: allegro: fix calculation of CPB size
media: allegro: fix reset if WAKEUP has not been set properly
media: allegro: extract mcu and codec address calculation
media: allegro: warn if response message has an unexpected size
media: allegro: skip filler data if possible
media: allegro: make frame rate configurable
media: allegro: make QP configurable
media: allegro: read bitrate mode directly from control
media: allegro: handle dependency of bitrate and bitrate_peak
media: allegro: verify source and destination buffer in VCU response
media: allegro: pass buffers through firmware
media: allegro: move mail definitions to separate file
media: allegro: create new struct for channel parameters
drivers/staging/media/allegro-dvt/Makefile | 2 +-
.../staging/media/allegro-dvt/allegro-core.c | 808 ++++++++++--------
.../staging/media/allegro-dvt/allegro-mail.c | 37 +
.../staging/media/allegro-dvt/allegro-mail.h | 267 ++++++
4 files changed, 738 insertions(+), 376 deletions(-)
create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.c
create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.h
--
2.20.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/18] media: allegro: print message on mcu error
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 02/18] media: allegro: fail encoding only on actual errors Michael Tretter
` (17 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
The codec firmware uses error codes to report errors during the
configuration of a channel or while encoding a frame. Translate them
into human readable strings for debugging.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
.../staging/media/allegro-dvt/allegro-core.c | 62 +++++++++++++++++--
1 file changed, 58 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 3be41698df4c..c400559637e9 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -572,6 +572,56 @@ static inline bool channel_exists(struct allegro_channel *channel)
return channel->mcu_channel_id != -1;
}
+#define AL_ERROR 0x80
+#define AL_ERR_INIT_FAILED 0x81
+#define AL_ERR_NO_FRAME_DECODED 0x82
+#define AL_ERR_RESOLUTION_CHANGE 0x85
+#define AL_ERR_NO_MEMORY 0x87
+#define AL_ERR_STREAM_OVERFLOW 0x88
+#define AL_ERR_TOO_MANY_SLICES 0x89
+#define AL_ERR_BUF_NOT_READY 0x8c
+#define AL_ERR_NO_CHANNEL_AVAILABLE 0x8d
+#define AL_ERR_RESOURCE_UNAVAILABLE 0x8e
+#define AL_ERR_NOT_ENOUGH_CORES 0x8f
+#define AL_ERR_REQUEST_MALFORMED 0x90
+#define AL_ERR_CMD_NOT_ALLOWED 0x91
+#define AL_ERR_INVALID_CMD_VALUE 0x92
+
+static inline const char *allegro_err_to_string(unsigned int err)
+{
+ switch (err) {
+ case AL_ERR_INIT_FAILED:
+ return "initialization failed";
+ case AL_ERR_NO_FRAME_DECODED:
+ return "no frame decoded";
+ case AL_ERR_RESOLUTION_CHANGE:
+ return "resolution change";
+ case AL_ERR_NO_MEMORY:
+ return "out of memory";
+ case AL_ERR_STREAM_OVERFLOW:
+ return "stream buffer overflow";
+ case AL_ERR_TOO_MANY_SLICES:
+ return "too many slices";
+ case AL_ERR_BUF_NOT_READY:
+ return "buffer not ready";
+ case AL_ERR_NO_CHANNEL_AVAILABLE:
+ return "no channel available";
+ case AL_ERR_RESOURCE_UNAVAILABLE:
+ return "resource unavailable";
+ case AL_ERR_NOT_ENOUGH_CORES:
+ return "not enough cores";
+ case AL_ERR_REQUEST_MALFORMED:
+ return "request malformed";
+ case AL_ERR_CMD_NOT_ALLOWED:
+ return "command not allowed";
+ case AL_ERR_INVALID_CMD_VALUE:
+ return "invalid command value";
+ case AL_ERROR:
+ default:
+ return "unknown error";
+ }
+}
+
static unsigned int estimate_stream_size(unsigned int width,
unsigned int height)
{
@@ -1488,8 +1538,10 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
if (msg->error_code) {
v4l2_err(&dev->v4l2_dev,
- "channel %d: error while encoding frame: %x\n",
- channel->mcu_channel_id, msg->error_code);
+ "channel %d: failed to encode frame: %s (%x)\n",
+ channel->mcu_channel_id,
+ allegro_err_to_string(msg->error_code),
+ msg->error_code);
goto err;
}
@@ -1632,8 +1684,10 @@ allegro_handle_create_channel(struct allegro_dev *dev,
if (msg->error_code) {
v4l2_err(&dev->v4l2_dev,
- "user %d: mcu failed to create channel: error %x\n",
- channel->user_id, msg->error_code);
+ "user %d: mcu failed to create channel: %s (%x)\n",
+ channel->user_id,
+ allegro_err_to_string(msg->error_code),
+ msg->error_code);
err = -EIO;
goto out;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 02/18] media: allegro: fail encoding only on actual errors
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
2020-02-17 15:13 ` [PATCH 01/18] media: allegro: print message on mcu error Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 03/18] media: allegro: fix type of gop_length in channel_create message Michael Tretter
` (16 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
Only negative values are actual errors and positive values are used for
warnings. Warnings should not fail the encoding process.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index c400559637e9..0aa88e489f13 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -1536,7 +1536,7 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
dst_buf->sequence = channel->csequence++;
- if (msg->error_code) {
+ if (msg->error_code & AL_ERROR) {
v4l2_err(&dev->v4l2_dev,
"channel %d: failed to encode frame: %s (%x)\n",
channel->mcu_channel_id,
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 03/18] media: allegro: fix type of gop_length in channel_create message
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
2020-02-17 15:13 ` [PATCH 01/18] media: allegro: print message on mcu error Michael Tretter
2020-02-17 15:13 ` [PATCH 02/18] media: allegro: fail encoding only on actual errors Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 04/18] media: allegro: remove unknown39 field from create_channel Michael Tretter
` (15 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
The gop_length field is actually only u16 and there are two more u8
fields in the message:
- the number of consecutive b-frames
- frequency of golden frames
Fix the message and thus fix the configuration of the GOP length.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 0aa88e489f13..1ff58683e782 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -393,7 +393,10 @@ struct mcu_msg_create_channel {
u32 freq_ird;
u32 freq_lt;
u32 gdr_mode;
- u32 gop_length;
+ u16 gop_length;
+ u8 num_b;
+ u8 freq_golden_ref;
+
u32 unknown39;
u32 subframe_latency;
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 04/18] media: allegro: remove unknown39 field from create_channel
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (2 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 03/18] media: allegro: fix type of gop_length in channel_create message Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 05/18] media: allegro: start a GOP with an IDR frame Michael Tretter
` (14 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
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 1ff58683e782..c93b3ba39391 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);
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 05/18] media: allegro: start a GOP with an IDR frame
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (3 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 04/18] media: allegro: remove unknown39 field from create_channel Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 06/18] media: allegro: fix calculation of CPB size Michael Tretter
` (13 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
When creating a channel, freq_idr defines the number of frames between
IDR frames in the coded stream. In V4L2, the period between IDR frames
shall be taken from the GOP_SIZE control.
Set the IDR frame frequency equal to the GOP size and let every GOP
start with an IDR frame.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index c93b3ba39391..b04ded8ae06b 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -390,7 +390,7 @@ struct mcu_msg_create_channel {
/* gop param */
u32 gop_ctrl_mode;
- u32 freq_ird;
+ u32 freq_idr;
u32 freq_lt;
u32 gdr_mode;
u16 gop_length;
@@ -1115,7 +1115,7 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
msg.rate_control_option = 0x00000000;
msg.gop_ctrl_mode = 0x00000000;
- msg.freq_ird = 0x7fffffff;
+ msg.freq_idr = channel->gop_size;
msg.freq_lt = 0;
msg.gdr_mode = 0x00000000;
msg.gop_length = channel->gop_size;
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 06/18] media: allegro: fix calculation of CPB size
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (4 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 05/18] media: allegro: start a GOP with an IDR frame Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 07/18] media: allegro: fix reset if WAKEUP has not been set properly Michael Tretter
` (12 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index b04ded8ae06b..383a5fe07d64 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 <linux/bits.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -1094,12 +1095,11 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
msg.rate_control_mode =
v4l2_bitrate_mode_to_mcu_mode(channel->bitrate_mode);
- /* 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;
+ (channel->cpb_size * 90000) / (channel->bitrate_peak / 1000 / BITS_PER_BYTE);
+ /* 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.target_bitrate = channel->bitrate;
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 07/18] media: allegro: fix reset if WAKEUP has not been set properly
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (5 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 06/18] media: allegro: fix calculation of CPB size Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 08/18] media: allegro: extract mcu and codec address calculation Michael Tretter
` (11 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
The Zynq UltraScale+ Devices Register Reference states that the WAKEUP
bit "should be set to 0 after the MCU sleep status bit gets back to 0."
If this is not done, the mcu is not going to sleep on reset and fail the
reset.
Set WAKEUP to 0 before triggering a reset to make sure that the reset is
successful.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 383a5fe07d64..3366e3605cf5 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -1975,6 +1975,14 @@ static int allegro_mcu_reset(struct allegro_dev *dev)
{
int err;
+ /*
+ * Ensure that the AL5_MCU_WAKEUP bit is set to 0 otherwise the mcu
+ * does not go to sleep after the reset.
+ */
+ err = regmap_write(dev->regmap, AL5_MCU_WAKEUP, 0);
+ if (err)
+ return err;
+
err = regmap_write(dev->regmap,
AL5_MCU_RESET_MODE, AL5_MCU_RESET_MODE_SLEEP);
if (err < 0)
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 08/18] media: allegro: extract mcu and codec address calculation
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (6 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 07/18] media: allegro: fix reset if WAKEUP has not been set properly Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 09/18] media: allegro: warn if response message has an unexpected size Michael Tretter
` (10 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
.../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 3366e3605cf5..c0b3a6858b27 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;
@@ -1158,8 +1181,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 */
@@ -1186,11 +1209,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);
@@ -1249,10 +1272,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++;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 09/18] media: allegro: warn if response message has an unexpected size
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (7 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 08/18] media: allegro: extract mcu and codec address calculation Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 10/18] media: allegro: skip filler data if possible Michael Tretter
` (9 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index c0b3a6858b27..868dd9b35400 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -1696,6 +1696,11 @@ 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,
@@ -1789,6 +1794,11 @@ 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,
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 10/18] media: allegro: skip filler data if possible
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (8 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 09/18] media: allegro: warn if response message has an unexpected size Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 11/18] media: allegro: make frame rate configurable Michael Tretter
` (8 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
.../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 868dd9b35400..71ed3abc61f0 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -1637,17 +1637,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,
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 11/18] media: allegro: make frame rate configurable
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (9 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 10/18] media: allegro: skip filler data if possible Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 12/18] media: allegro: make QP configurable Michael Tretter
` (7 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
.../staging/media/allegro-dvt/allegro-core.c | 60 +++++++++++++++++--
1 file changed, 55 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 71ed3abc61f0..3ecc38047436 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -7,6 +7,7 @@
#include <linux/bits.h>
#include <linux/firmware.h>
+#include <linux/gcd.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
@@ -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;
@@ -1123,8 +1127,9 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
(channel->cpb_size * 90000) / (channel->bitrate_peak / 1000 / BITS_PER_BYTE);
/* 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;
@@ -1433,9 +1438,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;
@@ -2100,7 +2107,8 @@ 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) {
@@ -2146,6 +2154,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;
@@ -2736,6 +2745,44 @@ 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)
{
@@ -2774,6 +2821,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,
};
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 12/18] media: allegro: make QP configurable
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (10 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 11/18] media: allegro: make frame rate configurable Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 13/18] media: allegro: read bitrate mode directly from control Michael Tretter
` (6 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
The V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE control allows to enable/disable
rate control on a channel. When rate control is disabled, the driver
shall use constant QP, which are set by the application. Also implement
the controls for configuring the QP.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
.../staging/media/allegro-dvt/allegro-core.c | 105 ++++++++++++++++--
1 file changed, 95 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 3ecc38047436..c25f76fffa5e 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -198,6 +198,7 @@ struct allegro_channel {
unsigned int csequence;
enum v4l2_mpeg_video_bitrate_mode bitrate_mode;
+ bool frame_rc_enable;
unsigned int bitrate;
unsigned int bitrate_peak;
unsigned int cpb_size;
@@ -205,6 +206,12 @@ struct allegro_channel {
struct v4l2_ctrl *mpeg_video_h264_profile;
struct v4l2_ctrl *mpeg_video_h264_level;
+ struct v4l2_ctrl *mpeg_video_h264_i_frame_qp;
+ struct v4l2_ctrl *mpeg_video_h264_max_qp;
+ struct v4l2_ctrl *mpeg_video_h264_min_qp;
+ 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;
@@ -1081,6 +1088,14 @@ v4l2_bitrate_mode_to_mcu_mode(enum v4l2_mpeg_video_bitrate_mode mode)
}
}
+static s16 get_qp_delta(int minuend, int subtrahend)
+{
+ if (minuend == subtrahend)
+ return -1;
+ else
+ return minuend - subtrahend;
+}
+
static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
struct allegro_channel *channel)
{
@@ -1120,8 +1135,12 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
msg.max_transfo_depth_intra = 1;
msg.max_transfo_depth_inter = 1;
- msg.rate_control_mode =
- v4l2_bitrate_mode_to_mcu_mode(channel->bitrate_mode);
+ if (channel->frame_rc_enable)
+ msg.rate_control_mode =
+ v4l2_bitrate_mode_to_mcu_mode(channel->bitrate_mode);
+ else
+ msg.rate_control_mode = 0;
+
/* Encoder expects cpb_size in units of a 90 kHz clock. */
msg.cpb_size =
(channel->cpb_size * 90000) / (channel->bitrate_peak / 1000 / BITS_PER_BYTE);
@@ -1132,11 +1151,15 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
msg.clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000;
msg.target_bitrate = channel->bitrate;
msg.max_bitrate = channel->bitrate_peak;
- msg.initial_qp = 25;
- msg.min_qp = 10;
- msg.max_qp = 51;
- msg.ip_delta = -1;
- msg.pb_delta = -1;
+ msg.initial_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_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(
+ v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_i_frame_qp),
+ v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp));
+ msg.pb_delta = get_qp_delta(
+ v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp),
+ v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_b_frame_qp));
msg.golden_ref = 0;
msg.golden_delta = 2;
msg.golden_ref_frequency = 10;
@@ -1455,7 +1478,7 @@ static ssize_t allegro_h264_write_sps(struct allegro_channel *channel,
/* See Rec. ITU-T H.264 (04/2017) p. 410 E-54 */
sps->vui.vcl_hrd_parameters.cpb_size_value_minus1[0] =
(channel->cpb_size * 1000) / (1 << (4 + sps->vui.vcl_hrd_parameters.cpb_size_scale)) - 1;
- sps->vui.vcl_hrd_parameters.cbr_flag[0] = 1;
+ sps->vui.vcl_hrd_parameters.cbr_flag[0] = !v4l2_ctrl_g_ctrl(channel->mpeg_video_frame_rc_enable);
sps->vui.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 = 31;
sps->vui.vcl_hrd_parameters.cpb_removal_delay_length_minus1 = 31;
sps->vui.vcl_hrd_parameters.dpb_output_delay_length_minus1 = 31;
@@ -1677,13 +1700,13 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
v4l2_dbg(1, debug, &dev->v4l2_dev,
- "channel %d: encoded frame #%03d (%s%s, %d bytes)\n",
+ "channel %d: encoded frame #%03d (%s%s, QP %d, %d bytes)\n",
channel->mcu_channel_id,
dst_buf->sequence,
msg->is_idr ? "IDR, " : "",
msg->slice_type == AL_ENC_SLICE_TYPE_I ? "I slice" :
msg->slice_type == AL_ENC_SLICE_TYPE_P ? "P slice" : "unknown",
- partition->size);
+ msg->qp, partition->size);
err:
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
@@ -2062,6 +2085,12 @@ static void allegro_destroy_channel(struct allegro_channel *channel)
v4l2_ctrl_grab(channel->mpeg_video_h264_profile, false);
v4l2_ctrl_grab(channel->mpeg_video_h264_level, false);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_i_frame_qp, false);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_max_qp, false);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_min_qp, false);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_p_frame_qp, false);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_b_frame_qp, false);
+ v4l2_ctrl_grab(channel->mpeg_video_frame_rc_enable, false);
v4l2_ctrl_grab(channel->mpeg_video_bitrate_mode, false);
v4l2_ctrl_grab(channel->mpeg_video_bitrate, false);
v4l2_ctrl_grab(channel->mpeg_video_bitrate_peak, false);
@@ -2122,6 +2151,12 @@ static int allegro_create_channel(struct allegro_channel *channel)
v4l2_ctrl_grab(channel->mpeg_video_h264_profile, true);
v4l2_ctrl_grab(channel->mpeg_video_h264_level, true);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_i_frame_qp, true);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_max_qp, true);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_min_qp, true);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_p_frame_qp, true);
+ v4l2_ctrl_grab(channel->mpeg_video_h264_b_frame_qp, true);
+ v4l2_ctrl_grab(channel->mpeg_video_frame_rc_enable, true);
v4l2_ctrl_grab(channel->mpeg_video_bitrate_mode, true);
v4l2_ctrl_grab(channel->mpeg_video_bitrate, true);
v4l2_ctrl_grab(channel->mpeg_video_bitrate_peak, true);
@@ -2334,6 +2369,23 @@ static int allegro_queue_init(void *priv,
return 0;
}
+static int allegro_clamp_qp(struct allegro_channel *channel, struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_ctrl *next_ctrl;
+
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP)
+ next_ctrl = channel->mpeg_video_h264_p_frame_qp;
+ else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP)
+ next_ctrl = channel->mpeg_video_h264_b_frame_qp;
+ else
+ return 0;
+
+ /* Modify range automatically updates the value */
+ __v4l2_ctrl_modify_range(next_ctrl, ctrl->val, 51, 1, ctrl->val);
+
+ return allegro_clamp_qp(channel, next_ctrl);
+}
+
static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct allegro_channel *channel = container_of(ctrl->handler,
@@ -2348,6 +2400,9 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
channel->level = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+ channel->frame_rc_enable = ctrl->val;
+ break;
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
channel->bitrate_mode = ctrl->val;
break;
@@ -2363,6 +2418,11 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
channel->gop_size = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+ allegro_clamp_qp(channel, ctrl);
+ break;
}
return 0;
@@ -2407,6 +2467,31 @@ static int allegro_open(struct file *file)
V4L2_CID_MPEG_VIDEO_H264_LEVEL,
V4L2_MPEG_VIDEO_H264_LEVEL_5_1, mask,
V4L2_MPEG_VIDEO_H264_LEVEL_5_1);
+ channel->mpeg_video_h264_i_frame_qp = v4l2_ctrl_new_std(handler,
+ &allegro_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+ 0, 51, 1, 30);
+ channel->mpeg_video_h264_max_qp = v4l2_ctrl_new_std(handler,
+ &allegro_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+ 0, 51, 1, 51);
+ channel->mpeg_video_h264_min_qp = v4l2_ctrl_new_std(handler,
+ &allegro_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+ 0, 51, 1, 0);
+ channel->mpeg_video_h264_p_frame_qp = v4l2_ctrl_new_std(handler,
+ &allegro_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+ 0, 51, 1, 30);
+ channel->mpeg_video_h264_b_frame_qp = v4l2_ctrl_new_std(handler,
+ &allegro_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+ 0, 51, 1, 30);
+ channel->mpeg_video_frame_rc_enable = v4l2_ctrl_new_std(handler,
+ &allegro_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
+ false, 0x1,
+ true, false);
channel->mpeg_video_bitrate_mode = v4l2_ctrl_new_std_menu(handler,
&allegro_ctrl_ops,
V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 13/18] media: allegro: read bitrate mode directly from control
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (11 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 12/18] media: allegro: make QP configurable Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 14/18] media: allegro: handle dependency of bitrate and bitrate_peak Michael Tretter
` (5 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
There is no need to copy the bitrate mode to a field in the channel and
the value can be read directly from the control.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index c25f76fffa5e..8c26158eab93 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -197,7 +197,6 @@ struct allegro_channel {
unsigned int sizeimage_encoded;
unsigned int csequence;
- enum v4l2_mpeg_video_bitrate_mode bitrate_mode;
bool frame_rc_enable;
unsigned int bitrate;
unsigned int bitrate_peak;
@@ -1137,7 +1136,7 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
if (channel->frame_rc_enable)
msg.rate_control_mode =
- v4l2_bitrate_mode_to_mcu_mode(channel->bitrate_mode);
+ v4l2_bitrate_mode_to_mcu_mode(v4l2_ctrl_g_ctrl(channel->mpeg_video_bitrate_mode));
else
msg.rate_control_mode = 0;
@@ -2206,7 +2205,6 @@ static void allegro_set_default_params(struct allegro_channel *channel)
channel->sizeimage_encoded =
estimate_stream_size(channel->width, channel->height);
- channel->bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
channel->bitrate = maximum_bitrate(channel->level);
channel->bitrate_peak = maximum_bitrate(channel->level);
channel->cpb_size = maximum_cpb_size(channel->level);
@@ -2403,9 +2401,6 @@ 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_MODE:
- channel->bitrate_mode = ctrl->val;
- break;
case V4L2_CID_MPEG_VIDEO_BITRATE:
channel->bitrate = ctrl->val;
break;
@@ -2496,7 +2491,7 @@ static int allegro_open(struct file *file)
&allegro_ctrl_ops,
V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
- channel->bitrate_mode);
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
channel->mpeg_video_bitrate = v4l2_ctrl_new_std(handler,
&allegro_ctrl_ops,
V4L2_CID_MPEG_VIDEO_BITRATE,
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 14/18] media: allegro: handle dependency of bitrate and bitrate_peak
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (12 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 13/18] media: allegro: read bitrate mode directly from control Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-25 14:14 ` Hans Verkuil
2020-02-17 15:13 ` [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response Michael Tretter
` (4 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/allegro-core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 8c26158eab93..cedb09ea649f 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -2403,9 +2403,15 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_MPEG_VIDEO_BITRATE:
channel->bitrate = ctrl->val;
+ if (channel->bitrate > channel->bitrate_peak)
+ __v4l2_ctrl_s_ctrl(channel->mpeg_video_bitrate_peak,
+ channel->bitrate);
break;
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
channel->bitrate_peak = ctrl->val;
+ if (channel->bitrate_peak < channel->bitrate)
+ __v4l2_ctrl_s_ctrl(channel->mpeg_video_bitrate,
+ channel->bitrate_peak);
break;
case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
channel->cpb_size = ctrl->val;
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (13 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 14/18] media: allegro: handle dependency of bitrate and bitrate_peak Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-19 15:41 ` kbuild test robot
2020-02-17 15:13 ` [PATCH 16/18] media: allegro: pass buffers through firmware Michael Tretter
` (3 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
The PUT_STREAM_BUFFER and ENCODE_FRAME request have fields that allow to
pass arbitrary 64 bit values through the firmware to the ENCODE_FRAME
response. Use these values to verify that the buffers when finishing the
frame are actually the same buffers that have been sent for encoding a
frame.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
.../staging/media/allegro-dvt/allegro-core.c | 21 ++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index cedb09ea649f..4f525920c194 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -1198,7 +1198,8 @@ static int allegro_mcu_send_destroy_channel(struct allegro_dev *dev,
static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
struct allegro_channel *channel,
dma_addr_t paddr,
- unsigned long size)
+ unsigned long size,
+ u64 stream_id)
{
struct mcu_msg_put_stream_buffer msg;
@@ -1212,7 +1213,7 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
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 */
+ msg.stream_id = stream_id; /* copied to mcu_msg_encode_frame_response */
allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));
allegro_mcu_interrupt(dev);
@@ -1222,7 +1223,8 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,
struct allegro_channel *channel,
- dma_addr_t src_y, dma_addr_t src_uv)
+ dma_addr_t src_y, dma_addr_t src_uv,
+ u64 src_handle)
{
struct mcu_msg_encode_frame msg;
@@ -1235,7 +1237,7 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,
msg.encoding_options = AL_OPT_FORCE_LOAD;
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_handle = src_handle; /* copied to mcu_msg_encode_frame_response */
msg.src_y = to_codec_addr(dev, src_y);
msg.src_uv = to_codec_addr(dev, src_uv);
msg.stride = channel->stride;
@@ -1584,8 +1586,13 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
ssize_t free;
src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx);
-
dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
+
+ if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
+ v4l2_err(&dev->v4l2_dev,
+ "channel %d: check failed\n",
+ channel->mcu_channel_id);
+
dst_buf->sequence = channel->csequence++;
if (msg->error_code & AL_ERROR) {
@@ -2954,14 +2961,14 @@ static void allegro_device_run(void *priv)
dst_buf = v4l2_m2m_next_dst_buf(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);
- allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size);
+ allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, (u64)dst_buf);
src_buf = v4l2_m2m_next_src_buf(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);
+ allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv, (u64)src_buf);
}
static const struct v4l2_m2m_ops allegro_m2m_ops = {
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 16/18] media: allegro: pass buffers through firmware
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (14 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-25 14:09 ` Hans Verkuil
2020-02-17 15:13 ` [PATCH 17/18] media: allegro: move mail definitions to separate file Michael Tretter
` (2 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
.../staging/media/allegro-dvt/allegro-core.c | 104 +++++++++++++++---
1 file changed, 89 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 4f525920c194..80d3383b84f8 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -226,6 +226,10 @@ 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;
+ struct mutex shadow_list_lock;
+
struct list_head list;
struct completion completion;
@@ -247,6 +251,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;
@@ -1570,6 +1582,43 @@ 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 (u64) buffer;
+}
+
+static struct vb2_v4l2_buffer *allegro_get_buffer(struct allegro_channel *channel,
+ struct list_head *list,
+ u64 handle)
+{
+ struct allegro_dev *dev = channel->dev;
+ struct allegro_m2m_buffer *shadow;
+ u64 found;
+
+ mutex_lock(&channel->shadow_list_lock);
+ shadow = list_first_entry(list, struct allegro_m2m_buffer, head);
+ list_del_init(&shadow->head);
+ mutex_unlock(&channel->shadow_list_lock);
+
+ found = (u64) (&shadow->buf.vb);
+ if (handle != found)
+ v4l2_warn(&dev->v4l2_dev,
+ "channel %d: output buffer mismatch 0x%llx, expected 0x%llx\n",
+ channel->mcu_channel_id, handle, found);
+
+ return &shadow->buf.vb;
+}
+
static void allegro_channel_finish_frame(struct allegro_channel *channel,
struct mcu_msg_encode_frame_response *msg)
{
@@ -1585,13 +1634,17 @@ 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);
- dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
+ 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\n",
+ channel->mcu_channel_id);
- if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
- v4l2_err(&dev->v4l2_dev,
- "channel %d: check failed\n",
- channel->mcu_channel_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\n",
+ channel->mcu_channel_id);
dst_buf->sequence = channel->csequence++;
@@ -1718,8 +1771,6 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
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);
}
static int allegro_handle_init(struct allegro_dev *dev,
@@ -2312,16 +2363,31 @@ 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);
@@ -2352,7 +2418,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)
@@ -2365,7 +2431,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)
@@ -2457,6 +2523,9 @@ static int allegro_open(struct file *file)
v4l2_fh_add(&channel->fh);
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;
@@ -2957,18 +3026,23 @@ 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);
- allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, (u64)dst_buf);
+ dst_handle = allegro_put_buffer(channel, &channel->stream_shadow_list, dst_buf);
+ allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, 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, (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 = {
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 17/18] media: allegro: move mail definitions to separate file
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (15 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 16/18] media: allegro: pass buffers through firmware Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 18/18] media: allegro: create new struct for channel parameters Michael Tretter
2020-02-25 14:20 ` [PATCH 00/18] media: allegro: fixes and new features Hans Verkuil
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
Move the mail definitions from the driver core to a dedicated file.
The mails that are exchanged between driver and firmware are not stable
across firmware versions. This is in preparation to make the driver able
to handle multiple firmware version by having dedicated code for
handling mails.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
drivers/staging/media/allegro-dvt/Makefile | 2 +-
.../staging/media/allegro-dvt/allegro-core.c | 274 +-----------------
.../staging/media/allegro-dvt/allegro-mail.c | 37 +++
.../staging/media/allegro-dvt/allegro-mail.h | 263 +++++++++++++++++
4 files changed, 302 insertions(+), 274 deletions(-)
create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.c
create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.h
diff --git a/drivers/staging/media/allegro-dvt/Makefile b/drivers/staging/media/allegro-dvt/Makefile
index 80817160815c..8e306dcdc55c 100644
--- a/drivers/staging/media/allegro-dvt/Makefile
+++ b/drivers/staging/media/allegro-dvt/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-allegro-objs := allegro-core.o nal-h264.o
+allegro-objs := allegro-core.o nal-h264.o allegro-mail.o
obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index 80d3383b84f8..e56256d1cdb3 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -28,6 +28,7 @@
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-v4l2.h>
+#include "allegro-mail.h"
#include "nal-h264.h"
/*
@@ -281,279 +282,6 @@ static const struct fw_info supported_firmware[] = {
},
};
-enum mcu_msg_type {
- MCU_MSG_TYPE_INIT = 0x0000,
- MCU_MSG_TYPE_CREATE_CHANNEL = 0x0005,
- MCU_MSG_TYPE_DESTROY_CHANNEL = 0x0006,
- MCU_MSG_TYPE_ENCODE_FRAME = 0x0007,
- MCU_MSG_TYPE_PUT_STREAM_BUFFER = 0x0012,
- MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE = 0x000e,
- MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE = 0x000f,
-};
-
-static const char *msg_type_name(enum mcu_msg_type type)
-{
- static char buf[9];
-
- switch (type) {
- case MCU_MSG_TYPE_INIT:
- return "INIT";
- case MCU_MSG_TYPE_CREATE_CHANNEL:
- return "CREATE_CHANNEL";
- case MCU_MSG_TYPE_DESTROY_CHANNEL:
- return "DESTROY_CHANNEL";
- case MCU_MSG_TYPE_ENCODE_FRAME:
- return "ENCODE_FRAME";
- case MCU_MSG_TYPE_PUT_STREAM_BUFFER:
- return "PUT_STREAM_BUFFER";
- case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE:
- return "PUSH_BUFFER_INTERMEDIATE";
- case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE:
- return "PUSH_BUFFER_REFERENCE";
- default:
- snprintf(buf, sizeof(buf), "(0x%04x)", type);
- return buf;
- }
-}
-
-struct mcu_msg_header {
- u16 length; /* length of the body in bytes */
- u16 type;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_init_request {
- struct mcu_msg_header header;
- u32 reserved0; /* maybe a unused channel id */
- u32 suballoc_dma;
- u32 suballoc_size;
- s32 l2_cache[3];
-} __attribute__ ((__packed__));
-
-struct mcu_msg_init_response {
- struct mcu_msg_header header;
- u32 reserved0;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_create_channel {
- struct mcu_msg_header header;
- u32 user_id;
- u16 width;
- u16 height;
- u32 format;
- u32 colorspace;
- u32 src_mode;
- u8 profile;
- u16 constraint_set_flags;
- s8 codec;
- u16 level;
- u16 tier;
- u32 sps_param;
- u32 pps_param;
-
- u32 enc_option;
-#define AL_OPT_WPP BIT(0)
-#define AL_OPT_TILE BIT(1)
-#define AL_OPT_LF BIT(2)
-#define AL_OPT_LF_X_SLICE BIT(3)
-#define AL_OPT_LF_X_TILE BIT(4)
-#define AL_OPT_SCL_LST BIT(5)
-#define AL_OPT_CONST_INTRA_PRED BIT(6)
-#define AL_OPT_QP_TAB_RELATIVE BIT(7)
-#define AL_OPT_FIX_PREDICTOR BIT(8)
-#define AL_OPT_CUSTOM_LDA BIT(9)
-#define AL_OPT_ENABLE_AUTO_QP BIT(10)
-#define AL_OPT_ADAPT_AUTO_QP BIT(11)
-#define AL_OPT_TRANSFO_SKIP BIT(13)
-#define AL_OPT_FORCE_REC BIT(15)
-#define AL_OPT_FORCE_MV_OUT BIT(16)
-#define AL_OPT_FORCE_MV_CLIP BIT(17)
-#define AL_OPT_LOWLAT_SYNC BIT(18)
-#define AL_OPT_LOWLAT_INT BIT(19)
-#define AL_OPT_RDO_COST_MODE BIT(20)
-
- s8 beta_offset;
- s8 tc_offset;
- u16 reserved10;
- u32 unknown11;
- u32 unknown12;
- u16 num_slices;
- u16 prefetch_auto;
- u32 prefetch_mem_offset;
- u32 prefetch_mem_size;
- u16 clip_hrz_range;
- u16 clip_vrt_range;
- u16 me_range[4];
- u8 max_cu_size;
- u8 min_cu_size;
- u8 max_tu_size;
- u8 min_tu_size;
- u8 max_transfo_depth_inter;
- u8 max_transfo_depth_intra;
- u16 reserved20;
- u32 entropy_mode;
- u32 wp_mode;
-
- /* rate control param */
- u32 rate_control_mode;
- u32 initial_rem_delay;
- u32 cpb_size;
- u16 framerate;
- u16 clk_ratio;
- u32 target_bitrate;
- u32 max_bitrate;
- u16 initial_qp;
- u16 min_qp;
- u16 max_qp;
- s16 ip_delta;
- s16 pb_delta;
- u16 golden_ref;
- u16 golden_delta;
- u16 golden_ref_frequency;
- u32 rate_control_option;
-
- /* gop param */
- u32 gop_ctrl_mode;
- u32 freq_idr;
- u32 freq_lt;
- u32 gdr_mode;
- u16 gop_length;
- u8 num_b;
- u8 freq_golden_ref;
-
- u32 subframe_latency;
- u32 lda_control_mode;
- u32 unknown41;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_create_channel_response {
- struct mcu_msg_header header;
- u32 channel_id;
- u32 user_id;
- u32 options;
- u32 num_core;
- u32 pps_param;
- u32 int_buffers_count;
- u32 int_buffers_size;
- u32 rec_buffers_count;
- u32 rec_buffers_size;
- u32 reserved;
- u32 error_code;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_destroy_channel {
- struct mcu_msg_header header;
- u32 channel_id;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_destroy_channel_response {
- struct mcu_msg_header header;
- u32 channel_id;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_push_buffers_internal_buffer {
- u32 dma_addr;
- u32 mcu_addr;
- u32 size;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_push_buffers_internal {
- struct mcu_msg_header header;
- u32 channel_id;
- struct mcu_msg_push_buffers_internal_buffer buffer[0];
-} __attribute__ ((__packed__));
-
-struct mcu_msg_put_stream_buffer {
- struct mcu_msg_header header;
- u32 channel_id;
- u32 dma_addr;
- u32 mcu_addr;
- u32 size;
- u32 offset;
- u64 stream_id;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_encode_frame {
- struct mcu_msg_header header;
- u32 channel_id;
- u32 reserved;
-
- u32 encoding_options;
-#define AL_OPT_USE_QP_TABLE BIT(0)
-#define AL_OPT_FORCE_LOAD BIT(1)
-#define AL_OPT_USE_L2 BIT(2)
-#define AL_OPT_DISABLE_INTRA BIT(3)
-#define AL_OPT_DEPENDENT_SLICES BIT(4)
-
- s16 pps_qp;
- u16 padding;
- u64 user_param;
- u64 src_handle;
-
- u32 request_options;
-#define AL_OPT_SCENE_CHANGE BIT(0)
-#define AL_OPT_RESTART_GOP BIT(1)
-#define AL_OPT_USE_LONG_TERM BIT(2)
-#define AL_OPT_UPDATE_PARAMS BIT(3)
-
- /* u32 scene_change_delay (optional) */
- /* rate control param (optional) */
- /* gop param (optional) */
- u32 src_y;
- u32 src_uv;
- u32 stride;
- u32 ep2;
- u64 ep2_v;
-} __attribute__ ((__packed__));
-
-struct mcu_msg_encode_frame_response {
- struct mcu_msg_header header;
- u32 channel_id;
- u64 stream_id; /* see mcu_msg_put_stream_buffer */
- u64 user_param; /* see mcu_msg_encode_frame */
- u64 src_handle; /* see mcu_msg_encode_frame */
- u16 skip;
- u16 is_ref;
- u32 initial_removal_delay;
- u32 dpb_output_delay;
- u32 size;
- u32 frame_tag_size;
- s32 stuffing;
- s32 filler;
- u16 num_column;
- u16 num_row;
- u16 qp;
- u8 num_ref_idx_l0;
- u8 num_ref_idx_l1;
- u32 partition_table_offset;
- s32 partition_table_size;
- u32 sum_complex;
- s32 tile_width[4];
- s32 tile_height[22];
- u32 error_code;
-
- u32 slice_type;
-#define AL_ENC_SLICE_TYPE_B 0
-#define AL_ENC_SLICE_TYPE_P 1
-#define AL_ENC_SLICE_TYPE_I 2
-
- u32 pic_struct;
- u8 is_idr;
- u8 is_first_slice;
- u8 is_last_slice;
- u8 reserved;
- u16 pps_qp;
- u16 reserved1;
- u32 reserved2;
-} __attribute__ ((__packed__));
-
-union mcu_msg_response {
- struct mcu_msg_header header;
- struct mcu_msg_init_response init;
- struct mcu_msg_create_channel_response create_channel;
- struct mcu_msg_destroy_channel_response destroy_channel;
- 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))
diff --git a/drivers/staging/media/allegro-dvt/allegro-mail.c b/drivers/staging/media/allegro-dvt/allegro-mail.c
new file mode 100644
index 000000000000..df0d8d26a6fb
--- /dev/null
+++ b/drivers/staging/media/allegro-dvt/allegro-mail.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de>
+ *
+ * Helper functions for handling messages that are send via mailbox to the
+ * Allegro VCU firmware.
+ */
+
+#include <linux/export.h>
+
+#include "allegro-mail.h"
+
+const char *msg_type_name(enum mcu_msg_type type)
+{
+ static char buf[9];
+
+ switch (type) {
+ case MCU_MSG_TYPE_INIT:
+ return "INIT";
+ case MCU_MSG_TYPE_CREATE_CHANNEL:
+ return "CREATE_CHANNEL";
+ case MCU_MSG_TYPE_DESTROY_CHANNEL:
+ return "DESTROY_CHANNEL";
+ case MCU_MSG_TYPE_ENCODE_FRAME:
+ return "ENCODE_FRAME";
+ case MCU_MSG_TYPE_PUT_STREAM_BUFFER:
+ return "PUT_STREAM_BUFFER";
+ case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE:
+ return "PUSH_BUFFER_INTERMEDIATE";
+ case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE:
+ return "PUSH_BUFFER_REFERENCE";
+ default:
+ snprintf(buf, sizeof(buf), "(0x%04x)", type);
+ return buf;
+ }
+}
+EXPORT_SYMBOL(msg_type_name);
diff --git a/drivers/staging/media/allegro-dvt/allegro-mail.h b/drivers/staging/media/allegro-dvt/allegro-mail.h
new file mode 100644
index 000000000000..d9050d6b5c97
--- /dev/null
+++ b/drivers/staging/media/allegro-dvt/allegro-mail.h
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de>
+ *
+ * Allegro VCU firmware mailbox mail definitions
+ */
+
+#ifndef ALLEGRO_MAIL_H
+#define ALLEGRO_MAIL_H
+
+#include <linux/kernel.h>
+
+enum mcu_msg_type {
+ MCU_MSG_TYPE_INIT = 0x0000,
+ MCU_MSG_TYPE_CREATE_CHANNEL = 0x0005,
+ MCU_MSG_TYPE_DESTROY_CHANNEL = 0x0006,
+ MCU_MSG_TYPE_ENCODE_FRAME = 0x0007,
+ MCU_MSG_TYPE_PUT_STREAM_BUFFER = 0x0012,
+ MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE = 0x000e,
+ MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE = 0x000f,
+};
+
+const char *msg_type_name(enum mcu_msg_type type);
+
+struct mcu_msg_header {
+ u16 length; /* length of the body in bytes */
+ u16 type;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_init_request {
+ struct mcu_msg_header header;
+ u32 reserved0; /* maybe a unused channel id */
+ u32 suballoc_dma;
+ u32 suballoc_size;
+ s32 l2_cache[3];
+} __attribute__ ((__packed__));
+
+struct mcu_msg_init_response {
+ struct mcu_msg_header header;
+ u32 reserved0;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_create_channel {
+ struct mcu_msg_header header;
+ u32 user_id;
+ u16 width;
+ u16 height;
+ u32 format;
+ u32 colorspace;
+ u32 src_mode;
+ u8 profile;
+ u16 constraint_set_flags;
+ s8 codec;
+ u16 level;
+ u16 tier;
+ u32 sps_param;
+ u32 pps_param;
+
+ u32 enc_option;
+#define AL_OPT_WPP BIT(0)
+#define AL_OPT_TILE BIT(1)
+#define AL_OPT_LF BIT(2)
+#define AL_OPT_LF_X_SLICE BIT(3)
+#define AL_OPT_LF_X_TILE BIT(4)
+#define AL_OPT_SCL_LST BIT(5)
+#define AL_OPT_CONST_INTRA_PRED BIT(6)
+#define AL_OPT_QP_TAB_RELATIVE BIT(7)
+#define AL_OPT_FIX_PREDICTOR BIT(8)
+#define AL_OPT_CUSTOM_LDA BIT(9)
+#define AL_OPT_ENABLE_AUTO_QP BIT(10)
+#define AL_OPT_ADAPT_AUTO_QP BIT(11)
+#define AL_OPT_TRANSFO_SKIP BIT(13)
+#define AL_OPT_FORCE_REC BIT(15)
+#define AL_OPT_FORCE_MV_OUT BIT(16)
+#define AL_OPT_FORCE_MV_CLIP BIT(17)
+#define AL_OPT_LOWLAT_SYNC BIT(18)
+#define AL_OPT_LOWLAT_INT BIT(19)
+#define AL_OPT_RDO_COST_MODE BIT(20)
+
+ s8 beta_offset;
+ s8 tc_offset;
+ u16 reserved10;
+ u32 unknown11;
+ u32 unknown12;
+ u16 num_slices;
+ u16 prefetch_auto;
+ u32 prefetch_mem_offset;
+ u32 prefetch_mem_size;
+ u16 clip_hrz_range;
+ u16 clip_vrt_range;
+ u16 me_range[4];
+ u8 max_cu_size;
+ u8 min_cu_size;
+ u8 max_tu_size;
+ u8 min_tu_size;
+ u8 max_transfo_depth_inter;
+ u8 max_transfo_depth_intra;
+ u16 reserved20;
+ u32 entropy_mode;
+ u32 wp_mode;
+
+ /* rate control param */
+ u32 rate_control_mode;
+ u32 initial_rem_delay;
+ u32 cpb_size;
+ u16 framerate;
+ u16 clk_ratio;
+ u32 target_bitrate;
+ u32 max_bitrate;
+ u16 initial_qp;
+ u16 min_qp;
+ u16 max_qp;
+ s16 ip_delta;
+ s16 pb_delta;
+ u16 golden_ref;
+ u16 golden_delta;
+ u16 golden_ref_frequency;
+ u32 rate_control_option;
+
+ /* gop param */
+ u32 gop_ctrl_mode;
+ u32 freq_idr;
+ u32 freq_lt;
+ u32 gdr_mode;
+ u16 gop_length;
+ u8 num_b;
+ u8 freq_golden_ref;
+
+ u32 subframe_latency;
+ u32 lda_control_mode;
+ u32 unknown41;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_create_channel_response {
+ struct mcu_msg_header header;
+ u32 channel_id;
+ u32 user_id;
+ u32 options;
+ u32 num_core;
+ u32 pps_param;
+ u32 int_buffers_count;
+ u32 int_buffers_size;
+ u32 rec_buffers_count;
+ u32 rec_buffers_size;
+ u32 reserved;
+ u32 error_code;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_destroy_channel {
+ struct mcu_msg_header header;
+ u32 channel_id;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_destroy_channel_response {
+ struct mcu_msg_header header;
+ u32 channel_id;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_push_buffers_internal_buffer {
+ u32 dma_addr;
+ u32 mcu_addr;
+ u32 size;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_push_buffers_internal {
+ struct mcu_msg_header header;
+ u32 channel_id;
+ struct mcu_msg_push_buffers_internal_buffer buffer[0];
+} __attribute__ ((__packed__));
+
+struct mcu_msg_put_stream_buffer {
+ struct mcu_msg_header header;
+ u32 channel_id;
+ u32 dma_addr;
+ u32 mcu_addr;
+ u32 size;
+ u32 offset;
+ u64 stream_id;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_encode_frame {
+ struct mcu_msg_header header;
+ u32 channel_id;
+ u32 reserved;
+
+ u32 encoding_options;
+#define AL_OPT_USE_QP_TABLE BIT(0)
+#define AL_OPT_FORCE_LOAD BIT(1)
+#define AL_OPT_USE_L2 BIT(2)
+#define AL_OPT_DISABLE_INTRA BIT(3)
+#define AL_OPT_DEPENDENT_SLICES BIT(4)
+
+ s16 pps_qp;
+ u16 padding;
+ u64 user_param;
+ u64 src_handle;
+
+ u32 request_options;
+#define AL_OPT_SCENE_CHANGE BIT(0)
+#define AL_OPT_RESTART_GOP BIT(1)
+#define AL_OPT_USE_LONG_TERM BIT(2)
+#define AL_OPT_UPDATE_PARAMS BIT(3)
+
+ /* u32 scene_change_delay (optional) */
+ /* rate control param (optional) */
+ /* gop param (optional) */
+ u32 src_y;
+ u32 src_uv;
+ u32 stride;
+ u32 ep2;
+ u64 ep2_v;
+} __attribute__ ((__packed__));
+
+struct mcu_msg_encode_frame_response {
+ struct mcu_msg_header header;
+ u32 channel_id;
+ u64 stream_id; /* see mcu_msg_put_stream_buffer */
+ u64 user_param; /* see mcu_msg_encode_frame */
+ u64 src_handle; /* see mcu_msg_encode_frame */
+ u16 skip;
+ u16 is_ref;
+ u32 initial_removal_delay;
+ u32 dpb_output_delay;
+ u32 size;
+ u32 frame_tag_size;
+ s32 stuffing;
+ s32 filler;
+ u16 num_column;
+ u16 num_row;
+ u16 qp;
+ u8 num_ref_idx_l0;
+ u8 num_ref_idx_l1;
+ u32 partition_table_offset;
+ s32 partition_table_size;
+ u32 sum_complex;
+ s32 tile_width[4];
+ s32 tile_height[22];
+ u32 error_code;
+
+ u32 slice_type;
+#define AL_ENC_SLICE_TYPE_B 0
+#define AL_ENC_SLICE_TYPE_P 1
+#define AL_ENC_SLICE_TYPE_I 2
+
+ u32 pic_struct;
+ u8 is_idr;
+ u8 is_first_slice;
+ u8 is_last_slice;
+ u8 reserved;
+ u16 pps_qp;
+ u16 reserved1;
+ u32 reserved2;
+} __attribute__ ((__packed__));
+
+union mcu_msg_response {
+ struct mcu_msg_header header;
+ struct mcu_msg_init_response init;
+ struct mcu_msg_create_channel_response create_channel;
+ struct mcu_msg_destroy_channel_response destroy_channel;
+ struct mcu_msg_encode_frame_response encode_frame;
+};
+
+#endif
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 18/18] media: allegro: create new struct for channel parameters
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (16 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 17/18] media: allegro: move mail definitions to separate file Michael Tretter
@ 2020-02-17 15:13 ` Michael Tretter
2020-02-25 14:20 ` [PATCH 00/18] media: allegro: fixes and new features Hans Verkuil
18 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-02-17 15:13 UTC (permalink / raw)
To: linux-media; +Cc: hverkuil-cisco, kernel, Michael Tretter
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 <m.tretter@pengutronix.de>
---
.../staging/media/allegro-dvt/allegro-core.c | 139 ++++++++++--------
.../staging/media/allegro-dvt/allegro-mail.h | 10 +-
2 files changed, 83 insertions(+), 66 deletions(-)
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index e56256d1cdb3..a7aa85ba5391 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -835,81 +835,94 @@ 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)
-{
- 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;
+static int fill_create_channel_param(struct allegro_channel *channel,
+ struct create_channel_param *param)
+{
+ 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;
if (channel->frame_rc_enable)
- msg.rate_control_mode =
+ param->rate_control_mode =
v4l2_bitrate_mode_to_mcu_mode(v4l2_ctrl_g_ctrl(channel->mpeg_video_bitrate_mode));
else
- msg.rate_control_mode = 0;
+ param->rate_control_mode = 0;
/* Encoder expects cpb_size in units of a 90 kHz clock. */
- msg.cpb_size =
+ param->cpb_size =
(channel->cpb_size * 90000) / (channel->bitrate_peak / 1000 / BITS_PER_BYTE);
/* 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 = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_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(
+ 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 = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_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(
v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_i_frame_qp),
v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp));
- msg.pb_delta = get_qp_delta(
+ param->pb_delta = get_qp_delta(
v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp),
v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_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;
+ 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;
+
+ 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 d9050d6b5c97..1a80320db4da 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;
--
2.20.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response
2020-02-17 15:13 ` [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response Michael Tretter
@ 2020-02-19 15:41 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2020-02-19 15:41 UTC (permalink / raw)
To: Michael Tretter; +Cc: kbuild-all, linux-media
[-- Attachment #1: Type: text/plain, Size: 7855 bytes --]
Hi Michael,
I love your patch! Perhaps something to improve:
[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v5.6-rc2 next-20200219]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Michael-Tretter/media-allegro-fixes-and-new-features/20200219-202330
base: git://linuxtv.org/media_tree.git master
config: c6x-allyesconfig (attached as .config)
compiler: c6x-elf-gcc (GCC) 7.5.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.5.0 make.cross ARCH=c6x
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/staging/media/allegro-dvt/allegro-core.c: In function 'allegro_channel_finish_frame':
>> drivers/staging/media/allegro-dvt/allegro-core.c:1591:6: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
^
drivers/staging/media/allegro-dvt/allegro-core.c:1591:41: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
^
drivers/staging/media/allegro-dvt/allegro-core.c: In function 'allegro_device_run':
drivers/staging/media/allegro-dvt/allegro-core.c:2964:71: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, (u64)dst_buf);
^
drivers/staging/media/allegro-dvt/allegro-core.c:2971:61: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv, (u64)src_buf);
^
vim +1591 drivers/staging/media/allegro-dvt/allegro-core.c
1572
1573 static void allegro_channel_finish_frame(struct allegro_channel *channel,
1574 struct mcu_msg_encode_frame_response *msg)
1575 {
1576 struct allegro_dev *dev = channel->dev;
1577 struct vb2_v4l2_buffer *src_buf;
1578 struct vb2_v4l2_buffer *dst_buf;
1579 struct {
1580 u32 offset;
1581 u32 size;
1582 } *partition;
1583 enum vb2_buffer_state state = VB2_BUF_STATE_ERROR;
1584 char *curr;
1585 ssize_t len;
1586 ssize_t free;
1587
1588 src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx);
1589 dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
1590
> 1591 if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
1592 v4l2_err(&dev->v4l2_dev,
1593 "channel %d: check failed\n",
1594 channel->mcu_channel_id);
1595
1596 dst_buf->sequence = channel->csequence++;
1597
1598 if (msg->error_code & AL_ERROR) {
1599 v4l2_err(&dev->v4l2_dev,
1600 "channel %d: failed to encode frame: %s (%x)\n",
1601 channel->mcu_channel_id,
1602 allegro_err_to_string(msg->error_code),
1603 msg->error_code);
1604 goto err;
1605 }
1606
1607 if (msg->partition_table_size != 1) {
1608 v4l2_warn(&dev->v4l2_dev,
1609 "channel %d: only handling first partition table entry (%d entries)\n",
1610 channel->mcu_channel_id, msg->partition_table_size);
1611 }
1612
1613 if (msg->partition_table_offset +
1614 msg->partition_table_size * sizeof(*partition) >
1615 vb2_plane_size(&dst_buf->vb2_buf, 0)) {
1616 v4l2_err(&dev->v4l2_dev,
1617 "channel %d: partition table outside of dst_buf\n",
1618 channel->mcu_channel_id);
1619 goto err;
1620 }
1621
1622 partition =
1623 vb2_plane_vaddr(&dst_buf->vb2_buf, 0) + msg->partition_table_offset;
1624 if (partition->offset + partition->size >
1625 vb2_plane_size(&dst_buf->vb2_buf, 0)) {
1626 v4l2_err(&dev->v4l2_dev,
1627 "channel %d: encoded frame is outside of dst_buf (offset 0x%x, size 0x%x)\n",
1628 channel->mcu_channel_id, partition->offset,
1629 partition->size);
1630 goto err;
1631 }
1632
1633 v4l2_dbg(2, debug, &dev->v4l2_dev,
1634 "channel %d: encoded frame of size %d is at offset 0x%x\n",
1635 channel->mcu_channel_id, partition->size, partition->offset);
1636
1637 /*
1638 * The payload must include the data before the partition offset,
1639 * because we will put the sps and pps data there.
1640 */
1641 vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
1642 partition->offset + partition->size);
1643
1644 curr = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
1645 free = partition->offset;
1646 if (msg->is_idr) {
1647 len = allegro_h264_write_sps(channel, curr, free);
1648 if (len < 0) {
1649 v4l2_err(&dev->v4l2_dev,
1650 "not enough space for sequence parameter set: %zd left\n",
1651 free);
1652 goto err;
1653 }
1654 curr += len;
1655 free -= len;
1656 v4l2_dbg(1, debug, &dev->v4l2_dev,
1657 "channel %d: wrote %zd byte SPS nal unit\n",
1658 channel->mcu_channel_id, len);
1659 }
1660
1661 if (msg->slice_type == AL_ENC_SLICE_TYPE_I) {
1662 len = allegro_h264_write_pps(channel, curr, free);
1663 if (len < 0) {
1664 v4l2_err(&dev->v4l2_dev,
1665 "not enough space for picture parameter set: %zd left\n",
1666 free);
1667 goto err;
1668 }
1669 curr += len;
1670 free -= len;
1671 v4l2_dbg(1, debug, &dev->v4l2_dev,
1672 "channel %d: wrote %zd byte PPS nal unit\n",
1673 channel->mcu_channel_id, len);
1674 }
1675
1676 if (msg->slice_type != AL_ENC_SLICE_TYPE_I && !msg->is_idr) {
1677 dst_buf->vb2_buf.planes[0].data_offset = free;
1678 free = 0;
1679 } else {
1680 len = nal_h264_write_filler(&dev->plat_dev->dev, curr, free);
1681 if (len < 0) {
1682 v4l2_err(&dev->v4l2_dev,
1683 "failed to write %zd filler data\n", free);
1684 goto err;
1685 }
1686 curr += len;
1687 free -= len;
1688 v4l2_dbg(2, debug, &dev->v4l2_dev,
1689 "channel %d: wrote %zd bytes filler nal unit\n",
1690 channel->mcu_channel_id, len);
1691 }
1692
1693 if (free != 0) {
1694 v4l2_err(&dev->v4l2_dev,
1695 "non-VCL NAL units do not fill space until VCL NAL unit: %zd bytes left\n",
1696 free);
1697 goto err;
1698 }
1699
1700 state = VB2_BUF_STATE_DONE;
1701
1702 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
1703 if (msg->is_idr)
1704 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1705 else
1706 dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
1707
1708 v4l2_dbg(1, debug, &dev->v4l2_dev,
1709 "channel %d: encoded frame #%03d (%s%s, QP %d, %d bytes)\n",
1710 channel->mcu_channel_id,
1711 dst_buf->sequence,
1712 msg->is_idr ? "IDR, " : "",
1713 msg->slice_type == AL_ENC_SLICE_TYPE_I ? "I slice" :
1714 msg->slice_type == AL_ENC_SLICE_TYPE_P ? "P slice" : "unknown",
1715 msg->qp, partition->size);
1716
1717 err:
1718 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1719
1720 allegro_channel_buf_done(channel, dst_buf, state);
1721
1722 v4l2_m2m_job_finish(dev->m2m_dev, channel->fh.m2m_ctx);
1723 }
1724
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 51587 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response
@ 2020-02-19 15:41 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2020-02-19 15:41 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 8056 bytes --]
Hi Michael,
I love your patch! Perhaps something to improve:
[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v5.6-rc2 next-20200219]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Michael-Tretter/media-allegro-fixes-and-new-features/20200219-202330
base: git://linuxtv.org/media_tree.git master
config: c6x-allyesconfig (attached as .config)
compiler: c6x-elf-gcc (GCC) 7.5.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.5.0 make.cross ARCH=c6x
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/staging/media/allegro-dvt/allegro-core.c: In function 'allegro_channel_finish_frame':
>> drivers/staging/media/allegro-dvt/allegro-core.c:1591:6: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
^
drivers/staging/media/allegro-dvt/allegro-core.c:1591:41: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
^
drivers/staging/media/allegro-dvt/allegro-core.c: In function 'allegro_device_run':
drivers/staging/media/allegro-dvt/allegro-core.c:2964:71: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, (u64)dst_buf);
^
drivers/staging/media/allegro-dvt/allegro-core.c:2971:61: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv, (u64)src_buf);
^
vim +1591 drivers/staging/media/allegro-dvt/allegro-core.c
1572
1573 static void allegro_channel_finish_frame(struct allegro_channel *channel,
1574 struct mcu_msg_encode_frame_response *msg)
1575 {
1576 struct allegro_dev *dev = channel->dev;
1577 struct vb2_v4l2_buffer *src_buf;
1578 struct vb2_v4l2_buffer *dst_buf;
1579 struct {
1580 u32 offset;
1581 u32 size;
1582 } *partition;
1583 enum vb2_buffer_state state = VB2_BUF_STATE_ERROR;
1584 char *curr;
1585 ssize_t len;
1586 ssize_t free;
1587
1588 src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx);
1589 dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
1590
> 1591 if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
1592 v4l2_err(&dev->v4l2_dev,
1593 "channel %d: check failed\n",
1594 channel->mcu_channel_id);
1595
1596 dst_buf->sequence = channel->csequence++;
1597
1598 if (msg->error_code & AL_ERROR) {
1599 v4l2_err(&dev->v4l2_dev,
1600 "channel %d: failed to encode frame: %s (%x)\n",
1601 channel->mcu_channel_id,
1602 allegro_err_to_string(msg->error_code),
1603 msg->error_code);
1604 goto err;
1605 }
1606
1607 if (msg->partition_table_size != 1) {
1608 v4l2_warn(&dev->v4l2_dev,
1609 "channel %d: only handling first partition table entry (%d entries)\n",
1610 channel->mcu_channel_id, msg->partition_table_size);
1611 }
1612
1613 if (msg->partition_table_offset +
1614 msg->partition_table_size * sizeof(*partition) >
1615 vb2_plane_size(&dst_buf->vb2_buf, 0)) {
1616 v4l2_err(&dev->v4l2_dev,
1617 "channel %d: partition table outside of dst_buf\n",
1618 channel->mcu_channel_id);
1619 goto err;
1620 }
1621
1622 partition =
1623 vb2_plane_vaddr(&dst_buf->vb2_buf, 0) + msg->partition_table_offset;
1624 if (partition->offset + partition->size >
1625 vb2_plane_size(&dst_buf->vb2_buf, 0)) {
1626 v4l2_err(&dev->v4l2_dev,
1627 "channel %d: encoded frame is outside of dst_buf (offset 0x%x, size 0x%x)\n",
1628 channel->mcu_channel_id, partition->offset,
1629 partition->size);
1630 goto err;
1631 }
1632
1633 v4l2_dbg(2, debug, &dev->v4l2_dev,
1634 "channel %d: encoded frame of size %d is at offset 0x%x\n",
1635 channel->mcu_channel_id, partition->size, partition->offset);
1636
1637 /*
1638 * The payload must include the data before the partition offset,
1639 * because we will put the sps and pps data there.
1640 */
1641 vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
1642 partition->offset + partition->size);
1643
1644 curr = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
1645 free = partition->offset;
1646 if (msg->is_idr) {
1647 len = allegro_h264_write_sps(channel, curr, free);
1648 if (len < 0) {
1649 v4l2_err(&dev->v4l2_dev,
1650 "not enough space for sequence parameter set: %zd left\n",
1651 free);
1652 goto err;
1653 }
1654 curr += len;
1655 free -= len;
1656 v4l2_dbg(1, debug, &dev->v4l2_dev,
1657 "channel %d: wrote %zd byte SPS nal unit\n",
1658 channel->mcu_channel_id, len);
1659 }
1660
1661 if (msg->slice_type == AL_ENC_SLICE_TYPE_I) {
1662 len = allegro_h264_write_pps(channel, curr, free);
1663 if (len < 0) {
1664 v4l2_err(&dev->v4l2_dev,
1665 "not enough space for picture parameter set: %zd left\n",
1666 free);
1667 goto err;
1668 }
1669 curr += len;
1670 free -= len;
1671 v4l2_dbg(1, debug, &dev->v4l2_dev,
1672 "channel %d: wrote %zd byte PPS nal unit\n",
1673 channel->mcu_channel_id, len);
1674 }
1675
1676 if (msg->slice_type != AL_ENC_SLICE_TYPE_I && !msg->is_idr) {
1677 dst_buf->vb2_buf.planes[0].data_offset = free;
1678 free = 0;
1679 } else {
1680 len = nal_h264_write_filler(&dev->plat_dev->dev, curr, free);
1681 if (len < 0) {
1682 v4l2_err(&dev->v4l2_dev,
1683 "failed to write %zd filler data\n", free);
1684 goto err;
1685 }
1686 curr += len;
1687 free -= len;
1688 v4l2_dbg(2, debug, &dev->v4l2_dev,
1689 "channel %d: wrote %zd bytes filler nal unit\n",
1690 channel->mcu_channel_id, len);
1691 }
1692
1693 if (free != 0) {
1694 v4l2_err(&dev->v4l2_dev,
1695 "non-VCL NAL units do not fill space until VCL NAL unit: %zd bytes left\n",
1696 free);
1697 goto err;
1698 }
1699
1700 state = VB2_BUF_STATE_DONE;
1701
1702 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
1703 if (msg->is_idr)
1704 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1705 else
1706 dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
1707
1708 v4l2_dbg(1, debug, &dev->v4l2_dev,
1709 "channel %d: encoded frame #%03d (%s%s, QP %d, %d bytes)\n",
1710 channel->mcu_channel_id,
1711 dst_buf->sequence,
1712 msg->is_idr ? "IDR, " : "",
1713 msg->slice_type == AL_ENC_SLICE_TYPE_I ? "I slice" :
1714 msg->slice_type == AL_ENC_SLICE_TYPE_P ? "P slice" : "unknown",
1715 msg->qp, partition->size);
1716
1717 err:
1718 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1719
1720 allegro_channel_buf_done(channel, dst_buf, state);
1721
1722 v4l2_m2m_job_finish(dev->m2m_dev, channel->fh.m2m_ctx);
1723 }
1724
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 51587 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 16/18] media: allegro: pass buffers through firmware
2020-02-17 15:13 ` [PATCH 16/18] media: allegro: pass buffers through firmware Michael Tretter
@ 2020-02-25 14:09 ` Hans Verkuil
2020-03-03 15:40 ` Michael Tretter
0 siblings, 1 reply; 26+ messages in thread
From: Hans Verkuil @ 2020-02-25 14:09 UTC (permalink / raw)
To: Michael Tretter, linux-media; +Cc: kernel
On 2/17/20 4:13 PM, Michael Tretter wrote:
> 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 <m.tretter@pengutronix.de>
> ---
> .../staging/media/allegro-dvt/allegro-core.c | 104 +++++++++++++++---
> 1 file changed, 89 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
> index 4f525920c194..80d3383b84f8 100644
> --- a/drivers/staging/media/allegro-dvt/allegro-core.c
> +++ b/drivers/staging/media/allegro-dvt/allegro-core.c
> @@ -226,6 +226,10 @@ 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;
> + struct mutex shadow_list_lock;
This lock is never used in interrupt context, right? Just checking.
Also add a comment explaining what the lock protects.
> +
> struct list_head list;
> struct completion completion;
>
> @@ -247,6 +251,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;
> @@ -1570,6 +1582,43 @@ 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 (u64) buffer;
> +}
> +
> +static struct vb2_v4l2_buffer *allegro_get_buffer(struct allegro_channel *channel,
> + struct list_head *list,
> + u64 handle)
> +{
> + struct allegro_dev *dev = channel->dev;
> + struct allegro_m2m_buffer *shadow;
> + u64 found;
> +
> + mutex_lock(&channel->shadow_list_lock);
> + shadow = list_first_entry(list, struct allegro_m2m_buffer, head);
> + list_del_init(&shadow->head);
> + mutex_unlock(&channel->shadow_list_lock);
> +
> + found = (u64) (&shadow->buf.vb);
> + if (handle != found)
> + v4l2_warn(&dev->v4l2_dev,
> + "channel %d: output buffer mismatch 0x%llx, expected 0x%llx\n",
> + channel->mcu_channel_id, handle, found);
> +
> + return &shadow->buf.vb;
This function never returns NULL...
> +}
> +
> static void allegro_channel_finish_frame(struct allegro_channel *channel,
> struct mcu_msg_encode_frame_response *msg)
> {
> @@ -1585,13 +1634,17 @@ 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);
> - dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
> + src_buf = allegro_get_buffer(channel, &channel->source_shadow_list, msg->src_handle);
> + if (!src_buf)
...but this it checked here...
> + v4l2_warn(&dev->v4l2_dev,
> + "channel %d: invalid source buffer\n",
> + channel->mcu_channel_id);
>
> - if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
> - v4l2_err(&dev->v4l2_dev,
> - "channel %d: check failed\n",
> - channel->mcu_channel_id);
> + dst_buf = allegro_get_buffer(channel, &channel->stream_shadow_list, msg->stream_id);
> + if (!dst_buf)
...and here. That doesn't look right.
> + v4l2_warn(&dev->v4l2_dev,
> + "channel %d: invalid stream buffer\n",
> + channel->mcu_channel_id);
>
> dst_buf->sequence = channel->csequence++;
>
> @@ -1718,8 +1771,6 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
> 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);
> }
>
> static int allegro_handle_init(struct allegro_dev *dev,
> @@ -2312,16 +2363,31 @@ 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);
> @@ -2352,7 +2418,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)
> @@ -2365,7 +2431,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)
> @@ -2457,6 +2523,9 @@ static int allegro_open(struct file *file)
> v4l2_fh_add(&channel->fh);
>
> 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;
>
> @@ -2957,18 +3026,23 @@ 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);
> - allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, (u64)dst_buf);
> + dst_handle = allegro_put_buffer(channel, &channel->stream_shadow_list, dst_buf);
> + allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, 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, (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 = {
>
Regards,
Hans
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 14/18] media: allegro: handle dependency of bitrate and bitrate_peak
2020-02-17 15:13 ` [PATCH 14/18] media: allegro: handle dependency of bitrate and bitrate_peak Michael Tretter
@ 2020-02-25 14:14 ` Hans Verkuil
0 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2020-02-25 14:14 UTC (permalink / raw)
To: Michael Tretter, linux-media; +Cc: kernel
On 2/17/20 4:13 PM, Michael Tretter wrote:
> 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 <m.tretter@pengutronix.de>
> ---
> drivers/staging/media/allegro-dvt/allegro-core.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
> index 8c26158eab93..cedb09ea649f 100644
> --- a/drivers/staging/media/allegro-dvt/allegro-core.c
> +++ b/drivers/staging/media/allegro-dvt/allegro-core.c
> @@ -2403,9 +2403,15 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
> break;
> case V4L2_CID_MPEG_VIDEO_BITRATE:
> channel->bitrate = ctrl->val;
> + if (channel->bitrate > channel->bitrate_peak)
> + __v4l2_ctrl_s_ctrl(channel->mpeg_video_bitrate_peak,
> + channel->bitrate);
> break;
> case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
> channel->bitrate_peak = ctrl->val;
> + if (channel->bitrate_peak < channel->bitrate)
> + __v4l2_ctrl_s_ctrl(channel->mpeg_video_bitrate,
> + channel->bitrate_peak);
> break;
> case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
> channel->cpb_size = ctrl->val;
>
In the case of controls that are depend on one another you use a
control cluster and implement try_ctrl. See e.g. drivers/media/usb/hdpvr/hdpvr-video.c
which does the same thing.
Documentation on control clusters is here:
https://hverkuil.home.xs4all.nl/spec/kapi/v4l2-controls.html#control-clusters
Regards,
Hans
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 00/18] media: allegro: fixes and new features
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
` (17 preceding siblings ...)
2020-02-17 15:13 ` [PATCH 18/18] media: allegro: create new struct for channel parameters Michael Tretter
@ 2020-02-25 14:20 ` Hans Verkuil
2020-03-03 15:42 ` Michael Tretter
18 siblings, 1 reply; 26+ messages in thread
From: Hans Verkuil @ 2020-02-25 14:20 UTC (permalink / raw)
To: Michael Tretter, linux-media; +Cc: kernel
On 2/17/20 4:13 PM, Michael Tretter wrote:
> Hello,
>
> these are a several patches for the allegro-dvt driver that have piled up over
> the last few month while I was improving my understanding of the codec.
>
> Patches 1 to 9 fix errors in the interaction with the mcu. This includes
> better interpretation of return values from the firmware, wrong fields in the
> mails, wrong values in the fields and an error when resetting the mcu.
>
> Patches 10 to 14 wire up more controls and allow user space applications to
> control the framerate and the quality of the codec.
>
> Patches 15 and 16 enable the firmware to take care of the buffer scheduling
> and allow more parallelism inside the firmware. Please have a close look at
> patch 16, because it changes the behavior of the driver to finish the m2m_job
> before the driver returns the v4l2_buffers.
>
> Patches 17 and 18 start work to restructure how to create the mails that are
> sent to the firmware, because different firmware versions expect different
> mail formats and, thus, I need additional code to generate mails if I want to
> support different firmware versions.
Posted comments for patches 14 and 16. Also note the 'kbuild test robot' post for
patch 15.
I also get a number of warnings/checks when checkpatch.pl --strict over the
patch series (and even one ERROR). Some can be ignored, but there are others
that can be easily fixed with some reformatting.
Regards,
Hans
>
> This is the v4l-compliance test result:
>
> v4l2-compliance SHA: b62d322d4401e6b6e5cbd78cedad9eb69dac1324, 64 bits, 64-bit time_t
>
> Compliance test for allegro device /dev/video3:
>
> Driver Info:
> Driver name : allegro
> Card type : Allegro DVT Video Encoder
> Bus info : platform:a0009000.video-codec
> Driver version : 5.6.0
> Capabilities : 0x84208000
> Video Memory-to-Memory
> Streaming
> Extended Pix Format
> Device Capabilities
> Device Caps : 0x04208000
> Video Memory-to-Memory
> Streaming
> Extended Pix Format
> Detected Stateful Encoder
>
> Required ioctls:
> test VIDIOC_QUERYCAP: OK
>
> Allow for multiple opens:
> test second /dev/video3 open: OK
> test VIDIOC_QUERYCAP: OK
> test VIDIOC_G/S_PRIORITY: OK
> test for unlimited opens: OK
>
> test invalid ioctls: OK
> Debug ioctls:
> test VIDIOC_DBG_G/S_REGISTER: OK
> test VIDIOC_LOG_STATUS: OK (Not Supported)
>
> Input ioctls:
> test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> test VIDIOC_ENUMAUDIO: OK (Not Supported)
> test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDIO: OK (Not Supported)
> Inputs: 0 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
> test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Input/Output configuration ioctls:
> test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> test VIDIOC_G/S_EDID: OK (Not Supported)
>
> Control ioctls:
> test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> test VIDIOC_QUERYCTRL: OK
> test VIDIOC_G/S_CTRL: OK
> test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> Standard Controls: 16 Private Controls: 0
>
> Format ioctls:
> test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> warn: v4l2-test-formats.cpp(1329): S_PARM is supported for buftype 2, but not for ENUM_FRAMEINTERVALS
> test VIDIOC_G/S_PARM: OK
> test VIDIOC_G_FBUF: OK (Not Supported)
> test VIDIOC_G_FMT: OK
> test VIDIOC_TRY_FMT: OK
> test VIDIOC_S_FMT: OK
> test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> test Cropping: OK (Not Supported)
> test Composing: OK (Not Supported)
> test Scaling: OK (Not Supported)
>
> Codec ioctls:
> test VIDIOC_(TRY_)ENCODER_CMD: OK
> test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>
> Buffer ioctls:
> test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> test VIDIOC_EXPBUF: OK
> test Requests: OK (Not Supported)
>
> Test input 0:
>
> Streaming ioctls:
> test read/write: OK (Not Supported)
> test blocking wait: OK
> Video Capture: Captured 59 buffers
> test MMAP (select): OK
> Video Capture: Captured 59 buffers
> test MMAP (epoll): OK
> test USERPTR (select): OK (Not Supported)
> test DMABUF: Cannot test, specify --expbuf-device
>
> Total for allegro device /dev/video3: 50, Succeeded: 50, Failed: 0, Warnings: 1
>
> Michael
>
> Michael Tretter (18):
> media: allegro: print message on mcu error
> media: allegro: fail encoding only on actual errors
> media: allegro: fix type of gop_length in channel_create message
> media: allegro: remove unknown39 field from create_channel
> media: allegro: start a GOP with an IDR frame
> media: allegro: fix calculation of CPB size
> media: allegro: fix reset if WAKEUP has not been set properly
> media: allegro: extract mcu and codec address calculation
> media: allegro: warn if response message has an unexpected size
> media: allegro: skip filler data if possible
> media: allegro: make frame rate configurable
> media: allegro: make QP configurable
> media: allegro: read bitrate mode directly from control
> media: allegro: handle dependency of bitrate and bitrate_peak
> media: allegro: verify source and destination buffer in VCU response
> media: allegro: pass buffers through firmware
> media: allegro: move mail definitions to separate file
> media: allegro: create new struct for channel parameters
>
> drivers/staging/media/allegro-dvt/Makefile | 2 +-
> .../staging/media/allegro-dvt/allegro-core.c | 808 ++++++++++--------
> .../staging/media/allegro-dvt/allegro-mail.c | 37 +
> .../staging/media/allegro-dvt/allegro-mail.h | 267 ++++++
> 4 files changed, 738 insertions(+), 376 deletions(-)
> create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.c
> create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.h
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 16/18] media: allegro: pass buffers through firmware
2020-02-25 14:09 ` Hans Verkuil
@ 2020-03-03 15:40 ` Michael Tretter
0 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-03-03 15:40 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media, kernel
On Tue, 25 Feb 2020 15:09:37 +0100, Hans Verkuil wrote:
> On 2/17/20 4:13 PM, Michael Tretter wrote:
> > 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 <m.tretter@pengutronix.de>
> > ---
> > .../staging/media/allegro-dvt/allegro-core.c | 104 +++++++++++++++---
> > 1 file changed, 89 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
> > index 4f525920c194..80d3383b84f8 100644
> > --- a/drivers/staging/media/allegro-dvt/allegro-core.c
> > +++ b/drivers/staging/media/allegro-dvt/allegro-core.c
> > @@ -226,6 +226,10 @@ 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;
> > + struct mutex shadow_list_lock;
>
> This lock is never used in interrupt context, right? Just checking.
The lock is used from user threads and the threaded irq handler, but
not in an interrupt context.
>
> Also add a comment explaining what the lock protects.
Will do.
>
> > +
> > struct list_head list;
> > struct completion completion;
> >
> > @@ -247,6 +251,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;
> > @@ -1570,6 +1582,43 @@ 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 (u64) buffer;
> > +}
> > +
> > +static struct vb2_v4l2_buffer *allegro_get_buffer(struct allegro_channel *channel,
> > + struct list_head *list,
> > + u64 handle)
> > +{
> > + struct allegro_dev *dev = channel->dev;
> > + struct allegro_m2m_buffer *shadow;
> > + u64 found;
> > +
> > + mutex_lock(&channel->shadow_list_lock);
> > + shadow = list_first_entry(list, struct allegro_m2m_buffer, head);
> > + list_del_init(&shadow->head);
> > + mutex_unlock(&channel->shadow_list_lock);
> > +
> > + found = (u64) (&shadow->buf.vb);
> > + if (handle != found)
> > + v4l2_warn(&dev->v4l2_dev,
> > + "channel %d: output buffer mismatch 0x%llx, expected 0x%llx\n",
> > + channel->mcu_channel_id, handle, found);
> > +
> > + return &shadow->buf.vb;
>
> This function never returns NULL...
>
> > +}
> > +
> > static void allegro_channel_finish_frame(struct allegro_channel *channel,
> > struct mcu_msg_encode_frame_response *msg)
> > {
> > @@ -1585,13 +1634,17 @@ 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);
> > - dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
> > + src_buf = allegro_get_buffer(channel, &channel->source_shadow_list, msg->src_handle);
> > + if (!src_buf)
>
> ...but this it checked here...
>
> > + v4l2_warn(&dev->v4l2_dev,
> > + "channel %d: invalid source buffer\n",
> > + channel->mcu_channel_id);
> >
> > - if ((u64)src_buf != msg->src_handle || (u64)dst_buf != msg->stream_id)
> > - v4l2_err(&dev->v4l2_dev,
> > - "channel %d: check failed\n",
> > - channel->mcu_channel_id);
> > + dst_buf = allegro_get_buffer(channel, &channel->stream_shadow_list, msg->stream_id);
> > + if (!dst_buf)
>
> ...and here. That doesn't look right.
I started to implement error handling in case the firmware returns
wrong buffers, but I stopped at printing warnings and using the next
buffers anyway. I didn't really know what to do, if that happens,
because I don't have v4l2_buffers that I could return to user space to
report errors. Maybe it is best to keep buffers on the shadow queues,
print a warning, and ignore the message from the firmware.
I will fix allegro_get_buffer() to return NULL and properly fail in
these cases.
Thanks,
Michael
>
> > + v4l2_warn(&dev->v4l2_dev,
> > + "channel %d: invalid stream buffer\n",
> > + channel->mcu_channel_id);
> >
> > dst_buf->sequence = channel->csequence++;
> >
> > @@ -1718,8 +1771,6 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
> > 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);
> > }
> >
> > static int allegro_handle_init(struct allegro_dev *dev,
> > @@ -2312,16 +2363,31 @@ 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);
> > @@ -2352,7 +2418,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)
> > @@ -2365,7 +2431,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)
> > @@ -2457,6 +2523,9 @@ static int allegro_open(struct file *file)
> > v4l2_fh_add(&channel->fh);
> >
> > 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;
> >
> > @@ -2957,18 +3026,23 @@ 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);
> > - allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, (u64)dst_buf);
> > + dst_handle = allegro_put_buffer(channel, &channel->stream_shadow_list, dst_buf);
> > + allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size, 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, (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 = {
> >
>
> Regards,
>
> Hans
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 00/18] media: allegro: fixes and new features
2020-02-25 14:20 ` [PATCH 00/18] media: allegro: fixes and new features Hans Verkuil
@ 2020-03-03 15:42 ` Michael Tretter
0 siblings, 0 replies; 26+ messages in thread
From: Michael Tretter @ 2020-03-03 15:42 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media, kernel
On Tue, 25 Feb 2020 15:20:41 +0100, Hans Verkuil wrote:
> On 2/17/20 4:13 PM, Michael Tretter wrote:
> > Hello,
> >
> > these are a several patches for the allegro-dvt driver that have piled up over
> > the last few month while I was improving my understanding of the codec.
> >
> > Patches 1 to 9 fix errors in the interaction with the mcu. This includes
> > better interpretation of return values from the firmware, wrong fields in the
> > mails, wrong values in the fields and an error when resetting the mcu.
> >
> > Patches 10 to 14 wire up more controls and allow user space applications to
> > control the framerate and the quality of the codec.
> >
> > Patches 15 and 16 enable the firmware to take care of the buffer scheduling
> > and allow more parallelism inside the firmware. Please have a close look at
> > patch 16, because it changes the behavior of the driver to finish the m2m_job
> > before the driver returns the v4l2_buffers.
> >
> > Patches 17 and 18 start work to restructure how to create the mails that are
> > sent to the firmware, because different firmware versions expect different
> > mail formats and, thus, I need additional code to generate mails if I want to
> > support different firmware versions.
>
> Posted comments for patches 14 and 16. Also note the 'kbuild test robot' post for
> patch 15.
>
> I also get a number of warnings/checks when checkpatch.pl --strict over the
> patch series (and even one ERROR). Some can be ignored, but there are others
> that can be easily fixed with some reformatting.
Thanks. I totally forgot about checkpatch... I will fix the
warnings/checks in v2.
Michael
>
> Regards,
>
> Hans
>
> >
> > This is the v4l-compliance test result:
> >
> > v4l2-compliance SHA: b62d322d4401e6b6e5cbd78cedad9eb69dac1324, 64 bits, 64-bit time_t
> >
> > Compliance test for allegro device /dev/video3:
> >
> > Driver Info:
> > Driver name : allegro
> > Card type : Allegro DVT Video Encoder
> > Bus info : platform:a0009000.video-codec
> > Driver version : 5.6.0
> > Capabilities : 0x84208000
> > Video Memory-to-Memory
> > Streaming
> > Extended Pix Format
> > Device Capabilities
> > Device Caps : 0x04208000
> > Video Memory-to-Memory
> > Streaming
> > Extended Pix Format
> > Detected Stateful Encoder
> >
> > Required ioctls:
> > test VIDIOC_QUERYCAP: OK
> >
> > Allow for multiple opens:
> > test second /dev/video3 open: OK
> > test VIDIOC_QUERYCAP: OK
> > test VIDIOC_G/S_PRIORITY: OK
> > test for unlimited opens: OK
> >
> > test invalid ioctls: OK
> > Debug ioctls:
> > test VIDIOC_DBG_G/S_REGISTER: OK
> > test VIDIOC_LOG_STATUS: OK (Not Supported)
> >
> > Input ioctls:
> > test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> > test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> > test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> > test VIDIOC_ENUMAUDIO: OK (Not Supported)
> > test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> > test VIDIOC_G/S_AUDIO: OK (Not Supported)
> > Inputs: 0 Audio Inputs: 0 Tuners: 0
> >
> > Output ioctls:
> > test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> > test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> > test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> > test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> > test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> > Outputs: 0 Audio Outputs: 0 Modulators: 0
> >
> > Input/Output configuration ioctls:
> > test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> > test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> > test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> > test VIDIOC_G/S_EDID: OK (Not Supported)
> >
> > Control ioctls:
> > test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> > test VIDIOC_QUERYCTRL: OK
> > test VIDIOC_G/S_CTRL: OK
> > test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> > test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> > test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> > Standard Controls: 16 Private Controls: 0
> >
> > Format ioctls:
> > test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> > warn: v4l2-test-formats.cpp(1329): S_PARM is supported for buftype 2, but not for ENUM_FRAMEINTERVALS
> > test VIDIOC_G/S_PARM: OK
> > test VIDIOC_G_FBUF: OK (Not Supported)
> > test VIDIOC_G_FMT: OK
> > test VIDIOC_TRY_FMT: OK
> > test VIDIOC_S_FMT: OK
> > test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> > test Cropping: OK (Not Supported)
> > test Composing: OK (Not Supported)
> > test Scaling: OK (Not Supported)
> >
> > Codec ioctls:
> > test VIDIOC_(TRY_)ENCODER_CMD: OK
> > test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> > test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
> >
> > Buffer ioctls:
> > test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> > test VIDIOC_EXPBUF: OK
> > test Requests: OK (Not Supported)
> >
> > Test input 0:
> >
> > Streaming ioctls:
> > test read/write: OK (Not Supported)
> > test blocking wait: OK
> > Video Capture: Captured 59 buffers
> > test MMAP (select): OK
> > Video Capture: Captured 59 buffers
> > test MMAP (epoll): OK
> > test USERPTR (select): OK (Not Supported)
> > test DMABUF: Cannot test, specify --expbuf-device
> >
> > Total for allegro device /dev/video3: 50, Succeeded: 50, Failed: 0, Warnings: 1
> >
> > Michael
> >
> > Michael Tretter (18):
> > media: allegro: print message on mcu error
> > media: allegro: fail encoding only on actual errors
> > media: allegro: fix type of gop_length in channel_create message
> > media: allegro: remove unknown39 field from create_channel
> > media: allegro: start a GOP with an IDR frame
> > media: allegro: fix calculation of CPB size
> > media: allegro: fix reset if WAKEUP has not been set properly
> > media: allegro: extract mcu and codec address calculation
> > media: allegro: warn if response message has an unexpected size
> > media: allegro: skip filler data if possible
> > media: allegro: make frame rate configurable
> > media: allegro: make QP configurable
> > media: allegro: read bitrate mode directly from control
> > media: allegro: handle dependency of bitrate and bitrate_peak
> > media: allegro: verify source and destination buffer in VCU response
> > media: allegro: pass buffers through firmware
> > media: allegro: move mail definitions to separate file
> > media: allegro: create new struct for channel parameters
> >
> > drivers/staging/media/allegro-dvt/Makefile | 2 +-
> > .../staging/media/allegro-dvt/allegro-core.c | 808 ++++++++++--------
> > .../staging/media/allegro-dvt/allegro-mail.c | 37 +
> > .../staging/media/allegro-dvt/allegro-mail.h | 267 ++++++
> > 4 files changed, 738 insertions(+), 376 deletions(-)
> > create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.c
> > create mode 100644 drivers/staging/media/allegro-dvt/allegro-mail.h
> >
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2020-03-03 15:42 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-17 15:13 [PATCH 00/18] media: allegro: fixes and new features Michael Tretter
2020-02-17 15:13 ` [PATCH 01/18] media: allegro: print message on mcu error Michael Tretter
2020-02-17 15:13 ` [PATCH 02/18] media: allegro: fail encoding only on actual errors Michael Tretter
2020-02-17 15:13 ` [PATCH 03/18] media: allegro: fix type of gop_length in channel_create message Michael Tretter
2020-02-17 15:13 ` [PATCH 04/18] media: allegro: remove unknown39 field from create_channel Michael Tretter
2020-02-17 15:13 ` [PATCH 05/18] media: allegro: start a GOP with an IDR frame Michael Tretter
2020-02-17 15:13 ` [PATCH 06/18] media: allegro: fix calculation of CPB size Michael Tretter
2020-02-17 15:13 ` [PATCH 07/18] media: allegro: fix reset if WAKEUP has not been set properly Michael Tretter
2020-02-17 15:13 ` [PATCH 08/18] media: allegro: extract mcu and codec address calculation Michael Tretter
2020-02-17 15:13 ` [PATCH 09/18] media: allegro: warn if response message has an unexpected size Michael Tretter
2020-02-17 15:13 ` [PATCH 10/18] media: allegro: skip filler data if possible Michael Tretter
2020-02-17 15:13 ` [PATCH 11/18] media: allegro: make frame rate configurable Michael Tretter
2020-02-17 15:13 ` [PATCH 12/18] media: allegro: make QP configurable Michael Tretter
2020-02-17 15:13 ` [PATCH 13/18] media: allegro: read bitrate mode directly from control Michael Tretter
2020-02-17 15:13 ` [PATCH 14/18] media: allegro: handle dependency of bitrate and bitrate_peak Michael Tretter
2020-02-25 14:14 ` Hans Verkuil
2020-02-17 15:13 ` [PATCH 15/18] media: allegro: verify source and destination buffer in VCU response Michael Tretter
2020-02-19 15:41 ` kbuild test robot
2020-02-19 15:41 ` kbuild test robot
2020-02-17 15:13 ` [PATCH 16/18] media: allegro: pass buffers through firmware Michael Tretter
2020-02-25 14:09 ` Hans Verkuil
2020-03-03 15:40 ` Michael Tretter
2020-02-17 15:13 ` [PATCH 17/18] media: allegro: move mail definitions to separate file Michael Tretter
2020-02-17 15:13 ` [PATCH 18/18] media: allegro: create new struct for channel parameters Michael Tretter
2020-02-25 14:20 ` [PATCH 00/18] media: allegro: fixes and new features Hans Verkuil
2020-03-03 15:42 ` Michael Tretter
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.