-
-
Notifications
You must be signed in to change notification settings - Fork 248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support for YUV420 and YVU variants. #276
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,7 +39,8 @@ | |
#define US_VIDEO_MAX_FPS ((uint)120) | ||
|
||
#define US_STANDARDS_STR "PAL, NTSC, SECAM" | ||
#define US_FORMATS_STR "YUYV, YVYU, UYVY, RGB565, RGB24, BGR24, MJPEG, JPEG" | ||
#define US_FORMATS_STR "YUYV, YVYU, UYVY, YU12, YV12," | ||
#define US_FORMATS2_STR "RGB565, RGB24, BGR24, MJPEG, JPEG" | ||
Comment on lines
+42
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do it in one line, as it was before. I'll think about how to form this list beautifully automatically, but then. |
||
#define US_IO_METHODS_STR "MMAP, USERPTR" | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,7 @@ | |
|
||
|
||
#include "encoder.h" | ||
|
||
#include "../../../libs/logging.h" | ||
|
||
typedef struct { | ||
struct jpeg_destination_mgr mgr; // Default manager | ||
|
@@ -38,6 +38,7 @@ typedef struct { | |
static void _jpeg_set_dest_frame(j_compress_ptr jpeg, us_frame_s *frame); | ||
|
||
static void _jpeg_write_scanlines_yuv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); | ||
static void _jpeg_write_scanlines_yuv_planar(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); | ||
static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); | ||
static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); | ||
#ifndef JCS_EXTENSIONS | ||
|
@@ -69,9 +70,11 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned q | |
switch (src->format) { | ||
case V4L2_PIX_FMT_YUYV: | ||
case V4L2_PIX_FMT_YVYU: | ||
case V4L2_PIX_FMT_UYVY: jpeg.in_color_space = JCS_YCbCr; break; | ||
case V4L2_PIX_FMT_UYVY: | ||
case V4L2_PIX_FMT_YUV420: | ||
case V4L2_PIX_FMT_YVU420: jpeg.in_color_space = JCS_YCbCr; break; | ||
# ifdef JCS_EXTENSIONS | ||
case V4L2_PIX_FMT_BGR24: jpeg.in_color_space = JCS_EXT_BGR; break; | ||
case V4L2_PIX_FMT_BGR24: jpeg.in_color_space = JCS_EXT_BGR; break; | ||
# endif | ||
default: jpeg.in_color_space = JCS_RGB; break; | ||
} | ||
|
@@ -85,7 +88,9 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned q | |
// https://www.fourcc.org/yuv.php | ||
case V4L2_PIX_FMT_YUYV: | ||
case V4L2_PIX_FMT_YVYU: | ||
case V4L2_PIX_FMT_UYVY: _jpeg_write_scanlines_yuv(&jpeg, src); break; | ||
case V4L2_PIX_FMT_UYVY: _jpeg_write_scanlines_yuv(&jpeg, src); break; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see why this line changed?.. |
||
case V4L2_PIX_FMT_YUV420: | ||
case V4L2_PIX_FMT_YVU420: _jpeg_write_scanlines_yuv_planar(&jpeg, src); break; | ||
case V4L2_PIX_FMT_RGB565: _jpeg_write_scanlines_rgb565(&jpeg, src); break; | ||
case V4L2_PIX_FMT_RGB24: _jpeg_write_scanlines_rgb24(&jpeg, src); break; | ||
case V4L2_PIX_FMT_BGR24: | ||
|
@@ -167,6 +172,62 @@ static void _jpeg_write_scanlines_yuv(struct jpeg_compress_struct *jpeg, const u | |
free(line_buf); | ||
} | ||
|
||
static void _jpeg_write_scanlines_yuv_planar(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { | ||
uint8_t *line_buf; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
US_CALLOC(line_buf, frame->width * 3); | ||
|
||
US_LOG_DEBUG("Using Planar Encoder"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you really need logging here? |
||
const unsigned padding = us_frame_get_padding(frame); | ||
const uint image_size = frame->width * frame->height; | ||
const uint chroma_array_size = (frame->used - image_size) / 2; | ||
const uint chroma_matrix_order = (image_size / chroma_array_size) == 16 ? 4 : 2; | ||
US_LOG_DEBUG("Planar data: Image Size %u, Chroma Array Size %u, Chroma Matrix Order %u", image_size, chroma_array_size, chroma_matrix_order); | ||
const uint8_t *data = frame->data; | ||
const uint8_t *chroma1_data = frame->data + image_size; | ||
const uint8_t *chroma2_data = frame->data + image_size + chroma_array_size; | ||
|
||
while (jpeg->next_scanline < frame->height) { | ||
uint8_t *ptr = line_buf; | ||
|
||
for (unsigned x = 0; x < frame->width; ++x) { | ||
// See also: https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-yuv420.html | ||
uint8_t y = data[x], u, v; | ||
uint chroma_position = x / chroma_matrix_order; | ||
|
||
switch (frame->format) { | ||
case V4L2_PIX_FMT_YUV420: | ||
u = chroma1_data[chroma_position]; | ||
v = chroma2_data[chroma_position]; | ||
break; | ||
case V4L2_PIX_FMT_YVU420: | ||
u = chroma2_data[chroma_position]; | ||
v = chroma1_data[chroma_position]; | ||
break; | ||
default: | ||
assert(0 && "Unsupported pixel format"); | ||
return; // Makes linter happy | ||
} | ||
|
||
ptr[0] = y; | ||
ptr[1] = u; | ||
ptr[2] = v; | ||
ptr += 3; | ||
} | ||
|
||
data += frame->width + padding; | ||
|
||
if( jpeg->next_scanline > 0 && jpeg->next_scanline % chroma_matrix_order == 0 ){ | ||
chroma1_data += (frame->width + padding) / chroma_matrix_order; | ||
chroma2_data += (frame->width + padding) / chroma_matrix_order; | ||
} | ||
|
||
JSAMPROW scanlines[1] = {line_buf}; | ||
jpeg_write_scanlines(jpeg, scanlines, 1); | ||
} | ||
|
||
free(line_buf); | ||
} | ||
|
||
static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { | ||
uint8_t *line_buf; | ||
US_CALLOC(line_buf, frame->width * 3); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -377,7 +377,7 @@ int options_parse(us_options_s *options, us_capture_s *cap, us_encoder_s *enc, u | |
case _O_RESOLUTION: OPT_RESOLUTION("--resolution", cap->width, cap->height, true); | ||
# pragma GCC diagnostic ignored "-Wsign-compare" | ||
# pragma GCC diagnostic push | ||
case _O_FORMAT: OPT_PARSE_ENUM("pixel format", cap->format, us_capture_parse_format, US_FORMATS_STR); | ||
case _O_FORMAT: OPT_PARSE_ENUM("pixel format", cap->format, us_capture_parse_format, US_FORMATS_STR " " US_FORMATS2_STR); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Single macro, as mentioned. |
||
# pragma GCC diagnostic pop | ||
case _O_FORMAT_SWAP_RGB: OPT_SET(cap->format_swap_rgb, true); | ||
case _O_TV_STANDARD: OPT_PARSE_ENUM("TV standard", cap->standard, us_capture_parse_standard, US_STANDARDS_STR); | ||
|
@@ -621,7 +621,9 @@ static void _help(FILE *fp, const us_capture_s *cap, const us_encoder_s *enc, co | |
SAY(" -i|--input <N> ────────────────────── Input channel. Default: %u.\n", cap->input); | ||
SAY(" -r|--resolution <WxH> ─────────────── Initial image resolution. Default: %ux%u.\n", cap->width, cap->height); | ||
SAY(" -m|--format <fmt> ─────────────────── Image format."); | ||
SAY(" Available: %s; default: YUYV.\n", US_FORMATS_STR); | ||
SAY(" Available: %s", US_FORMATS_STR); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Single macro, as mentioned. |
||
SAY(" %s;", US_FORMATS2_STR); | ||
SAY(" Default: YUYV.\n"); | ||
SAY(" --format-swap-rgb ──────────────── Enable R-G-B order swapping: RGB to BGR and vice versa."); | ||
SAY(" Default: disabled.\n"); | ||
SAY(" -a|--tv-standard <std> ────────────── Force TV standard."); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this, there is no point to log resolution because it was reported earlier on configuration stage and didn't changing while working.