diff options
author | Benoit Parrot <bparrot@ti.com> | 2019-09-11 12:04:27 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@iki.fi> | 2019-09-16 09:19:45 +0300 |
commit | 339e794dc14740d3628bac988e33e48d20551df4 (patch) | |
tree | c0512d2b303cf5e4e2ecaaa9c440306cdfa00290 /kms++util | |
parent | a5545df02b40414c2bf3abc60cf629c5f59d00ec (diff) |
videodevice: handle NV12 <-> NM12 translation
V4L2 and DRM differ in their interpretation of YUV420::NV12
V4L2 NV12 is a Y and UV co-located planes in a single plane buffer.
DRM NV12 is a Y and UV planes presented as dual plane buffer, which is
known as NM12 in V4L2.
Since here we have hybrid DRM/V4L2 user space helper functions we need
to translate DRM::NV12 to V4L2:NM12 pixel format back and forth to keep
the data view consistent.
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Diffstat (limited to 'kms++util')
-rw-r--r-- | kms++util/src/videodevice.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/kms++util/src/videodevice.cpp b/kms++util/src/videodevice.cpp index cc11357..23f45d4 100644 --- a/kms++util/src/videodevice.cpp +++ b/kms++util/src/videodevice.cpp @@ -15,6 +15,18 @@ using namespace std; using namespace kms; +/* + * V4L2 and DRM differ in their interpretation of YUV420::NV12 + * + * V4L2 NV12 is a Y and UV co-located planes in a single plane buffer. + * DRM NV12 is a Y and UV planes presented as dual plane buffer, + * which is known as NM12 in V4L2. + * + * Since here we have hybrid DRM/V4L2 user space helper functions + * we need to translate DRM::NV12 to V4L2:NM12 pixel format back + * and forth to keep the data view consistent. + */ + /* V4L2 helper funcs */ static vector<PixelFormat> v4l2_get_formats(int fd, uint32_t buf_type) { @@ -24,7 +36,11 @@ static vector<PixelFormat> v4l2_get_formats(int fd, uint32_t buf_type) desc.type = buf_type; while (ioctl(fd, VIDIOC_ENUM_FMT, &desc) == 0) { - v.push_back((PixelFormat)desc.pixelformat); + if (desc.pixelformat == V4L2_PIX_FMT_NV12M) + v.push_back(PixelFormat::NV12); + else if (desc.pixelformat != V4L2_PIX_FMT_NV12) + v.push_back((PixelFormat)desc.pixelformat); + desc.index++; } @@ -47,8 +63,14 @@ static void v4l2_set_format(int fd, PixelFormat fmt, uint32_t width, uint32_t he if (mplane) { v4l2_pix_format_mplane& mp = v4lfmt.fmt.pix_mp; + uint32_t used_fmt; + + if (fmt == PixelFormat::NV12) + used_fmt = V4L2_PIX_FMT_NV12M; + else + used_fmt = (uint32_t)fmt; - mp.pixelformat = (uint32_t)fmt; + mp.pixelformat = used_fmt; mp.width = width; mp.height = height; @@ -65,7 +87,7 @@ static void v4l2_set_format(int fd, PixelFormat fmt, uint32_t width, uint32_t he r = ioctl(fd, VIDIOC_S_FMT, &v4lfmt); ASSERT(r == 0); - ASSERT(mp.pixelformat == (uint32_t)fmt); + ASSERT(mp.pixelformat == used_fmt); ASSERT(mp.width == width); ASSERT(mp.height == height); |