From patchwork Mon Jan 21 18:56:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 10774409 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2BD2A91E for ; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19E7A29915 for ; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E41129D73; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0422929915 for ; Mon, 21 Jan 2019 18:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727338AbfAUS5V (ORCPT ); Mon, 21 Jan 2019 13:57:21 -0500 Received: from mail-wr1-f66.google.com ([209.85.221.66]:41176 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726575AbfAUS5U (ORCPT ); Mon, 21 Jan 2019 13:57:20 -0500 Received: by mail-wr1-f66.google.com with SMTP id x10so24590448wrs.8 for ; Mon, 21 Jan 2019 10:57:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ijCwH6DqnatoJm1xHFsdAVtYROaAMTdNO3FcfPqQE4w=; b=BMtj1wHpb31KW1h6sjfHIq0SSmv3MfJyv0hErCp3KLG2FpNUr8jqsSPiloS0FiDd5i QbgX2FSSkMIba2VANybjaGh0GGeXU/5KNi6TfBUYsKa5/IJBs7cq7VogHSYvi7g/d+ts YRjb6NUDJWIaH/T/ydEJYTe+cKSMNUXX4zVYJyXlBWyd9P8gDDYylArNT/yQf2juhY6f AbVGaBSpU7qAJ8FpG5EM1uWaro9/1tJCLMUtc0RCnE6iQIKbmiFRN8jLqsmOvZGbZ+4g XEVBZ064Ziie//0RrN5QFbQQGQGUfzfXpbqCg0WsdzBff/W8j4CURGhp3oSYTE9kTy2i J9Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ijCwH6DqnatoJm1xHFsdAVtYROaAMTdNO3FcfPqQE4w=; b=hIm4QRdCl32zl+gpoMMVFW8UjrpwPDCvhxKe0FtUgQVScHEz2t6DWuhUH31i2tb3RB OyOnJWontgHms9KiCTkFLzjmYCKtzbGB9MBJtGHaAgvzaqFKi+KET90J1mAAcHXrWbFn Lz1sTgbj7ZQwajKdF+kFxW8BdictSO3L45Cn8/NbHHrn3DUPtAvmBt0TKxJ3Qu0Kd04R QpXnncmQa4GCp5hkk1pS7K9L9DIq3YNSgtuL5hM5pXzVoMSPSmJ/IVPW3XYctHMsRB+A BqAV76KzNQsaw6kAuU0oh1QxJbfiUaRisqz/Tzh/wSCTgAKAxDytLXDKU/qJfxZR2+ZI 8ErA== X-Gm-Message-State: AJcUukdiVZad7IJ20LxZW5Xox8oy/dvG0LdcCxsAz2OuPAcejxH35UVj SyCKI68Ux3ULeEnU4DzDDHH9J+5Y9Ts= X-Google-Smtp-Source: ALg8bN49IUEkV5s+GjgtALFQ7H1lAGWagnpZmVSXVQOy2kiM310PPKMD4akw9xaiPlz96sqwSm6jXQ== X-Received: by 2002:adf:f9cb:: with SMTP id w11mr28842737wrr.201.1548097037211; Mon, 21 Jan 2019 10:57:17 -0800 (PST) Received: from localhost.localdomain ([87.70.46.65]) by smtp.gmail.com with ESMTPSA id 67sm145061521wra.37.2019.01.21.10.57.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Jan 2019 10:57:16 -0800 (PST) From: Dafna Hirschfeld To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, helen.koike@collabora.com, Dafna Hirschfeld Subject: [v4l-utils PATCH v2 1/5] v4l2-ctl: Add support for crop and compose selection in streaming Date: Mon, 21 Jan 2019 10:56:47 -0800 Message-Id: <20190121185651.6229-2-dafna3@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190121185651.6229-1-dafna3@gmail.com> References: <20190121185651.6229-1-dafna3@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Support crop and compose selection. If the driver supports crop/compose then the raw frame is arranged inside a padded buffer. Signed-off-by: Dafna Hirschfeld --- utils/common/codec-fwht.patch | 8 +- utils/common/v4l-stream.c | 14 +-- utils/common/v4l-stream.h | 6 +- utils/qvidcap/capture.cpp | 2 + utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 141 ++++++++++++++++++++++++-- 5 files changed, 150 insertions(+), 21 deletions(-) diff --git a/utils/common/codec-fwht.patch b/utils/common/codec-fwht.patch index 4d41225b..37ac4672 100644 --- a/utils/common/codec-fwht.patch +++ b/utils/common/codec-fwht.patch @@ -1,6 +1,6 @@ ---- a/utils/common/codec-fwht.h.old 2018-11-23 13:43:52.713731559 +0100 -+++ b/utils/common/codec-fwht.h 2018-11-23 13:47:55.484198283 +0100 -@@ -8,8 +8,24 @@ +--- a/utils/common/codec-fwht.h.old 2018-12-29 11:23:58.128328613 -0800 ++++ b/utils/common/codec-fwht.h 2018-12-29 11:24:16.099127560 -0800 +@@ -8,8 +8,26 @@ #define CODEC_FWHT_H #include @@ -17,6 +17,8 @@ +#define GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> ((8 * sizeof(long)) - 1 - (h)))) +#define pr_err(arg...) ++#define __round_mask(x, y) ((__typeof__(x))((y)-1)) ++#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) + + +typedef __u32 u32; diff --git a/utils/common/v4l-stream.c b/utils/common/v4l-stream.c index 9f842e21..a1cabadb 100644 --- a/utils/common/v4l-stream.c +++ b/utils/common/v4l-stream.c @@ -171,25 +171,28 @@ unsigned rle_compress(__u8 *b, unsigned size, unsigned bpl) return (__u8 *)dst - b; } -struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned w, unsigned h, +struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned visible_width, unsigned visible_height, + unsigned coded_width, unsigned coded_height, unsigned field, unsigned colorspace, unsigned xfer_func, unsigned ycbcr_enc, unsigned quantization) { struct codec_ctx *ctx; const struct v4l2_fwht_pixfmt_info *info = v4l2_fwht_find_pixfmt(pixfmt); unsigned int chroma_div; - unsigned int size = w * h; + unsigned int size = coded_width * coded_height; // fwht expects macroblock alignment, check can be dropped once that // restriction is lifted. - if (!info || w % 8 || h % 8) + if (!info || coded_width % 8 || coded_height % 8) return NULL; ctx = malloc(sizeof(*ctx)); if (!ctx) return NULL; - ctx->state.width = w; - ctx->state.height = h; + ctx->state.coded_width = coded_width; + ctx->state.coded_height = coded_height; + ctx->state.visible_width = visible_width; + ctx->state.visible_height = visible_height; ctx->state.info = info; ctx->field = field; ctx->state.colorspace = colorspace; @@ -208,7 +211,6 @@ struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned w, unsigned h, free(ctx); return NULL; } - ctx->state.ref_frame.width = ctx->state.ref_frame.height = 0; ctx->state.ref_frame.cb = ctx->state.ref_frame.luma + size; ctx->state.ref_frame.cr = ctx->state.ref_frame.cb + size / chroma_div; ctx->state.ref_frame.alpha = ctx->state.ref_frame.cr + size / chroma_div; diff --git a/utils/common/v4l-stream.h b/utils/common/v4l-stream.h index c235150b..fe5dfe90 100644 --- a/utils/common/v4l-stream.h +++ b/utils/common/v4l-stream.h @@ -9,12 +9,13 @@ #define _V4L_STREAM_H_ #include -#include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#include + /* Default port */ #define V4L_STREAM_PORT 8362 @@ -145,7 +146,8 @@ struct codec_ctx { unsigned rle_compress(__u8 *buf, unsigned size, unsigned bytesperline); void rle_decompress(__u8 *buf, unsigned size, unsigned rle_size, unsigned bytesperline); -struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned w, unsigned h, unsigned field, +struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned visible_width, unsigned visible_height, + unsigned coded_width, unsigned coded_height, unsigned field, unsigned colorspace, unsigned xfer_func, unsigned ycbcr_enc, unsigned quantization); void fwht_free(struct codec_ctx *ctx); diff --git a/utils/qvidcap/capture.cpp b/utils/qvidcap/capture.cpp index 8c11ac53..e04db6be 100644 --- a/utils/qvidcap/capture.cpp +++ b/utils/qvidcap/capture.cpp @@ -749,6 +749,7 @@ void CaptureWin::setModeSocket(int socket, int port) if (m_ctx) free(m_ctx); m_ctx = fwht_alloc(m_v4l_fmt.g_pixelformat(), m_v4l_fmt.g_width(), m_v4l_fmt.g_height(), + m_v4l_fmt.g_width(), m_v4l_fmt.g_height(), m_v4l_fmt.g_field(), m_v4l_fmt.g_colorspace(), m_v4l_fmt.g_xfer_func(), m_v4l_fmt.g_ycbcr_enc(), m_v4l_fmt.g_quantization()); @@ -1114,6 +1115,7 @@ void CaptureWin::listenForNewConnection() if (m_ctx) free(m_ctx); m_ctx = fwht_alloc(fmt.g_pixelformat(), fmt.g_width(), fmt.g_height(), + fmt.g_width(), fmt.g_height(), fmt.g_field(), fmt.g_colorspace(), fmt.g_xfer_func(), fmt.g_ycbcr_enc(), fmt.g_quantization()); setPixelAspect(pixelaspect); diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index 79e015ce..8a98b6bd 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -20,7 +20,6 @@ #include "v4l2-ctl.h" #include "v4l-stream.h" -#include "codec-fwht.h" extern "C" { #include "v4l2-tpg.h" @@ -73,6 +72,13 @@ static unsigned bpl_out[VIDEO_MAX_PLANES]; static bool last_buffer = false; static codec_ctx *ctx; +static unsigned int cropped_width; +static unsigned int cropped_height; +static unsigned int composed_width; +static unsigned int composed_height; +static bool support_cap_compose; +static bool support_out_crop; + #define TS_WINDOW 241 #define FILE_HDR_ID v4l2_fourcc('V', 'h', 'd', 'r') @@ -657,7 +663,60 @@ void streaming_cmd(int ch, char *optarg) } } -static bool fill_buffer_from_file(cv4l_queue &q, cv4l_buffer &b, FILE *fin) +static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf, + FILE *fpointer, unsigned &sz, + unsigned &len, bool is_read) +{ + const struct v4l2_fwht_pixfmt_info *vic_fmt = v4l2_fwht_find_pixfmt(fmt.g_pixelformat()); + unsigned coded_height = fmt.g_height(); + unsigned real_width; + unsigned real_height; + unsigned char *plane_p = buf; + unsigned char *row_p; + + if (is_read) { + real_width = cropped_width; + real_height = cropped_height; + } else { + real_width = composed_width; + real_height = composed_height; + } + + sz = 0; + len = real_width * real_height * vic_fmt->sizeimage_mult / vic_fmt->sizeimage_div; + + for (unsigned plane_idx = 0; plane_idx < vic_fmt->planes_num; plane_idx++) { + bool is_chroma_plane = plane_idx == 1 || plane_idx == 2; + unsigned h_div = is_chroma_plane ? vic_fmt->height_div : 1; + unsigned w_div = is_chroma_plane ? vic_fmt->width_div : 1; + unsigned step = is_chroma_plane ? vic_fmt->chroma_step : vic_fmt->luma_alpha_step; + unsigned stride_div = (vic_fmt->planes_num == 3 && plane_idx > 0) ? 2 : 1; + + row_p = plane_p; + for (unsigned i = 0; i < real_height / h_div; i++) { + unsigned int wsz = 0; + unsigned int consume_sz = step * real_width / w_div; + + if (is_read) + wsz = fread(row_p, 1, consume_sz, fpointer); + else + wsz = fwrite(row_p, 1, consume_sz, fpointer); + if (wsz == 0 && i == 0 && plane_idx == 0) + break; + if (wsz != consume_sz) { + fprintf(stderr, "padding: needed %u bytes, got %u\n", consume_sz, wsz); + return; + } + sz += wsz; + row_p += fmt.g_bytesperline() / stride_div; + } + plane_p += (fmt.g_bytesperline() / stride_div) * (coded_height / h_div); + if (sz == 0) + break; + } +} + +static bool fill_buffer_from_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &b, FILE *fin) { static bool first = true; static bool is_fwht = false; @@ -776,7 +835,9 @@ restart: void *buf = q.g_dataptr(b.g_index(), j); unsigned len = q.g_length(j); unsigned sz; + cv4l_fmt fmt; + fd.g_fmt(fmt, q.g_type()); if (from_with_hdr) { len = read_u32(fin); if (len > q.g_length(j)) { @@ -785,7 +846,12 @@ restart: return false; } } - sz = fread(buf, 1, len, fin); + + if (support_out_crop && v4l2_fwht_find_pixfmt(fmt.g_pixelformat())) + read_write_padded_frame(fmt, (unsigned char *)buf, fin, sz, len, true); + else + sz = fread(buf, 1, len, fin); + if (first && sz != len) { fprintf(stderr, "Insufficient data\n"); return false; @@ -908,7 +974,7 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf tpg_fillbuffer(&tpg, stream_out_std, j, (u8 *)q.g_dataptr(i, j)); } } - if (fin && !fill_buffer_from_file(q, buf, fin)) + if (fin && !fill_buffer_from_file(fd, q, buf, fin)) return -2; if (qbuf) { @@ -926,7 +992,7 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf return 0; } -static void write_buffer_to_file(cv4l_queue &q, cv4l_buffer &buf, FILE *fout) +static void write_buffer_to_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &buf, FILE *fout) { #ifndef NO_STREAM_TO unsigned comp_size[VIDEO_MAX_PLANES]; @@ -967,7 +1033,9 @@ static void write_buffer_to_file(cv4l_queue &q, cv4l_buffer &buf, FILE *fout) __u32 used = buf.g_bytesused(); unsigned offset = buf.g_data_offset(); unsigned sz; + cv4l_fmt fmt; + fd.g_fmt(fmt, q.g_type()); if (offset > used) { // Should never happen fprintf(stderr, "offset %d > used %d!\n", @@ -985,6 +1053,9 @@ static void write_buffer_to_file(cv4l_queue &q, cv4l_buffer &buf, FILE *fout) } if (host_fd_to >= 0) sz = fwrite(comp_ptr[j] + offset, 1, used, fout); + else if (support_cap_compose && v4l2_fwht_find_pixfmt(fmt.g_pixelformat())) + read_write_padded_frame(fmt, (u8 *)q.g_dataptr(buf.g_index(), j) + offset, + fout, sz, used, false); else sz = fwrite((u8 *)q.g_dataptr(buf.g_index(), j) + offset, 1, used, fout); @@ -1036,7 +1107,7 @@ static int do_handle_cap(cv4l_fd &fd, cv4l_queue &q, FILE *fout, int *index, if (fout && (!stream_skip || ignore_count_skip) && buf.g_bytesused(0) && !(buf.g_flags() & V4L2_BUF_FLAG_ERROR)) - write_buffer_to_file(q, buf, fout); + write_buffer_to_file(fd, q, buf, fout); if (buf.g_flags() & V4L2_BUF_FLAG_KEYFRAME) ch = 'K'; @@ -1135,7 +1206,7 @@ static int do_handle_out(cv4l_fd &fd, cv4l_queue &q, FILE *fin, cv4l_buffer *cap output_field = V4L2_FIELD_TOP; } - if (fin && !fill_buffer_from_file(q, buf, fin)) + if (fin && !fill_buffer_from_file(fd, q, buf, fin)) return -2; if (!fin && stream_out_refresh) { @@ -1333,10 +1404,15 @@ recover: write_u32(fout, cfmt.g_bytesperline(i)); bpl_cap[i] = rle_calc_bpl(cfmt.g_bytesperline(i), cfmt.g_pixelformat()); } - if (!host_lossless) - ctx = fwht_alloc(cfmt.g_pixelformat(), cfmt.g_width(), cfmt.g_height(), + if (!host_lossless) { + unsigned visible_width = support_cap_compose ? composed_width : cfmt.g_width(); + unsigned visible_height = support_cap_compose ? composed_height : cfmt.g_height(); + + ctx = fwht_alloc(cfmt.g_pixelformat(), visible_width, visible_height, + cfmt.g_width(), cfmt.g_height(), cfmt.g_field(), cfmt.g_colorspace(), cfmt.g_xfer_func(), cfmt.g_ycbcr_enc(), cfmt.g_quantization()); + } fflush(fout); } #endif @@ -1560,7 +1636,11 @@ static void streaming_set_out(cv4l_fd &fd) cfmt.s_quantization(read_u32(fin)); cfmt.s_xfer_func(read_u32(fin)); cfmt.s_flags(read_u32(fin)); - ctx = fwht_alloc(cfmt.g_pixelformat(), cfmt.g_width(), cfmt.g_height(), + unsigned visible_width = support_out_crop ? cropped_width : cfmt.g_width(); + unsigned visible_height = support_out_crop ? cropped_height : cfmt.g_height(); + + ctx = fwht_alloc(cfmt.g_pixelformat(), visible_width, visible_height, + cfmt.g_width(), cfmt.g_height(), cfmt.g_field(), cfmt.g_colorspace(), cfmt.g_xfer_func(), cfmt.g_ycbcr_enc(), cfmt.g_quantization()); @@ -2029,6 +2109,44 @@ done: fclose(file[OUT]); } +static int get_cap_compose_rect(cv4l_fd &fd) +{ + v4l2_selection sel; + + memset(&sel, 0, sizeof(sel)); + sel.type = vidcap_buftype; + sel.target = V4L2_SEL_TGT_COMPOSE; + + if (fd.g_selection(sel) == 0) { + support_cap_compose = true; + composed_width = sel.r.width; + composed_height = sel.r.height; + return 0; + } + + support_cap_compose = false; + return 0; +} + +static int get_out_crop_rect(cv4l_fd &fd) +{ + v4l2_selection sel; + + memset(&sel, 0, sizeof(sel)); + sel.type = vidout_buftype; + sel.target = V4L2_SEL_TGT_CROP; + + if (fd.g_selection(sel) == 0) { + support_out_crop = true; + cropped_width = sel.r.width; + cropped_height = sel.r.height; + return 0; + } + + support_out_crop = false; + return 0; +} + void streaming_set(cv4l_fd &fd, cv4l_fd &out_fd) { cv4l_disable_trace dt(fd); @@ -2036,6 +2154,9 @@ void streaming_set(cv4l_fd &fd, cv4l_fd &out_fd) int do_cap = options[OptStreamMmap] + options[OptStreamUser] + options[OptStreamDmaBuf]; int do_out = options[OptStreamOutMmap] + options[OptStreamOutUser] + options[OptStreamOutDmaBuf]; + get_cap_compose_rect(fd); + get_out_crop_rect(fd); + if (out_fd.g_fd() < 0) { out_capabilities = capabilities; out_priv_magic = priv_magic; From patchwork Mon Jan 21 18:56:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 10774407 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EE40A1390 for ; Mon, 21 Jan 2019 18:57:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD72329915 for ; Mon, 21 Jan 2019 18:57:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CEC1F29D73; Mon, 21 Jan 2019 18:57:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 662F329915 for ; Mon, 21 Jan 2019 18:57:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727189AbfAUS5V (ORCPT ); Mon, 21 Jan 2019 13:57:21 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:33509 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727152AbfAUS5U (ORCPT ); Mon, 21 Jan 2019 13:57:20 -0500 Received: by mail-wr1-f68.google.com with SMTP id c14so24684117wrr.0 for ; Mon, 21 Jan 2019 10:57:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kc+MSQlplxxDQET2NiFuk67i44zf7Qk+gKDf9xtPe8I=; b=vII7JBADj47g+sxdRqEYtpVFFEzgyMi2ljUUZm55kJKOb5CKIEXWxlZsqNp3wrAlhf 8cdp16jsKRxDib1NmH0JoSWHDzUQyo61Aec1fldlV6+KFNScIlPJtEf1IVYa5Yg64rtC BjaTRbiGnk/8g5iLuN3PVlRAxYEV9losEWJX6Hyes8pF1x7SF4S6tKo3zBtzosdUfPDA nVskSpmMrpGUjNe6i/wxffP/XBHiKoVp9hMBbBIMkjlicmhk5a6xQlPWzDhBW/dNBUN4 RzBQHQplU1pbW8XeJCLeCHl93/a1wZ2dgYOUS6WeJzrZl/64Ii730zDTLoPyS88l4dl6 UG9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kc+MSQlplxxDQET2NiFuk67i44zf7Qk+gKDf9xtPe8I=; b=Hcb1ea2QHkQI5mxDC80BzuTsdQXzCDNqgXAq/o7iSF2Gw7eA9nAIzqBukDgE5hqYEp SnAwU1i6AwQ8Ge1Q4eobkGhJ+wnc3yy5sAxTX7n2guFy/C4QGNYH+BUplUcuYzpNnn2e NoWlXyi+3K+0qDZP7X3657Ohdghtl1C9+6iIQNWwWWs4PSGpTIH1AK+4Fve6daQOUdb/ tu2O/FwEITjID1E/rPbl0DAmPPJhPrObc5C4jvGmkIcNxuEgEfY0m38nVQML7H0U5Vcr gHXsslUtgimMiPcZ/5X6ivmj8d+YwBgQW1xXfy2pipBYm7+NwD6RioZmDB5Z9PpQq8m5 BCyg== X-Gm-Message-State: AJcUukc9uQOvIh9yyno/4novJOdhQb7WglmCchb+W9M99KFFHvOGbHUg QwYP4SDG7pVMlMP+evn4fS2eu7IBNgE= X-Google-Smtp-Source: ALg8bN6kA+vKAzGjnHV43FvyA1nKie5bBW2ZYdj/mVfLRSpazKMmxP2t4hceVkSonghGLCYcbPuOaQ== X-Received: by 2002:adf:9168:: with SMTP id j95mr28747273wrj.217.1548097038475; Mon, 21 Jan 2019 10:57:18 -0800 (PST) Received: from localhost.localdomain ([87.70.46.65]) by smtp.gmail.com with ESMTPSA id 67sm145061521wra.37.2019.01.21.10.57.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Jan 2019 10:57:17 -0800 (PST) From: Dafna Hirschfeld To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, helen.koike@collabora.com, Dafna Hirschfeld Subject: [v4l-utils PATCH v2 2/5] v4l2-ctl: Add function get_codec_type Date: Mon, 21 Jan 2019 10:56:48 -0800 Message-Id: <20190121185651.6229-3-dafna3@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190121185651.6229-1-dafna3@gmail.com> References: <20190121185651.6229-1-dafna3@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add function get_codec_type that returns the type of codec NOT_CODEC/ENCODER/DEOCDER. Move the functions get_cap_compose/crop_rect to the start of the file. Signed-off-by: Dafna Hirschfeld --- utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 123 ++++++++++++++++++-------- 1 file changed, 85 insertions(+), 38 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index 8a98b6bd..1383c5f2 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -82,6 +82,12 @@ static bool support_out_crop; #define TS_WINDOW 241 #define FILE_HDR_ID v4l2_fourcc('V', 'h', 'd', 'r') +enum codec_type { + NOT_CODEC, + ENCODER, + DECODER +}; + class fps_timestamps { private: unsigned idx; @@ -334,6 +340,85 @@ void streaming_usage(void) V4L_STREAM_PORT); } +static enum codec_type get_codec_type(cv4l_fd &fd) +{ + struct v4l2_fmtdesc fmt_desc; + int num_cap_fmts = 0; + int num_compressed_cap_fmts = 0; + int num_out_fmts = 0; + int num_compressed_out_fmts = 0; + + if (!fd.has_vid_m2m()) + return NOT_CODEC; + + if (fd.enum_fmt(fmt_desc, true, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE)) + return NOT_CODEC; + + do { + if (fmt_desc.flags & V4L2_FMT_FLAG_COMPRESSED) + num_compressed_cap_fmts++; + num_cap_fmts++; + } while (!fd.enum_fmt(fmt_desc)); + + + if (fd.enum_fmt(fmt_desc, true, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT)) + return NOT_CODEC; + + do { + if (fmt_desc.flags & V4L2_FMT_FLAG_COMPRESSED) + num_compressed_out_fmts++; + num_out_fmts++; + } while (!fd.enum_fmt(fmt_desc)); + + if (num_compressed_out_fmts == 0 && num_compressed_cap_fmts == num_cap_fmts) { + return ENCODER; + } + + if (num_compressed_cap_fmts == 0 && num_compressed_out_fmts == num_out_fmts) { + return DECODER; + } + + return NOT_CODEC; +} + +static int get_cap_compose_rect(cv4l_fd &fd) +{ + v4l2_selection sel; + + memset(&sel, 0, sizeof(sel)); + sel.type = vidcap_buftype; + sel.target = V4L2_SEL_TGT_COMPOSE; + + if (fd.g_selection(sel) == 0) { + support_cap_compose = true; + composed_width = sel.r.width; + composed_height = sel.r.height; + return 0; + } + + support_cap_compose = false; + return 0; +} + +static int get_out_crop_rect(cv4l_fd &fd) +{ + v4l2_selection sel; + + memset(&sel, 0, sizeof(sel)); + sel.type = vidout_buftype; + sel.target = V4L2_SEL_TGT_CROP; + + if (fd.g_selection(sel) == 0) { + support_out_crop = true; + cropped_width = sel.r.width; + cropped_height = sel.r.height; + return 0; + } + + support_out_crop = false; + return 0; +} + static void set_time_stamp(cv4l_buffer &buf) { if ((buf.g_flags() & V4L2_BUF_FLAG_TIMESTAMP_MASK) != V4L2_BUF_FLAG_TIMESTAMP_COPY) @@ -2109,44 +2194,6 @@ done: fclose(file[OUT]); } -static int get_cap_compose_rect(cv4l_fd &fd) -{ - v4l2_selection sel; - - memset(&sel, 0, sizeof(sel)); - sel.type = vidcap_buftype; - sel.target = V4L2_SEL_TGT_COMPOSE; - - if (fd.g_selection(sel) == 0) { - support_cap_compose = true; - composed_width = sel.r.width; - composed_height = sel.r.height; - return 0; - } - - support_cap_compose = false; - return 0; -} - -static int get_out_crop_rect(cv4l_fd &fd) -{ - v4l2_selection sel; - - memset(&sel, 0, sizeof(sel)); - sel.type = vidout_buftype; - sel.target = V4L2_SEL_TGT_CROP; - - if (fd.g_selection(sel) == 0) { - support_out_crop = true; - cropped_width = sel.r.width; - cropped_height = sel.r.height; - return 0; - } - - support_out_crop = false; - return 0; -} - void streaming_set(cv4l_fd &fd, cv4l_fd &out_fd) { cv4l_disable_trace dt(fd); From patchwork Mon Jan 21 18:56:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 10774411 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DAD01575 for ; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B34B29915 for ; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F52429B5E; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2921929E39 for ; Mon, 21 Jan 2019 18:57:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727740AbfAUS5W (ORCPT ); Mon, 21 Jan 2019 13:57:22 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:55799 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727159AbfAUS5W (ORCPT ); Mon, 21 Jan 2019 13:57:22 -0500 Received: by mail-wm1-f68.google.com with SMTP id y139so11769412wmc.5 for ; Mon, 21 Jan 2019 10:57:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=j2Ro7FOdB8fUnLBTtNxgFEno/zfxzlxHXJY4sM0iMmE=; b=srBBe3lAHzoO9ZUQBGRT4GYOefJqK0vevHjaRh39KilA+gCxwdwBdZt0NDHCyO5dqp FQLWuiD8riTWw6u59c/lFrU1EmAnpNC/ug93qXXhB3bxs+2YdtT4jAomHnwyMqrv9kCq fO8Nywiq03JLRg48ReeM7vCHv6VxNFOeQMY8lYqsxUhHlFpY9SSS9PEy4llbjfmHv0M2 z4LEJhLP3oE7LJfBzZei892A1oFvqDCzOwsTxVBl5TMEPQbW7GIsV22qWNmDIGku/HRG Ec/yoHJS8iAyfuKua3WmC0/OUuuBG3OZxU5Y62OsHH+6gN36EoQId0+x8RN+097u5W0d IPcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=j2Ro7FOdB8fUnLBTtNxgFEno/zfxzlxHXJY4sM0iMmE=; b=X+Seh/MRuLdffGGRf6/Mo0TkzKky7yvoeJxcREEVKjqvdUbVhZt56zmZ9oSS+U8zUO 0YizwE142lNFigDqGEZ5nDxP5mkQm97UnU4hj4hC4UgIrqXBB7cfIW2GWgdV2bMWg5TZ VPMyYciUCvGbI2VyclFzD6KmSTGyMTLUMYgvSUvZzVvQMAylN3+6Fm8RHx/cJ2a+Skt7 x0FRZZq8hxgMWwoDBUqI46IILwZq4eG3Eur15rTonQVQhoGhSM2siqDFS/eW7CVrdWtE GsAUDaxvEC5DTq5YfCs279Z5y/m22JRtsemNh0FA5gbQNI4gs0eF32K3ADYWJA2Gbd7n msxg== X-Gm-Message-State: AJcUukdUZ+slFVnCqDjCoz43CHqEBoMa5GbYY9QuowqdCkSalUo1f827 zC1RbAT3KuYDjTc8TU7DpdJ3oCXtdLc= X-Google-Smtp-Source: ALg8bN5OwVhMU4W2/cql82+W6bF6bpev34M3EQ8AexE53fnx/byBvFHn+tr5POoIu8imFMQ9LVDr9w== X-Received: by 2002:a1c:a6c2:: with SMTP id p185mr491517wme.133.1548097039775; Mon, 21 Jan 2019 10:57:19 -0800 (PST) Received: from localhost.localdomain ([87.70.46.65]) by smtp.gmail.com with ESMTPSA id 67sm145061521wra.37.2019.01.21.10.57.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Jan 2019 10:57:19 -0800 (PST) From: Dafna Hirschfeld To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, helen.koike@collabora.com, Dafna Hirschfeld Subject: [v4l-utils PATCH v2 3/5] v4l2-ctl: Introduce capture_setup Date: Mon, 21 Jan 2019 10:56:49 -0800 Message-Id: <20190121185651.6229-4-dafna3@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190121185651.6229-1-dafna3@gmail.com> References: <20190121185651.6229-1-dafna3@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add function capture_setup that implements the capture setup sequence. Signed-off-by: Dafna Hirschfeld --- utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 46 ++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index 1383c5f2..d74a6c0b 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -1833,6 +1833,36 @@ enum stream_type { OUT, }; +static int capture_setup(cv4l_fd &fd, cv4l_queue &in) +{ + if (fd.streamoff(in.g_type())) { + fprintf(stderr, "%s: fd.streamoff error\n", __func__); + return -1; + } + get_cap_compose_rect(fd); + + /* release any buffer allocated */ + if (in.reqbufs(&fd)) { + fprintf(stderr, "%s: in.reqbufs 0 error\n", __func__); + return -1; + } + + if (in.reqbufs(&fd, reqbufs_count_cap)) { + fprintf(stderr, "%s: in.reqbufs %u error\n", __func__, + reqbufs_count_cap); + return -1; + } + if (in.obtain_bufs(&fd) || in.queue_all(&fd)) { + fprintf(stderr, "%s: in.obtain_bufs error\n", __func__); + return -1; + } + if (fd.streamon(in.g_type())) { + fprintf(stderr, "%s: fd.streamon error\n", __func__); + return -1; + } + return 0; +} + static void streaming_set_m2m(cv4l_fd &fd) { int fd_flags = fcntl(fd.g_fd(), F_GETFL); @@ -1897,21 +1927,21 @@ static void streaming_set_m2m(cv4l_fd &fd) } } - if (in.reqbufs(&fd, reqbufs_count_cap) || - out.reqbufs(&fd, reqbufs_count_out)) + if (out.reqbufs(&fd, reqbufs_count_out)) goto done; - if (in.obtain_bufs(&fd) || - in.queue_all(&fd) || - do_setup_out_buffers(fd, out, file[OUT], true)) + if (do_setup_out_buffers(fd, out, file[OUT], true)) goto done; - fps_ts[CAP].determine_field(fd.g_fd(), in.g_type()); - fps_ts[OUT].determine_field(fd.g_fd(), out.g_type()); + if (fd.streamon(out.g_type())) + goto done; - if (fd.streamon(in.g_type()) || fd.streamon(out.g_type())) + if (capture_setup(fd, in)) goto done; + fps_ts[CAP].determine_field(fd.g_fd(), in.g_type()); + fps_ts[OUT].determine_field(fd.g_fd(), out.g_type()); + while (stream_sleep == 0) sleep(100); From patchwork Mon Jan 21 18:56:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 10774415 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DE5D21390 for ; Mon, 21 Jan 2019 18:57:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB67F29915 for ; Mon, 21 Jan 2019 18:57:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF77729D73; Mon, 21 Jan 2019 18:57:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 097EB29B5E for ; Mon, 21 Jan 2019 18:57:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727869AbfAUS5Y (ORCPT ); Mon, 21 Jan 2019 13:57:24 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:32870 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727430AbfAUS5Y (ORCPT ); Mon, 21 Jan 2019 13:57:24 -0500 Received: by mail-wm1-f65.google.com with SMTP id r24so6829894wmh.0 for ; Mon, 21 Jan 2019 10:57:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=y1Vt+vupSml16wurFI+vB0XMni0wWuun1RPz8W5SZWk=; b=iKKtXfHg4LHfqNA1M0BHo0PH5DZ9ppMm18DOu3kVbe3KEgHuOh+rrH1zCVcSBkC/VR my1Zu74n5BqBeL4W0h8da5mxW71jrSAkUBOYWWWRqpAxFbnT9EyoeFjD/N39lI2+3YqB 4P80K5FZZMuAKt7piHISBbWy2ktq1ZzjrXFRoDgH/8uzVLWZgPTmYida8i+taS2VyDEs XeYbglhLnFV9A4DB/P9vmeJhY/Nx5rTWf6xP/4LMyZqidoOPRKB5im6TtwMTpg0VB2RS nt2toYP9Fr9WsBsIM47E1Kxb1JWcc8bmhS7zoeVfy3lkac3eJK5kBwWGiwi1TED6lW9I 50qw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=y1Vt+vupSml16wurFI+vB0XMni0wWuun1RPz8W5SZWk=; b=ofYiYk+hmLeAsRhx0wetTAA5uaX/D4WEp8yNGIZQ24mKVyUlWHAW/Bf1f8xtq15uy6 zMgKni3hZo5jaxt0hMRw8yc8cqZcBMwXTkHCD734WOIYiBh8Nk4j3hGhR8uW2yY02mcE nXR3a4KEaPzGcQmDZkx6mpPcalMsSQmP4OSDedPwwznlM2h1LGC32/RyNRXwSYwsSZ7s qVLsk1CCf7qX0vSexFzNsT4dLhknHwXNVlqR0XHTgVtNzTEvjz1uKnx56UFqHcSS7P+f rMSQv20Spx2ZryQIf+v8WtYJaBVyTL5ClpY/wLekSo74p4kbiqw63VNGS2yNDxrYznIK rCsQ== X-Gm-Message-State: AJcUuke7u6epxmvwaPOS2VeMhL4scb6SCZzmsMCiod707uHF5vCtTwqS s3843snt27U1v+vdTpwbEkfvcPR3hPo= X-Google-Smtp-Source: ALg8bN78KM6vBt8z5dv+D2lmSd7unNv5fOg3u5JJ55VBO20zJ7KxtTaj1oIX7JMI1Y2HkBIzl1FRcA== X-Received: by 2002:a1c:5fd7:: with SMTP id t206mr557135wmb.145.1548097041114; Mon, 21 Jan 2019 10:57:21 -0800 (PST) Received: from localhost.localdomain ([87.70.46.65]) by smtp.gmail.com with ESMTPSA id 67sm145061521wra.37.2019.01.21.10.57.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Jan 2019 10:57:20 -0800 (PST) From: Dafna Hirschfeld To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, helen.koike@collabora.com, Dafna Hirschfeld Subject: [v4l-utils PATCH v2 4/5] v4l2-ctl: Add support for source change event for m2m decoder Date: Mon, 21 Jan 2019 10:56:50 -0800 Message-Id: <20190121185651.6229-5-dafna3@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190121185651.6229-1-dafna3@gmail.com> References: <20190121185651.6229-1-dafna3@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Subscribe to source change event. The capture setup sequence is executed only due to a change event. Signed-off-by: Dafna Hirschfeld --- utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 112 +++++++++++++++++++------- 1 file changed, 85 insertions(+), 27 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index d74a6c0b..8d034b85 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -78,6 +78,7 @@ static unsigned int composed_width; static unsigned int composed_height; static bool support_cap_compose; static bool support_out_crop; +static bool in_source_change_event; #define TS_WINDOW 241 #define FILE_HDR_ID v4l2_fourcc('V', 'h', 'd', 'r') @@ -752,7 +753,8 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf, FILE *fpointer, unsigned &sz, unsigned &len, bool is_read) { - const struct v4l2_fwht_pixfmt_info *vic_fmt = v4l2_fwht_find_pixfmt(fmt.g_pixelformat()); + const struct v4l2_fwht_pixfmt_info *vic_fmt = + v4l2_fwht_find_pixfmt(fmt.g_pixelformat()); unsigned coded_height = fmt.g_height(); unsigned real_width; unsigned real_height; @@ -801,7 +803,8 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf, } } -static bool fill_buffer_from_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &b, FILE *fin) +static bool fill_buffer_from_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &b, + cv4l_fmt &fmt, FILE *fin) { static bool first = true; static bool is_fwht = false; @@ -1059,7 +1062,7 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf tpg_fillbuffer(&tpg, stream_out_std, j, (u8 *)q.g_dataptr(i, j)); } } - if (fin && !fill_buffer_from_file(fd, q, buf, fin)) + if (fin && !fill_buffer_from_file(fd, q, buf, fmt, fin)) return -2; if (qbuf) { @@ -1077,7 +1080,8 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf return 0; } -static void write_buffer_to_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &buf, FILE *fout) +static void write_buffer_to_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &buf, + cv4l_fmt &fmt, FILE *fout) { #ifndef NO_STREAM_TO unsigned comp_size[VIDEO_MAX_PLANES]; @@ -1118,9 +1122,7 @@ static void write_buffer_to_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &buf, F __u32 used = buf.g_bytesused(); unsigned offset = buf.g_data_offset(); unsigned sz; - cv4l_fmt fmt; - fd.g_fmt(fmt, q.g_type()); if (offset > used) { // Should never happen fprintf(stderr, "offset %d > used %d!\n", @@ -1153,7 +1155,7 @@ static void write_buffer_to_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &buf, F } static int do_handle_cap(cv4l_fd &fd, cv4l_queue &q, FILE *fout, int *index, - unsigned &count, fps_timestamps &fps_ts) + unsigned &count, fps_timestamps &fps_ts, cv4l_fmt &fmt) { char ch = '<'; int ret; @@ -1192,7 +1194,7 @@ static int do_handle_cap(cv4l_fd &fd, cv4l_queue &q, FILE *fout, int *index, if (fout && (!stream_skip || ignore_count_skip) && buf.g_bytesused(0) && !(buf.g_flags() & V4L2_BUF_FLAG_ERROR)) - write_buffer_to_file(fd, q, buf, fout); + write_buffer_to_file(fd, q, buf, fmt, fout); if (buf.g_flags() & V4L2_BUF_FLAG_KEYFRAME) ch = 'K'; @@ -1205,8 +1207,18 @@ static int do_handle_cap(cv4l_fd &fd, cv4l_queue &q, FILE *fout, int *index, host_fd_to >= 0 ? 100 - comp_perc / comp_perc_count : -1); comp_perc_count = comp_perc = 0; } - if (!last_buffer && index == NULL && fd.qbuf(buf)) - return -1; + if (!last_buffer && index == NULL) { + /* + * EINVAL in qbuf can happen if this is the last buffer before + * a dynamic resolution change sequence. In this case the buffer + * has the size that fits the old resolution and might not + * fit to the new one. + */ + if (fd.qbuf(buf) && errno != EINVAL) { + fprintf(stderr, "%s: qbuf error\n", __func__); + return -1; + } + } if (index) *index = buf.g_index(); @@ -1246,7 +1258,7 @@ static int do_handle_cap(cv4l_fd &fd, cv4l_queue &q, FILE *fout, int *index, } static int do_handle_out(cv4l_fd &fd, cv4l_queue &q, FILE *fin, cv4l_buffer *cap, - unsigned &count, fps_timestamps &fps_ts) + unsigned &count, fps_timestamps &fps_ts, cv4l_fmt fmt) { cv4l_buffer buf(q); int ret = 0; @@ -1291,7 +1303,7 @@ static int do_handle_out(cv4l_fd &fd, cv4l_queue &q, FILE *fin, cv4l_buffer *cap output_field = V4L2_FIELD_TOP; } - if (fin && !fill_buffer_from_file(fd, q, buf, fin)) + if (fin && !fill_buffer_from_file(fd, q, buf, fmt, fin)) return -2; if (!fin && stream_out_refresh) { @@ -1365,6 +1377,9 @@ static void streaming_set_cap(cv4l_fd &fd) bool eos; bool source_change; FILE *fout = NULL; + cv4l_fmt fmt; + + fd.g_fmt(fmt); if (!(capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | @@ -1573,7 +1588,7 @@ recover: if (FD_ISSET(fd.g_fd(), &read_fds)) { r = do_handle_cap(fd, q, fout, NULL, - count, fps_ts); + count, fps_ts, fmt); if (r == -1) break; } @@ -1605,6 +1620,9 @@ static void streaming_set_out(cv4l_fd &fd) fps_timestamps fps_ts; unsigned count = 0; FILE *fin = NULL; + cv4l_fmt fmt; + + fd.g_fmt(fmt); if (!(capabilities & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT | @@ -1806,7 +1824,7 @@ static void streaming_set_out(cv4l_fd &fd) } } r = do_handle_out(fd, q, fin, NULL, - count, fps_ts); + count, fps_ts, fmt); if (r == -1) break; @@ -1875,6 +1893,11 @@ static void streaming_set_m2m(cv4l_fd &fd) fd_set *rd_fds = &fds[0]; /* for capture */ fd_set *ex_fds = &fds[1]; /* for capture */ fd_set *wr_fds = &fds[2]; /* for output */ + bool cap_streaming = false; + cv4l_fmt fmt[2]; + + fd.g_fmt(fmt[OUT], out.g_type()); + fd.g_fmt(fmt[CAP], in.g_type()); if (!fd.has_vid_m2m()) { fprintf(stderr, "unsupported m2m stream type\n"); @@ -1897,6 +1920,10 @@ static void streaming_set_m2m(cv4l_fd &fd) bool have_eos = !fd.subscribe_event(sub); bool is_encoder = false; + enum codec_type codec_type = get_codec_type(fd); + + if (codec_type == NOT_CODEC) + goto done; if (have_eos) { cv4l_fmt fmt(in.g_type()); @@ -1905,6 +1932,11 @@ static void streaming_set_m2m(cv4l_fd &fd) is_encoder = !fmt.g_bytesperline(); } + memset(&sub, 0, sizeof(sub)); + sub.type = V4L2_EVENT_SOURCE_CHANGE; + if (fd.subscribe_event(sub)) + goto done; + if (file_to) { if (!strcmp(file_to, "-")) file[CAP] = stdout; @@ -1936,8 +1968,9 @@ static void streaming_set_m2m(cv4l_fd &fd) if (fd.streamon(out.g_type())) goto done; - if (capture_setup(fd, in)) - goto done; + if (codec_type == ENCODER) + if (capture_setup(fd, in)) + goto done; fps_ts[CAP].determine_field(fd.g_fd(), in.g_type()); fps_ts[OUT].determine_field(fd.g_fd(), out.g_type()); @@ -1982,7 +2015,7 @@ static void streaming_set_m2m(cv4l_fd &fd) if (rd_fds && FD_ISSET(fd.g_fd(), rd_fds)) { r = do_handle_cap(fd, in, file[CAP], NULL, - count[CAP], fps_ts[CAP]); + count[CAP], fps_ts[CAP], fmt[CAP]); if (r < 0) { rd_fds = NULL; if (!have_eos) { @@ -1990,13 +2023,11 @@ static void streaming_set_m2m(cv4l_fd &fd) break; } } - if (last_buffer) - break; } if (wr_fds && FD_ISSET(fd.g_fd(), wr_fds)) { r = do_handle_out(fd, out, file[OUT], NULL, - count[OUT], fps_ts[OUT]); + count[OUT], fps_ts[OUT], fmt[OUT]); if (r < 0) { wr_fds = NULL; @@ -2022,11 +2053,35 @@ static void streaming_set_m2m(cv4l_fd &fd) struct v4l2_event ev; while (!fd.dqevent(ev)) { - if (ev.type != V4L2_EVENT_EOS) - continue; - wr_fds = NULL; - fprintf(stderr, "EOS"); - fflush(stderr); + if (ev.type == V4L2_EVENT_EOS) { + wr_fds = NULL; + fprintf(stderr, "EOS"); + fflush(stderr); + } else if (ev.type == V4L2_EVENT_SOURCE_CHANGE) { + fprintf(stderr, "SOURCE CHANGE\n"); + in_source_change_event = true; + + /* + * if capture is not streaming, the + * driver will not send a last buffer so + * we set it here + */ + if (!cap_streaming) + last_buffer = true; + } + } + } + + if (last_buffer) { + if (in_source_change_event) { + in_source_change_event = false; + last_buffer = false; + if (capture_setup(fd, in)) + goto done; + fd.g_fmt(fmt[OUT], out.g_type()); + fd.g_fmt(fmt[CAP], in.g_type()); + cap_streaming = true; + } else { break; } } @@ -2063,7 +2118,10 @@ static void streaming_set_cap2out(cv4l_fd &fd, cv4l_fd &out_fd) FILE *file[2] = {NULL, NULL}; fd_set fds; unsigned cnt = 0; + cv4l_fmt fmt[2]; + fd.g_fmt(fmt[OUT], out.g_type()); + fd.g_fmt(fmt[CAP], in.g_type()); if (!(capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M | @@ -2179,7 +2237,7 @@ static void streaming_set_cap2out(cv4l_fd &fd, cv4l_fd &out_fd) int index = -1; r = do_handle_cap(fd, in, file[CAP], &index, - count[CAP], fps_ts[CAP]); + count[CAP], fps_ts[CAP], fmt[CAP]); if (r) fprintf(stderr, "handle cap %d\n", r); if (!r) { @@ -2188,7 +2246,7 @@ static void streaming_set_cap2out(cv4l_fd &fd, cv4l_fd &out_fd) if (fd.querybuf(buf)) break; r = do_handle_out(out_fd, out, file[OUT], &buf, - count[OUT], fps_ts[OUT]); + count[OUT], fps_ts[OUT], fmt[OUT]); } if (r) fprintf(stderr, "handle out %d\n", r); From patchwork Mon Jan 21 18:56:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 10774417 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1E7E01390 for ; Mon, 21 Jan 2019 18:57:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0CF6629915 for ; Mon, 21 Jan 2019 18:57:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 014EE29D73; Mon, 21 Jan 2019 18:57:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6797929915 for ; Mon, 21 Jan 2019 18:57:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727893AbfAUS5Z (ORCPT ); Mon, 21 Jan 2019 13:57:25 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38653 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727159AbfAUS5Z (ORCPT ); Mon, 21 Jan 2019 13:57:25 -0500 Received: by mail-wm1-f66.google.com with SMTP id m22so11922753wml.3 for ; Mon, 21 Jan 2019 10:57:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=l4uNpZvhrIuQIG9RNlb0MSWkIOACIDRPaSK5IKM0xzA=; b=GR+ZptN4yW6Kr/1jbIJAfe7Z6PQwSwfeYPcqcK0B71ijfrwDxll/S0zfNC4D5CPyjF +ZPtTbdKX7by4PUEqgnRNAWwjSzZ3ZIZ2TvQONvh9x3FTLyygMWKvvgBe4wdPR4QRx5t vPR8D3vNusGk+fbVZhZJxMgEiiV+F8skTUQ/ExJF/bWfu52rAIFh2TxJKTRGeOoTr+Ji G+Ps3BP6vaiw5/LjaGxR3mlhfm6hYLtDjtCrwjR2w9Q2Xr58A1eoCxz901j/RFfkpfZn /X1qFHlF2mZm877DSgk38UoOJx7iGr27odOIxw8S2pR/lznXbCTi8VjGjUVNlodbhr9U P/BQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=l4uNpZvhrIuQIG9RNlb0MSWkIOACIDRPaSK5IKM0xzA=; b=sAJbwt1nQug84FiipmkM+c+Nl8vrH/PQH9Sz8229r4xVBNqV7GrAKuYFykpqiYlBDW TbQX4gEl8RveQciFTmFYhf/SYgwTaE1i+RB0itq0Dx68gV+QhyVwCpKS53BCto11UXox NgCnmbeuD9h+hukrqXYZwh0DqLuRVRPdnATGl+8/d2rdBC5+QSPpDQlekEf8CVoDVfat z9oFSNEcC2KmNSPysyNdceeDYMMgXJ0AvDHNlHv9djKjJ3vF0jI6C0ERr7PW0TuUUg8R rboZD2mRDmey7T/qPNgDCTzv+5DRuY4Wq9FRrVcZ1lRU0BMr0oJZ5Y7/Kj5EHw818Xpg DOjA== X-Gm-Message-State: AJcUukf6OuH/IxWE9ExXC6ziekWb+ZPmrWhwoSdJntYqCV9fCKv0w1G1 E1rrjEuHnOHQNUW2I1D3+HdLRWAFjSA= X-Google-Smtp-Source: ALg8bN7sRw2Za2V4nC+bIPQXW1mw7zhd1HuUQ01aqCPHktW9dPjhNkarEQbn/VopWbuHtqn9vEHH8w== X-Received: by 2002:a1c:8c05:: with SMTP id o5mr533163wmd.29.1548097042520; Mon, 21 Jan 2019 10:57:22 -0800 (PST) Received: from localhost.localdomain ([87.70.46.65]) by smtp.gmail.com with ESMTPSA id 67sm145061521wra.37.2019.01.21.10.57.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Jan 2019 10:57:22 -0800 (PST) From: Dafna Hirschfeld To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, helen.koike@collabora.com, Dafna Hirschfeld Subject: [v4l-utils PATCH v2 5/5] v4l2-ctl: Add --stream-pixformat option Date: Mon, 21 Jan 2019 10:56:51 -0800 Message-Id: <20190121185651.6229-6-dafna3@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190121185651.6229-1-dafna3@gmail.com> References: <20190121185651.6229-1-dafna3@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This option sets the capture pixelformat in the capture setup sequence. If the format is not supported decoding will stop. If the option is not given then the default is to set the first supported format. Signed-off-by: Dafna Hirschfeld --- utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 37 +++++++++++++++++++++++++ utils/v4l2-ctl/v4l2-ctl.cpp | 39 ++++++++++++++++++--------- utils/v4l2-ctl/v4l2-ctl.h | 2 ++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index 8d034b85..3e0a449c 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -78,6 +78,7 @@ static unsigned int composed_width; static unsigned int composed_height; static bool support_cap_compose; static bool support_out_crop; +static unsigned int cap_pixelformat; static bool in_source_change_event; #define TS_WINDOW 241 @@ -272,6 +273,10 @@ void streaming_usage(void) " --stream-from \n" " stream from this file. The default is to generate a pattern.\n" " If is '-', then the data is read from stdin.\n" + " --stream-pixformat \n" + " set the video pixelformat." + " is either the format index as reported by\n" + " --list-formats-out, or the fourcc value as a string.\n" " --stream-from-hdr stream from this file. Same as --stream-from, but each\n" " frame is prefixed by a header. Use for compressed data.\n" " --stream-from-host \n" @@ -606,8 +611,16 @@ void streaming_cmd(int ch, char *optarg) { unsigned i; int speed; + int r; switch (ch) { + case OptStreamPixformat: + r = parse_pixelfmt(optarg, cap_pixelformat); + if (r) { + streaming_usage(); + exit(1); + } + break; case OptStreamCount: stream_count = strtoul(optarg, 0L, 0); break; @@ -1853,6 +1866,9 @@ enum stream_type { static int capture_setup(cv4l_fd &fd, cv4l_queue &in) { + v4l2_fmtdesc fmt_desc; + cv4l_fmt fmt; + if (fd.streamoff(in.g_type())) { fprintf(stderr, "%s: fd.streamoff error\n", __func__); return -1; @@ -1865,6 +1881,27 @@ static int capture_setup(cv4l_fd &fd, cv4l_queue &in) return -1; } + if (cap_pixelformat) { + if (fd.enum_fmt(fmt_desc, true, 0, in.g_type())) { + fprintf(stderr, "%s: fd.enum_fmt error\n", __func__); + return -1; + } + + do { + if (cap_pixelformat == fmt_desc.pixelformat) + break; + } while (!fd.enum_fmt(fmt_desc)); + + if (cap_pixelformat != fmt_desc.pixelformat) { + fprintf(stderr, "%s: format from user not supported\n", __func__); + return -1; + } + + fd.g_fmt(fmt, in.g_type()); + fmt.s_pixelformat(cap_pixelformat); + fd.s_fmt(fmt, in.g_type()); + } + if (in.reqbufs(&fd, reqbufs_count_cap)) { fprintf(stderr, "%s: in.reqbufs %u error\n", __func__, reqbufs_count_cap); diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index 1783979d..2cbf519e 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -238,6 +238,7 @@ static struct option long_options[] = { {"list-buffers-sdr", no_argument, 0, OptListBuffersSdr}, {"list-buffers-sdr-out", no_argument, 0, OptListBuffersSdrOut}, {"list-buffers-meta", no_argument, 0, OptListBuffersMeta}, + {"stream-pixformat", required_argument, 0, OptStreamPixformat}, {"stream-count", required_argument, 0, OptStreamCount}, {"stream-skip", required_argument, 0, OptStreamSkip}, {"stream-loop", no_argument, 0, OptStreamLoop}, @@ -722,6 +723,30 @@ __u32 parse_quantization(const char *s) return V4L2_QUANTIZATION_DEFAULT; } +int parse_pixelfmt(char *value, __u32 &pixelformat) +{ + int fmts = 0; + bool be_pixfmt; + + if(!value) + return -EINVAL; + + be_pixfmt = strlen(value) == 7 && !memcmp(value + 4, "-BE", 3); + if (be_pixfmt) + value[4] = 0; + if (strlen(value) == 4) { + pixelformat = + v4l2_fourcc(value[0], value[1], + value[2], value[3]); + if (be_pixfmt) + pixelformat |= 1 << 31; + } else { + pixelformat = strtol(value, 0L, 0); + } + fmts |= FmtPixelFormat; + return 0; +} + int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat, __u32 &field, __u32 &colorspace, __u32 &xfer_func, __u32 &ycbcr, __u32 &quantization, __u32 &flags, __u32 *bytesperline) @@ -729,7 +754,6 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat, char *value, *subs; int fmts = 0; unsigned bpl_index = 0; - bool be_pixfmt; field = V4L2_FIELD_ANY; flags = 0; @@ -760,18 +784,7 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat, fmts |= FmtHeight; break; case 2: - be_pixfmt = strlen(value) == 7 && !memcmp(value + 4, "-BE", 3); - if (be_pixfmt) - value[4] = 0; - if (strlen(value) == 4) { - pixelformat = - v4l2_fourcc(value[0], value[1], - value[2], value[3]); - if (be_pixfmt) - pixelformat |= 1 << 31; - } else { - pixelformat = strtol(value, 0L, 0); - } + parse_pixelfmt(value, pixelformat); fmts |= FmtPixelFormat; break; case 3: diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h index 5a52a0a4..8eee5351 100644 --- a/utils/v4l2-ctl/v4l2-ctl.h +++ b/utils/v4l2-ctl/v4l2-ctl.h @@ -205,6 +205,7 @@ enum Option { OptListBuffersSdr, OptListBuffersSdrOut, OptListBuffersMeta, + OptStreamPixformat, OptStreamCount, OptStreamSkip, OptStreamLoop, @@ -299,6 +300,7 @@ __u32 parse_xfer_func(const char *s); __u32 parse_ycbcr(const char *s); __u32 parse_hsv(const char *s); __u32 parse_quantization(const char *s); +int parse_pixelfmt(char *value, __u32 &pixelformat); int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat, __u32 &field, __u32 &colorspace, __u32 &xfer, __u32 &ycbcr, __u32 &quantization, __u32 &flags, __u32 *bytesperline);