Skip to content

Commit 7e4b8cd

Browse files
committed
helpers: Use opaque buffers where possible
In some situations, there is no direct mapping of a pisp image format to a V4L2 pixelformat. In such cases, use a generic/opaque buffer format (which happens to be a YUV444 multiplanar format), appropriately sized to fit the image contents. Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
1 parent cc26a86 commit 7e4b8cd

4 files changed

Lines changed: 45 additions & 15 deletions

File tree

src/helpers/backend_device.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ BackendDevice::~BackendDevice()
3030
nodes_.at("pispbe-config").StreamOff();
3131
}
3232

33-
void BackendDevice::Setup(const pisp_be_tiles_config &config, unsigned int buffer_count)
33+
void BackendDevice::Setup(const pisp_be_tiles_config &config, unsigned int buffer_count, bool use_opaque_format)
3434
{
3535
nodes_enabled_.clear();
3636

3737
if ((config.config.global.rgb_enables & PISP_BE_RGB_ENABLE_INPUT) ||
3838
(config.config.global.bayer_enables & PISP_BE_BAYER_ENABLE_INPUT))
3939
{
40-
nodes_.at("pispbe-input").SetFormat(config.config.input_format);
40+
nodes_.at("pispbe-input").SetFormat(config.config.input_format, use_opaque_format);
4141
// Release old/allocate a single buffer.
4242
nodes_.at("pispbe-input").ReturnBuffers();
4343
nodes_.at("pispbe-input").RequestBuffers(buffer_count);
@@ -46,7 +46,7 @@ void BackendDevice::Setup(const pisp_be_tiles_config &config, unsigned int buffe
4646

4747
if (config.config.global.rgb_enables & PISP_BE_RGB_ENABLE_OUTPUT0)
4848
{
49-
nodes_.at("pispbe-output0").SetFormat(config.config.output_format[0].image);
49+
nodes_.at("pispbe-output0").SetFormat(config.config.output_format[0].image, use_opaque_format);
5050
// Release old/allocate a single buffer.
5151
nodes_.at("pispbe-output0").ReturnBuffers();
5252
nodes_.at("pispbe-output0").RequestBuffers(buffer_count);
@@ -55,7 +55,7 @@ void BackendDevice::Setup(const pisp_be_tiles_config &config, unsigned int buffe
5555

5656
if (config.config.global.rgb_enables & PISP_BE_RGB_ENABLE_OUTPUT1)
5757
{
58-
nodes_.at("pispbe-output1").SetFormat(config.config.output_format[1].image);
58+
nodes_.at("pispbe-output1").SetFormat(config.config.output_format[1].image, use_opaque_format);
5959
// Release old/allocate a single buffer.
6060
nodes_.at("pispbe-output1").ReturnBuffers();
6161
nodes_.at("pispbe-output1").RequestBuffers(buffer_count);
@@ -64,7 +64,7 @@ void BackendDevice::Setup(const pisp_be_tiles_config &config, unsigned int buffe
6464

6565
if (config.config.global.bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT)
6666
{
67-
nodes_.at("pispbe-tdn_output").SetFormat(config.config.tdn_output_format);
67+
nodes_.at("pispbe-tdn_output").SetFormat(config.config.tdn_output_format, use_opaque_format);
6868
// Release old/allocate a single buffer.
6969
nodes_.at("pispbe-tdn_output").ReturnBuffers();
7070
nodes_.at("pispbe-tdn_output").RequestBuffers(buffer_count);
@@ -73,7 +73,7 @@ void BackendDevice::Setup(const pisp_be_tiles_config &config, unsigned int buffe
7373

7474
if (config.config.global.bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_OUTPUT)
7575
{
76-
nodes_.at("pispbe-stitch_output").SetFormat(config.config.stitch_output_format);
76+
nodes_.at("pispbe-stitch_output").SetFormat(config.config.stitch_output_format, use_opaque_format);
7777
// Release old/allocate a single buffer.
7878
nodes_.at("pispbe-stitch_output").ReturnBuffers();
7979
nodes_.at("pispbe-stitch_output").RequestBuffers(buffer_count);

src/helpers/backend_device.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class BackendDevice
2222
BackendDevice(const std::string &device);
2323
~BackendDevice();
2424

25-
void Setup(const pisp_be_tiles_config &config, unsigned int buffer_count = 1);
25+
void Setup(const pisp_be_tiles_config &config, unsigned int buffer_count = 1, bool use_opaque_format = false);
2626
int Run(const std::map<std::string, V4l2Device::Buffer> &buffers);
2727

2828
bool Valid() const

src/helpers/v4l2_device.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
using namespace libpisp::helpers;
2525

26+
namespace {
27+
2628
struct FormatInfo
2729
{
2830
unsigned int v4l2_pixfmt;
@@ -48,6 +50,8 @@ static FormatInfo get_v4l2_format(const std::string &format)
4850
return it->second;
4951
}
5052

53+
} // namespace
54+
5155
V4l2Device::V4l2Device(const std::string &device)
5256
: fd_(device, O_RDWR | O_NONBLOCK | O_CLOEXEC), num_memory_planes_(1)
5357
{
@@ -226,13 +230,11 @@ int V4l2Device::DequeueBuffer(unsigned int timeout_ms)
226230
return buf.index;
227231
}
228232

229-
void V4l2Device::SetFormat(const pisp_image_format_config &format)
233+
void V4l2Device::SetFormat(const pisp_image_format_config &format, bool use_opaque_format)
230234
{
231235
struct v4l2_format f = {};
232236
FormatInfo info = get_v4l2_format(libpisp::get_pisp_image_format(format.format));
233237

234-
assert(info.v4l2_pixfmt);
235-
236238
num_memory_planes_ = info.num_memory_planes;
237239

238240
f.type = buf_type_;
@@ -242,10 +244,38 @@ void V4l2Device::SetFormat(const pisp_image_format_config &format)
242244
f.fmt.pix_mp.field = V4L2_FIELD_NONE;
243245
f.fmt.pix_mp.num_planes = num_memory_planes_;
244246

245-
for (unsigned int p = 0; p < num_memory_planes_; p++)
247+
unsigned int num_image_planes = libpisp::num_planes((pisp_image_format)format.format);
248+
249+
if (use_opaque_format || info.v4l2_pixfmt == 0)
250+
{
251+
// This format is not specified by V4L2, we use an opaque buffer buffer as a workaround.
252+
// Size the dimensions down so the kernel drive does not attempt to resize it.
253+
f.fmt.pix_mp.width = 16;
254+
f.fmt.pix_mp.height = 16;
255+
f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV444M;
256+
num_memory_planes_ = 3;
257+
f.fmt.pix_mp.plane_fmt[0].bytesperline = format.stride;
258+
259+
f.fmt.pix_mp.plane_fmt[0].sizeimage = 0;
260+
for (unsigned int i = 0; i < 3; i++)
261+
f.fmt.pix_mp.plane_fmt[0].sizeimage += libpisp::get_plane_size(format, i);
262+
263+
f.fmt.pix_mp.plane_fmt[1].sizeimage = f.fmt.pix_mp.plane_fmt[2].sizeimage = f.fmt.pix_mp.plane_fmt[0].sizeimage;
264+
f.fmt.pix_mp.plane_fmt[1].bytesperline = f.fmt.pix_mp.plane_fmt[2].bytesperline = format.stride2;
265+
}
266+
else
246267
{
247-
f.fmt.pix_mp.plane_fmt[p].bytesperline = p == 0 ? format.stride : format.stride2;
248-
f.fmt.pix_mp.plane_fmt[p].sizeimage = 0;
268+
unsigned int p = 0;
269+
for (; p < num_memory_planes_; p++)
270+
{
271+
const unsigned int stride = p == 0 ? format.stride : format.stride2;
272+
// Wallpaper stride is not something the V4L2 kernel knows about!
273+
f.fmt.pix_mp.plane_fmt[p].bytesperline = stride;
274+
f.fmt.pix_mp.plane_fmt[p].sizeimage = libpisp::get_plane_size(format, p);
275+
}
276+
277+
for (; p < num_image_planes; p++)
278+
f.fmt.pix_mp.plane_fmt[num_memory_planes_ - 1].sizeimage += libpisp::get_plane_size(format, p);
249279
}
250280

251281
int ret = ioctl(fd_.Get(), VIDIOC_S_FMT, &f);

src/helpers/v4l2_device.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class V4l2Device
5757
}
5858

5959
Buffer(const v4l2_buffer& buf)
60-
: buffer(buf), size({}), mem({})
60+
: buffer(buf), size({}), mem({})
6161
{
6262
}
6363

@@ -79,7 +79,7 @@ class V4l2Device
7979
int QueueBuffer(unsigned int index);
8080
int DequeueBuffer(unsigned int timeout_ms = 500);
8181

82-
void SetFormat(const pisp_image_format_config &format);
82+
void SetFormat(const pisp_image_format_config &format, bool use_opaque_format = false);
8383

8484
void StreamOn();
8585
void StreamOff();

0 commit comments

Comments
 (0)