summaryrefslogtreecommitdiff
path: root/v4l2-mfc-encoder
diff options
context:
space:
mode:
Diffstat (limited to 'v4l2-mfc-encoder')
-rw-r--r--v4l2-mfc-encoder/args.c116
-rw-r--r--v4l2-mfc-encoder/args.h5
-rw-r--r--v4l2-mfc-encoder/main.c6
3 files changed, 110 insertions, 17 deletions
diff --git a/v4l2-mfc-encoder/args.c b/v4l2-mfc-encoder/args.c
index 98ef886..282b3cb 100644
--- a/v4l2-mfc-encoder/args.c
+++ b/v4l2-mfc-encoder/args.c
@@ -30,20 +30,87 @@
#include "common.h"
#include "args.h"
+struct {
+ int id;
+ char *name;
+} ctrls[] = {
+ { V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, "force_frame"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, "frame_skip_mode"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY, "h264_arc_activity"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK, "h264_arc_dark"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH, "h264_arc_smooth"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC, "h264_arc_static"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P, "h264_ref_pic"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV, "padding_yuv"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_PADDING, "padding"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT, "rc_fixed_target_bit"},
+ { V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF, "rc_react_coeff"},
+ { V4L2_CID_MPEG_VIDEO_B_FRAMES, "b_frames"},
+ { V4L2_CID_MPEG_VIDEO_BITRATE, "bitrate"},
+ { V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, "intra_refresh_mb"},
+ { V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, "rc_enable"},
+ { V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, "gop_closure"},
+ { V4L2_CID_MPEG_VIDEO_GOP_SIZE, "gop_size"},
+ { V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP, "h263_b_qp"},
+ { V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP, "h263_i_qp"},
+ { V4L2_CID_MPEG_VIDEO_H263_MAX_QP, "h263_max_qp"},
+ { V4L2_CID_MPEG_VIDEO_H263_MIN_QP, "h263_min_qp"},
+ { V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, "h263_p_qp"},
+ { V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, "h264_8x8_transform"},
+ { V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, "h264_b_qp"},
+ { V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, "h264_cpb_size"},
+ { V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, "h264_entropy"},
+ { V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, "h264_i_qp"},
+ { V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, "h264_i_period"},
+ { V4L2_CID_MPEG_VIDEO_H264_LEVEL, "h264_level"},
+ { V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, "h264_loop_filter_alpha"},
+ { V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, "h264_loop_filter_beta"},
+ { V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, "h264_loop_filter_mode"},
+ { V4L2_CID_MPEG_VIDEO_H264_MAX_QP, "h264_max_qp"},
+ { V4L2_CID_MPEG_VIDEO_H264_MIN_QP, "h264_min_qp"},
+ { V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, "h264_p_qp"},
+ { V4L2_CID_MPEG_VIDEO_H264_PROFILE, "h264_profile"},
+ { V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT, "h264_vui_sar_height"},
+ { V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH, "h264_vui_sar_width"},
+ { V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, "h264_vui_sar"},
+ { V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC, "h264_vui_sar_idc"},
+ { V4L2_CID_MPEG_VIDEO_HEADER_MODE, "header_mode"},
+ { V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, "mb_rc"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP, "mpeg4_b_qp"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, "mpeg4_i_qp"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, "mpeg4_level"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP, "mpeg4_max_qp"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP, "mpeg4_min_qp"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, "mpeg4_p_qp"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, "mpeg4_profile"},
+ { V4L2_CID_MPEG_VIDEO_MPEG4_QPEL, "mpeg4_qpel"},
+ { V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, "slice_max_bytes"},
+ { V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, "slice_max_mb"},
+ { V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, "slice_mode"},
+ { V4L2_CID_MPEG_VIDEO_VBV_SIZE, "vbv_size"},
+};
+
void print_usage(char const *name)
{
+ int i;
printf("Usage: %s [args]\n"
"\t-i <device> - FIMC camera device (e.g. /dev/video1)\n"
"\t If not specified demo input device is used\n"
"\t-m <device> - (required) MFC device (e.g. /dev/video8)\n"
"\t-o <file> - Output file name\n"
- "\t-c <codec> - The codec of the encoded stream\n"
+ "\t-c <codec>[,param[=val]]...\n"
+ "\t - The codec of the encoded stream optionally\n"
+ "\t followed by comma separated parameters.\n"
"\t Available codecs: mpeg4, h263, h264\n"
"\t-d <duration> - Number of frames to encode\n"
"\t-r <rate> - Frame rate\n"
- "\t-b <bitrate> - Bitrate\n"
"\t-s <size> - Size of frame in format WxH\n"
+ "Codec parameters:\n"
, name);
+
+ for (i = 0; i < array_len(ctrls); ++i) {
+ printf("\t%s\n", ctrls[i].name);
+ }
}
int get_codec(char *str)
@@ -67,15 +134,26 @@ void set_options_default(struct options *o)
o->rate = 25;
o->out_name = "demo.out";
o->codec = V4L2_PIX_FMT_H264;
- o->bitrate = 1000;
}
int parse_args(struct options *opts, int argc, char **argv)
{
- int c;
+ static const int codecs[] = {
+ V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_H263, V4L2_PIX_FMT_H264 };
+ const int nctrls = array_len(ctrls);
+ char *tokens[nctrls + 4];
+ char *s, *v;
+ int c, i;
set_options_default(opts);
+ for (i = 0; i < nctrls; ++i)
+ tokens[i] = ctrls[i].name;
+ tokens[i++] = "mpeg4";
+ tokens[i++] = "h263";
+ tokens[i++] = "h264";
+ tokens[i++] = NULL;
+
while ((c = getopt(argc, argv, "i:m:o:c:d:r:s:b:")) != -1) {
switch (c) {
case 'i':
@@ -88,11 +166,28 @@ int parse_args(struct options *opts, int argc, char **argv)
opts->out_name = optarg;
break;
case 'c':
- opts->codec = get_codec(optarg);
- if (opts->codec == 0) {
- err("Unknown codec");
- return -1;
- }
+ s = optarg;
+
+ while (*s) {
+ c = getsubopt(&s, tokens, &v);
+ if (c < 0) {
+ err("unknown codec option '%s'", v);
+ return -1;
+ } else if (c < nctrls) {
+ int *ctl = opts->ctrls[opts->nctrls++];
+ if (opts->nctrls > MAX_CTRLS) {
+ err("Too many codec options");
+ return -1;
+ }
+ ctl[0] = ctrls[c].id;
+ ctl[1] = v ? atoi(v) : 1;
+ dbg("opt %s=%d", ctrls[c].name, ctl[1]);
+ } else {
+ dbg("codec: %.04s",
+ (char *)&codecs[c - nctrls]);
+ opts->codec = codecs[c - nctrls];
+ }
+ };
break;
case 'd':
opts->duration = atoi(optarg);
@@ -109,9 +204,6 @@ int parse_args(struct options *opts, int argc, char **argv)
}
opts->height = atoi(++sep);
break;
- case 'b':
- opts->bitrate = atoi(optarg);
- break;
}
default:
return -1;
diff --git a/v4l2-mfc-encoder/args.h b/v4l2-mfc-encoder/args.h
index 757cb2f..f63b99e 100644
--- a/v4l2-mfc-encoder/args.h
+++ b/v4l2-mfc-encoder/args.h
@@ -25,6 +25,8 @@
#include "common.h"
+#define MAX_CTRLS 100
+
struct options {
char *in_name;
char *mfc_name;
@@ -34,7 +36,8 @@ struct options {
int height;
int duration;
int rate;
- int bitrate;
+ int nctrls;
+ int ctrls[MAX_CTRLS][2];
};
void print_usage(char const *name);
diff --git a/v4l2-mfc-encoder/main.c b/v4l2-mfc-encoder/main.c
index 5681bab..22bca26 100644
--- a/v4l2-mfc-encoder/main.c
+++ b/v4l2-mfc-encoder/main.c
@@ -76,10 +76,8 @@ int main(int argc, char *argv[])
if (mfc_set_rate(mfc, opts.rate))
return 1;
- if (mfc_set_bitrate(mfc, opts.bitrate))
- return 1;
-
- mfc_set_mpeg_control(mfc, V4L2_CID_MPEG_VIDEO_B_FRAMES, 2);
+ for (i = 0; i < opts.nctrls; ++i)
+ mfc_set_mpeg_control(mfc, opts.ctrls[i][0], opts.ctrls[i][1]);
if (opts.in_name)
if (v4l_copy_fmt(mfc, DIR_IN, input, DIR_OUT))