The encoder buffer can have a negative impact on the quality of the encoded video. Add a control to allow user space to disable the encoder buffer per channel if the VCU supports the encoder buffer but the quality is not sufficient.
Unified · Split
| @@ -105,6 +105,12 @@ · 104 unmodified lines | ||
| 105 | 105 | #define BETA_OFFSET_DIV_2 -1 |
| 106 | 106 | #define TC_OFFSET_DIV_2 -1 |
| 107 | 107 | |
| 108 | +/* | |
| 109 | + * This control allows applications to explicitly disable the encoder buffer. | |
| 110 | + * This value is Allegro specific. | |
| 111 | + */ | |
| 112 | +#define V4L2_CID_USER_ALLEGRO_ENCODER_BUFFER (V4L2_CID_USER_ALLEGRO_BASE + 0) | |
| 113 | + | |
| 108 | 114 | static int debug; |
| 109 | 115 | module_param(debug, int, 0644); |
| 110 | 116 | MODULE_PARM_DESC(debug, "Debug level (0-2)"); |
| @@ -275,6 +281,8 @@ struct allegro_channel { · 164 unmodified lines | ||
| 275 | 281 | struct v4l2_ctrl *mpeg_video_cpb_size; |
| 276 | 282 | struct v4l2_ctrl *mpeg_video_gop_size; |
| 277 | 283 | |
| 284 | + struct v4l2_ctrl *encoder_buffer; | |
| 285 | + | |
| 278 | 286 | /* user_id is used to identify the channel during CREATE_CHANNEL */ |
| 279 | 287 | /* not sure, what to set here and if this is actually required */ |
| 280 | 288 | int user_id; |
| @@ -1255,7 +1263,7 @@ static int fill_create_channel_param(struct allegro_channel *channel, · 974 unmodified lines | ||
| 1255 | 1263 | param->max_transfo_depth_intra = channel->max_transfo_depth_intra; |
| 1256 | 1264 | param->max_transfo_depth_inter = channel->max_transfo_depth_inter; |
| 1257 | 1265 | |
| 1258 | − param->encoder_buffer_enabled = channel->dev->has_encoder_buffer; | |
| 1266 | + param->encoder_buffer_enabled = v4l2_ctrl_g_ctrl(channel->encoder_buffer); | |
| 1259 | 1267 | param->encoder_buffer_offset = 0; |
| 1260 | 1268 | |
| 1261 | 1269 | param->rate_control_mode = channel->frame_rc_enable ? |
| @@ -1381,7 +1389,7 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev, · 119 unmodified lines | ||
| 1381 | 1389 | u64 src_handle) |
| 1382 | 1390 | { |
| 1383 | 1391 | struct mcu_msg_encode_frame msg; |
| 1384 | − bool use_encoder_buffer = channel->dev->has_encoder_buffer; | |
| 1392 | + bool use_encoder_buffer = v4l2_ctrl_g_ctrl(channel->encoder_buffer); | |
| 1385 | 1393 | |
| 1386 | 1394 | memset(&msg, 0, sizeof(msg)); |
| 1387 | 1395 | |
| @@ -2466,6 +2474,8 @@ static void allegro_destroy_channel(struct allegro_channel *channel) · 1078 unmodified lines | ||
| 2466 | 2474 | v4l2_ctrl_grab(channel->mpeg_video_cpb_size, false); |
| 2467 | 2475 | v4l2_ctrl_grab(channel->mpeg_video_gop_size, false); |
| 2468 | 2476 | |
| 2477 | + v4l2_ctrl_grab(channel->encoder_buffer, false); | |
| 2478 | + | |
| 2469 | 2479 | if (channel->user_id != -1) { |
| 2470 | 2480 | clear_bit(channel->user_id, &dev->channel_user_ids); |
| 2471 | 2481 | channel->user_id = -1; |
| @@ -2532,6 +2542,8 @@ static int allegro_create_channel(struct allegro_channel *channel) · 60 unmodified lines | ||
| 2532 | 2542 | v4l2_ctrl_grab(channel->mpeg_video_cpb_size, true); |
| 2533 | 2543 | v4l2_ctrl_grab(channel->mpeg_video_gop_size, true); |
| 2534 | 2544 | |
| 2545 | + v4l2_ctrl_grab(channel->encoder_buffer, true); | |
| 2546 | + | |
| 2535 | 2547 | reinit_completion(&channel->completion); |
| 2536 | 2548 | allegro_mcu_send_create_channel(dev, channel); |
| 2537 | 2549 | timeout = wait_for_completion_timeout(&channel->completion, |
| @@ -2915,6 +2927,10 @@ static int allegro_try_ctrl(struct v4l2_ctrl *ctrl) · 377 unmodified lines | ||
| 2915 | 2927 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: |
| 2916 | 2928 | allegro_clamp_bitrate(channel, ctrl); |
| 2917 | 2929 | break; |
| 2930 | + case V4L2_CID_USER_ALLEGRO_ENCODER_BUFFER: | |
| 2931 | + if (!channel->dev->has_encoder_buffer) | |
| 2932 | + ctrl->val = 0; | |
| 2933 | + break; | |
| 2918 | 2934 | } |
| 2919 | 2935 | |
| 2920 | 2936 | return 0; |
| @@ -2955,6 +2971,16 @@ static const struct v4l2_ctrl_ops allegro_ctrl_ops = { · 34 unmodified lines | ||
| 2955 | 2971 | .s_ctrl = allegro_s_ctrl, |
| 2956 | 2972 | }; |
| 2957 | 2973 | |
| 2974 | +static const struct v4l2_ctrl_config allegro_encoder_buffer_ctrl_config = { | |
| 2975 | + .id = V4L2_CID_USER_ALLEGRO_ENCODER_BUFFER, | |
| 2976 | + .name = "Encoder Buffer Enable", | |
| 2977 | + .type = V4L2_CTRL_TYPE_BOOLEAN, | |
| 2978 | + .min = 0, | |
| 2979 | + .max = 1, | |
| 2980 | + .step = 1, | |
| 2981 | + .def = 1, | |
| 2982 | +}; | |
| 2983 | + | |
| 2958 | 2984 | static int allegro_open(struct file *file) |
| 2959 | 2985 | { |
| 2960 | 2986 | struct video_device *vdev = video_devdata(file); |
| @@ -3106,6 +3132,8 @@ static int allegro_open(struct file *file) · 145 unmodified lines | ||
| 3106 | 3132 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, |
| 3107 | 3133 | 0, ALLEGRO_GOP_SIZE_MAX, |
| 3108 | 3134 | 1, ALLEGRO_GOP_SIZE_DEFAULT); |
| 3135 | + channel->encoder_buffer = v4l2_ctrl_new_custom(handler, | |
| 3136 | + &allegro_encoder_buffer_ctrl_config, NULL); | |
| 3109 | 3137 | v4l2_ctrl_new_std(handler, |
| 3110 | 3138 | &allegro_ctrl_ops, |
| 3111 | 3139 | V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, |
| @@ -211,6 +211,11 @@ enum v4l2_colorfx { · 210 unmodified lines | ||
| 211 | 211 | * We reserve 128 controls for this driver. |
| 212 | 212 | */ |
| 213 | 213 | #define V4L2_CID_USER_CCS_BASE (V4L2_CID_USER_BASE + 0x10f0) |
| 214 | +/* | |
| 215 | + * The base for Allegro driver controls. | |
| 216 | + * We reserve 16 controls for this driver. | |
| 217 | + */ | |
| 218 | +#define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170) | |
| 214 | 219 | |
| 215 | 220 | /* MPEG-class control IDs */ |
| 216 | 221 | /* The MPEG controls are applicable to all codec controls |