mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
Merge "msm: vidc: add superframe encode support"
This commit is contained in:
commit
a108e35d45
9 changed files with 192 additions and 3 deletions
|
|
@ -876,6 +876,7 @@ static struct hfi_packetization_ops hfi_default = {
|
|||
.session_get_buf_req = create_pkt_cmd_session_get_buf_req,
|
||||
.session_flush = create_pkt_cmd_session_flush,
|
||||
.session_set_property = create_pkt_cmd_session_set_property,
|
||||
.session_sync_process = create_pkt_cmd_session_sync_process,
|
||||
};
|
||||
|
||||
struct hfi_packetization_ops *hfi_get_pkt_ops_handle(
|
||||
|
|
|
|||
|
|
@ -397,6 +397,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
|
|||
.default_value = V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||
.step = 1,
|
||||
},
|
||||
{
|
||||
.id = V4L2_CID_MPEG_VIDC_SUPERFRAME,
|
||||
.name = "Superframe",
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.minimum = 0,
|
||||
.maximum = 0,
|
||||
.default_value = 0,
|
||||
.step = 1,
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
|
||||
|
|
|
|||
|
|
@ -948,6 +948,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
|
|||
.default_value = 0,
|
||||
.step = 500,
|
||||
},
|
||||
{
|
||||
.id = V4L2_CID_MPEG_VIDC_SUPERFRAME,
|
||||
.name = "Superframe",
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.minimum = 0,
|
||||
.maximum = VIDC_SUPERFRAME_MAX,
|
||||
.default_value = 0,
|
||||
.step = 1,
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
|
||||
|
|
@ -1798,6 +1807,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
|||
case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE:
|
||||
case V4L2_CID_MPEG_VIDEO_VBV_DELAY:
|
||||
case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS:
|
||||
case V4L2_CID_MPEG_VIDC_SUPERFRAME:
|
||||
dprintk(VIDC_HIGH, "Control set: ID : %x Val : %d\n",
|
||||
ctrl->id, ctrl->val);
|
||||
break;
|
||||
|
|
@ -2166,6 +2176,12 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst)
|
|||
goto disable_bframe;
|
||||
}
|
||||
}
|
||||
|
||||
/* do not enable bframe if superframe is enabled */
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
if (ctrl->val)
|
||||
goto disable_bframe;
|
||||
|
||||
dprintk(VIDC_HIGH, "Bframe can be enabled!\n");
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@
|
|||
/* extra o/p buffers in case of decoder dcvs */
|
||||
#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4
|
||||
|
||||
/* extra buffers for encoder HFR usecase */
|
||||
#define HFR_EXTRA_INPUT_BUFFERS 4
|
||||
#define HFR_EXTRA_OUTPUT_BUFFERS 12
|
||||
|
||||
#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32
|
||||
#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8
|
||||
#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16
|
||||
|
|
@ -724,6 +728,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst,
|
|||
enum hal_buffer buffer_type)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
struct v4l2_format *f;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
||||
|
|
@ -758,6 +763,19 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst,
|
|||
count = inst->batch.size;
|
||||
}
|
||||
|
||||
/* increase both input and output counts for HFR/HSR encode case */
|
||||
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
|
||||
if (is_encode_session(inst) && msm_vidc_get_fps(inst) >= 120 &&
|
||||
!res_is_greater_than(f->fmt.pix_mp.width,
|
||||
f->fmt.pix_mp.height, 1920, 1088)) {
|
||||
if (buffer_type == HAL_BUFFER_INPUT &&
|
||||
count < HFR_EXTRA_INPUT_BUFFERS)
|
||||
count = HFR_EXTRA_INPUT_BUFFERS;
|
||||
if (buffer_type == HAL_BUFFER_OUTPUT &&
|
||||
count < HFR_EXTRA_OUTPUT_BUFFERS)
|
||||
count = HFR_EXTRA_OUTPUT_BUFFERS;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst)
|
|||
return NUM_MBS_PER_FRAME(height, width);
|
||||
}
|
||||
|
||||
static int msm_vidc_get_fps(struct msm_vidc_inst *inst)
|
||||
int msm_vidc_get_fps(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int fps;
|
||||
|
||||
|
|
@ -176,10 +176,16 @@ static int msm_vidc_get_fps(struct msm_vidc_inst *inst)
|
|||
void update_recon_stats(struct msm_vidc_inst *inst,
|
||||
struct recon_stats_type *recon_stats)
|
||||
{
|
||||
struct v4l2_ctrl *ctrl;
|
||||
struct recon_buf *binfo;
|
||||
u32 CR = 0, CF = 0;
|
||||
u32 frame_size;
|
||||
|
||||
/* do not consider recon stats in case of superframe */
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
if (ctrl->val)
|
||||
return;
|
||||
|
||||
CR = get_ubwc_compression_ratio(recon_stats->ubwc_stats_info);
|
||||
|
||||
frame_size = (msm_vidc_get_mbs_per_frame(inst) / (32 * 8) * 3) / 2;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ bool res_is_less_than_or_equal_to(u32 width, u32 height,
|
|||
bool res_is_greater_than_or_equal_to(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height);
|
||||
int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_get_fps(struct msm_vidc_inst *inst);
|
||||
int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst);
|
||||
int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst);
|
||||
void msm_comm_free_freq_table(struct msm_vidc_inst *inst);
|
||||
|
|
@ -36,4 +37,8 @@ void msm_comm_update_input_cr(struct msm_vidc_inst *inst, u32 index,
|
|||
void update_recon_stats(struct msm_vidc_inst *inst,
|
||||
struct recon_stats_type *recon_stats);
|
||||
void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core);
|
||||
bool res_is_greater_than(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height);
|
||||
bool res_is_less_than(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2436,6 +2436,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
|||
struct vidc_hal_ebd *empty_buf_done;
|
||||
u32 planes[VIDEO_MAX_PLANES] = {0};
|
||||
struct v4l2_format *f;
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
if (!response) {
|
||||
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
|
||||
|
|
@ -2468,9 +2469,23 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
|||
__func__, planes[0], planes[1]);
|
||||
goto exit;
|
||||
}
|
||||
mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED;
|
||||
vb = &mbuf->vvb.vb2_buf;
|
||||
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
if (ctrl->val && empty_buf_done->offset +
|
||||
empty_buf_done->filled_len < vb->planes[0].length) {
|
||||
dprintk(VIDC_HIGH,
|
||||
"%s: %x : addr (%#x): offset (%d) + filled_len (%d) < length (%d)\n",
|
||||
__func__, hash32_ptr(inst->session),
|
||||
empty_buf_done->packet_buffer,
|
||||
empty_buf_done->offset,
|
||||
empty_buf_done->filled_len,
|
||||
vb->planes[0].length);
|
||||
kref_put_mbuf(mbuf);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED;
|
||||
vb->planes[0].bytesused = response->input_done.filled_len;
|
||||
if (vb->planes[0].bytesused > vb->planes[0].length)
|
||||
dprintk(VIDC_LOW, "bytesused overflow length\n");
|
||||
|
|
@ -4315,6 +4330,98 @@ err_bad_input:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
int rc, i;
|
||||
struct hfi_device *hdev;
|
||||
struct v4l2_format *f;
|
||||
struct v4l2_ctrl *ctrl;
|
||||
u64 ts_delta_us;
|
||||
struct vidc_frame_data *frames;
|
||||
u32 num_etbs, superframe_count, frame_size, hfi_fmt;
|
||||
|
||||
if (!inst || !inst->core || !inst->core->device || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
hdev = inst->core->device;
|
||||
frames = inst->superframe_data;
|
||||
|
||||
if (!is_input_buffer(mbuf))
|
||||
return msm_comm_qbuf_to_hfi(inst, mbuf);
|
||||
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
superframe_count = ctrl->val;
|
||||
if (superframe_count > VIDC_SUPERFRAME_MAX) {
|
||||
dprintk(VIDC_ERR, "%s: wrong superframe count %d, max %d\n",
|
||||
__func__, superframe_count, VIDC_SUPERFRAME_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ts_delta_us = 1000000 / (inst->clk_data.frame_rate >> 16);
|
||||
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
|
||||
hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat);
|
||||
frame_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width,
|
||||
f->fmt.pix_mp.height);
|
||||
if (frame_size * superframe_count !=
|
||||
mbuf->vvb.vb2_buf.planes[0].length) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: %#x : invalid superframe length, pxlfmt %#x wxh %dx%d framesize %d count %d length %d\n",
|
||||
__func__, hash32_ptr(inst->session),
|
||||
f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
|
||||
f->fmt.pix_mp.height, frame_size, superframe_count,
|
||||
mbuf->vvb.vb2_buf.planes[0].length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
num_etbs = 0;
|
||||
populate_frame_data(&frames[0], mbuf, inst);
|
||||
/* prepare superframe buffers */
|
||||
frames[0].filled_len = frame_size;
|
||||
/*
|
||||
* superframe logic updates extradata and eos flags only, so
|
||||
* ensure no other flags are populated in populate_frame_data()
|
||||
*/
|
||||
frames[0].flags &= ~HAL_BUFFERFLAG_EXTRADATA;
|
||||
frames[0].flags &= ~HAL_BUFFERFLAG_EOS;
|
||||
if (frames[0].flags)
|
||||
dprintk(VIDC_ERR, "%s: invalid flags %#x\n",
|
||||
__func__, frames[0].flags);
|
||||
frames[0].flags = 0;
|
||||
|
||||
for (i = 0; i < superframe_count; i++) {
|
||||
if (i)
|
||||
memcpy(&frames[i], &frames[0],
|
||||
sizeof(struct vidc_frame_data));
|
||||
frames[i].offset += i * frame_size;
|
||||
frames[i].timestamp += i * ts_delta_us;
|
||||
if (!i) {
|
||||
/* first frame */
|
||||
if (frames[i].extradata_addr)
|
||||
frames[i].flags |= HAL_BUFFERFLAG_EXTRADATA;
|
||||
} else if (i == superframe_count - 1) {
|
||||
/* last frame */
|
||||
if (mbuf->vvb.flags & V4L2_BUF_FLAG_EOS)
|
||||
frames[i].flags |= HAL_BUFFERFLAG_EOS;
|
||||
}
|
||||
num_etbs++;
|
||||
}
|
||||
|
||||
rc = call_hfi_op(hdev, session_process_batch, inst->session,
|
||||
num_etbs, frames, 0, NULL);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: Failed to qbuf: %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
/* update mbuf flags */
|
||||
mbuf->flags |= MSM_VIDC_FLAG_QUEUED;
|
||||
mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED;
|
||||
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
|
|
@ -4345,6 +4452,7 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst,
|
|||
int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
if (!inst || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
|
||||
|
|
@ -4371,7 +4479,11 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
|
|||
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
|
||||
|
||||
print_vidc_buffer(VIDC_HIGH, "qbuf", inst, mbuf);
|
||||
rc = msm_comm_qbuf_to_hfi(inst, mbuf);
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
if (ctrl->val)
|
||||
rc = msm_comm_qbuf_superframe_to_hfi(inst, mbuf);
|
||||
else
|
||||
rc = msm_comm_qbuf_to_hfi(inst, mbuf);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc);
|
||||
|
||||
|
|
@ -4975,14 +5087,23 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst,
|
|||
int host_count, int act_count, enum hal_buffer type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct v4l2_ctrl *ctrl;
|
||||
struct hfi_device *hdev;
|
||||
struct hfi_buffer_count_actual buf_count;
|
||||
|
||||
if (!inst || !inst->core || !inst->core->device) {
|
||||
dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
hdev = inst->core->device;
|
||||
|
||||
buf_count.buffer_type = get_hfi_buffer(type);
|
||||
buf_count.buffer_count_actual = act_count;
|
||||
buf_count.buffer_count_min_host = host_count;
|
||||
/* set total superframe buffers count */
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
if (ctrl->val)
|
||||
buf_count.buffer_count_actual = act_count * ctrl->val;
|
||||
dprintk(VIDC_HIGH, "%s: %x : hal_buffer %d min_host %d actual %d\n",
|
||||
__func__, hash32_ptr(inst->session), type,
|
||||
host_count, act_count);
|
||||
|
|
|
|||
|
|
@ -119,6 +119,16 @@ static inline bool in_port_reconfig(struct msm_vidc_inst *inst)
|
|||
return inst->in_reconfig && inst->bufq[INPUT_PORT].vb2_bufq.streaming;
|
||||
}
|
||||
|
||||
static inline bool is_input_buffer(struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
return mbuf->vvb.vb2_buf.type == INPUT_MPLANE;
|
||||
}
|
||||
|
||||
static inline bool is_output_buffer(struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
return mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE;
|
||||
}
|
||||
|
||||
static inline int msm_comm_g_ctrl(struct msm_vidc_inst *inst,
|
||||
struct v4l2_control *ctrl)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
|
||||
/* Maintains the number of FTB's between each FBD over a window */
|
||||
#define DCVS_FTB_WINDOW 16
|
||||
/* Superframe can have maximum of 32 frames */
|
||||
#define VIDC_SUPERFRAME_MAX 32
|
||||
|
||||
#define V4L2_EVENT_VIDC_BASE 10
|
||||
#define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
|
||||
|
|
@ -477,6 +479,7 @@ struct msm_vidc_inst {
|
|||
struct msm_vidc_list etb_data;
|
||||
struct msm_vidc_list fbd_data;
|
||||
struct buffer_requirements buff_req;
|
||||
struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX];
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
|
||||
struct v4l2_ctrl **cluster;
|
||||
|
|
|
|||
Loading…
Reference in a new issue