msm: vidc: New buffer counts exchange
Implement new buffer count exchange method between clients
and driver, which is common for both Encoder and Decoder.
CRs-Fixed: 2022735
Change-Id: I83287e06ad0389868be936d9685be8354bede007
Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index a2fed10..6b3ddfa 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1069,6 +1069,7 @@
hfi = (struct hfi_buffer_count_actual *)
&pkt->rg_property_data[1];
hfi->buffer_count_actual = prop->buffer_count_actual;
+ hfi->buffer_count_min_host = prop->buffer_count_min_host;
buffer_type = get_hfi_buffer(prop->buffer_type);
if (buffer_type)
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 33821c7..fd6e681 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -20,10 +20,7 @@
#include "msm_vidc_clocks.h"
#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
-#define MIN_NUM_OUTPUT_BUFFERS 4
-#define MIN_NUM_CAPTURE_BUFFERS 6
-#define MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS 1
-#define MAX_NUM_OUTPUT_BUFFERS VB2_MAX_FRAME
+#define MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS MIN_NUM_CAPTURE_BUFFERS
#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8010
#define MB_SIZE_IN_PIXEL (16 * 16)
#define MAX_OPERATING_FRAME_RATE (300 << 16)
@@ -323,6 +320,30 @@
.qmenu = NULL,
},
{
+ .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
+ .name = "CAPTURE Count",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = MIN_NUM_CAPTURE_BUFFERS,
+ .maximum = MAX_NUM_CAPTURE_BUFFERS,
+ .default_value = MIN_NUM_CAPTURE_BUFFERS,
+ .step = 1,
+ .menu_skip_mask = 0,
+ .qmenu = NULL,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ },
+ {
+ .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
+ .name = "OUTPUT Count",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = MIN_NUM_OUTPUT_BUFFERS,
+ .maximum = MAX_NUM_OUTPUT_BUFFERS,
+ .default_value = MIN_NUM_OUTPUT_BUFFERS,
+ .step = 1,
+ .menu_skip_mask = 0,
+ .qmenu = NULL,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ },
+ {
.id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT,
.name = "Video decoder dpb color format",
.type = V4L2_CTRL_TYPE_MENU,
@@ -477,7 +498,6 @@
.name = "YCbCr Semiplanar 4:2:0",
.description = "Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12,
- .num_planes = 2,
.get_frame_size = get_frame_size_nv12,
.type = CAPTURE_PORT,
},
@@ -485,7 +505,6 @@
.name = "UBWC YCbCr Semiplanar 4:2:0",
.description = "UBWC Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12_UBWC,
- .num_planes = 2,
.get_frame_size = get_frame_size_nv12_ubwc,
.type = CAPTURE_PORT,
},
@@ -493,7 +512,6 @@
.name = "UBWC YCbCr Semiplanar 4:2:0 10bit",
.description = "UBWC Y/CbCr 4:2:0 10bit",
.fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC,
- .num_planes = 2,
.get_frame_size = get_frame_size_nv12_ubwc_10bit,
.type = CAPTURE_PORT,
},
@@ -501,7 +519,6 @@
.name = "Mpeg4",
.description = "Mpeg4 compressed format",
.fourcc = V4L2_PIX_FMT_MPEG4,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -510,7 +527,6 @@
.name = "Mpeg2",
.description = "Mpeg2 compressed format",
.fourcc = V4L2_PIX_FMT_MPEG2,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -519,7 +535,6 @@
.name = "H263",
.description = "H263 compressed format",
.fourcc = V4L2_PIX_FMT_H263,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -528,7 +543,6 @@
.name = "VC1",
.description = "VC-1 compressed format",
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -537,7 +551,6 @@
.name = "VC1 SP",
.description = "VC-1 compressed format G",
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -546,7 +559,6 @@
.name = "H264",
.description = "H264 compressed format",
.fourcc = V4L2_PIX_FMT_H264,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -555,7 +567,6 @@
.name = "H264_MVC",
.description = "H264_MVC compressed format",
.fourcc = V4L2_PIX_FMT_H264_MVC,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -564,7 +575,6 @@
.name = "HEVC",
.description = "HEVC compressed format",
.fourcc = V4L2_PIX_FMT_HEVC,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -573,7 +583,6 @@
.name = "VP8",
.description = "VP8 compressed format",
.fourcc = V4L2_PIX_FMT_VP8,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
.defer_outputs = false,
@@ -582,122 +591,12 @@
.name = "VP9",
.description = "VP9 compressed format",
.fourcc = V4L2_PIX_FMT_VP9,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed_full_yuv,
.type = OUTPUT_PORT,
.defer_outputs = true,
},
};
-int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
-{
- const struct msm_vidc_format *fmt = NULL;
- struct hfi_device *hdev;
- int rc = 0, i = 0, stride = 0, scanlines = 0, color_format = 0;
- unsigned int *plane_sizes = NULL, extra_idx = 0;
-
- if (!inst || !f || !inst->core || !inst->core->device) {
- dprintk(VIDC_ERR,
- "Invalid input, inst = %pK, format = %pK\n", inst, f);
- return -EINVAL;
- }
-
- hdev = inst->core->device;
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- fmt = &inst->fmts[CAPTURE_PORT];
- else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- fmt = &inst->fmts[OUTPUT_PORT];
- else
- return -ENOTSUPP;
-
- f->fmt.pix_mp.pixelformat = fmt->fourcc;
- f->fmt.pix_mp.num_planes = fmt->num_planes;
- if (inst->in_reconfig) {
- inst->prop.height[OUTPUT_PORT] = inst->reconfig_height;
- inst->prop.width[OUTPUT_PORT] = inst->reconfig_width;
-
- rc = msm_vidc_check_session_supported(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s: unsupported session\n", __func__);
- goto exit;
- }
- }
-
- f->fmt.pix_mp.height = inst->prop.height[CAPTURE_PORT];
- f->fmt.pix_mp.width = inst->prop.width[CAPTURE_PORT];
- stride = inst->prop.width[CAPTURE_PORT];
- scanlines = inst->prop.height[CAPTURE_PORT];
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- plane_sizes = &inst->bufq[OUTPUT_PORT].plane_sizes[0];
- for (i = 0; i < fmt->num_planes; ++i) {
- if (!plane_sizes[i]) {
- f->fmt.pix_mp.plane_fmt[i].sizeimage =
- get_frame_size(inst, fmt, f->type, i);
- plane_sizes[i] = f->fmt.pix_mp.plane_fmt[i].
- sizeimage;
- } else
- f->fmt.pix_mp.plane_fmt[i].sizeimage =
- plane_sizes[i];
- }
- f->fmt.pix_mp.height = inst->prop.height[OUTPUT_PORT];
- f->fmt.pix_mp.width = inst->prop.width[OUTPUT_PORT];
- f->fmt.pix_mp.plane_fmt[0].bytesperline =
- (__u16)inst->prop.width[OUTPUT_PORT];
- f->fmt.pix_mp.plane_fmt[0].reserved[0] =
- (__u16)inst->prop.height[OUTPUT_PORT];
- } else {
- switch (fmt->fourcc) {
- case V4L2_PIX_FMT_NV12:
- color_format = COLOR_FMT_NV12;
- break;
- case V4L2_PIX_FMT_NV12_UBWC:
- color_format = COLOR_FMT_NV12_UBWC;
- break;
- case V4L2_PIX_FMT_NV12_TP10_UBWC:
- color_format = COLOR_FMT_NV12_BPP10_UBWC;
- break;
- default:
- dprintk(VIDC_WARN, "Color format not recognized\n");
- rc = -ENOTSUPP;
- goto exit;
- }
-
- stride = VENUS_Y_STRIDE(color_format,
- inst->prop.width[CAPTURE_PORT]);
- scanlines = VENUS_Y_SCANLINES(color_format,
- inst->prop.height[CAPTURE_PORT]);
-
- f->fmt.pix_mp.plane_fmt[0].sizeimage =
- fmt->get_frame_size(0,
- inst->prop.height[CAPTURE_PORT],
- inst->prop.width[CAPTURE_PORT]);
-
- extra_idx = EXTRADATA_IDX(fmt->num_planes);
- if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
- f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
- VENUS_EXTRADATA_SIZE(
- inst->prop.height[CAPTURE_PORT],
- inst->prop.width[CAPTURE_PORT]);
- }
-
- for (i = 0; i < fmt->num_planes; ++i)
- inst->bufq[CAPTURE_PORT].plane_sizes[i] =
- f->fmt.pix_mp.plane_fmt[i].sizeimage;
-
- f->fmt.pix_mp.height = inst->prop.height[CAPTURE_PORT];
- f->fmt.pix_mp.width = inst->prop.width[CAPTURE_PORT];
- f->fmt.pix_mp.plane_fmt[0].bytesperline =
- (__u16)stride;
- f->fmt.pix_mp.plane_fmt[0].reserved[0] =
- (__u16)scanlines;
- }
-
-exit:
- return rc;
-}
-
int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
{
struct msm_vidc_format *fmt = NULL;
@@ -724,6 +623,14 @@
rc = -EINVAL;
goto err_invalid_fmt;
}
+
+ if (inst->fmts[fmt->type].fourcc == f->fmt.pix_mp.pixelformat &&
+ inst->prop.width[CAPTURE_PORT] == f->fmt.pix_mp.width &&
+ inst->prop.height[CAPTURE_PORT] ==
+ f->fmt.pix_mp.height) {
+ dprintk(VIDC_DBG, "Thank you : Nothing changed\n");
+ return 0;
+ }
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
@@ -750,7 +657,7 @@
inst->fmts[fmt->type].get_frame_size(0,
f->fmt.pix_mp.height, f->fmt.pix_mp.width);
- extra_idx = EXTRADATA_IDX(inst->fmts[fmt->type].num_planes);
+ extra_idx = EXTRADATA_IDX(inst->bufq[fmt->type].num_planes);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
VENUS_EXTRADATA_SIZE(
@@ -758,14 +665,12 @@
inst->prop.width[CAPTURE_PORT]);
}
- f->fmt.pix_mp.num_planes = inst->fmts[fmt->type].num_planes;
- for (i = 0; i < inst->fmts[fmt->type].num_planes; ++i) {
+ f->fmt.pix_mp.num_planes = inst->bufq[fmt->type].num_planes;
+ for (i = 0; i < inst->bufq[fmt->type].num_planes; i++) {
inst->bufq[CAPTURE_PORT].plane_sizes[i] =
f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- inst->prop.width[OUTPUT_PORT] = f->fmt.pix_mp.width;
- inst->prop.height[OUTPUT_PORT] = f->fmt.pix_mp.height;
fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
ARRAY_SIZE(vdec_formats),
@@ -781,34 +686,21 @@
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
- rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to initialize instance\n");
- goto err_invalid_fmt;
- }
-
- if (!(get_hal_codec(inst->fmts[fmt->type].fourcc) &
- inst->core->dec_codec_supported)) {
- dprintk(VIDC_ERR,
- "Codec(%#x) is not present in the supported codecs list(%#x)\n",
- get_hal_codec(inst->fmts[fmt->type].fourcc),
- inst->core->dec_codec_supported);
- rc = -EINVAL;
- goto err_invalid_fmt;
- }
-
rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
if (rc) {
dprintk(VIDC_ERR, "Failed to open instance\n");
goto err_invalid_fmt;
}
- rc = msm_vidc_check_session_supported(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s: session not supported\n", __func__);
- goto err_invalid_fmt;
+ if (inst->fmts[fmt->type].fourcc == f->fmt.pix_mp.pixelformat &&
+ inst->prop.width[OUTPUT_PORT] == f->fmt.pix_mp.width &&
+ inst->prop.height[OUTPUT_PORT] ==
+ f->fmt.pix_mp.height) {
+ dprintk(VIDC_DBG, "Thank you : Nothing changed\n");
+ return 0;
}
+ inst->prop.width[OUTPUT_PORT] = f->fmt.pix_mp.width;
+ inst->prop.height[OUTPUT_PORT] = f->fmt.pix_mp.height;
frame_sz.buffer_type = HAL_BUFFER_INPUT;
frame_sz.width = inst->prop.width[OUTPUT_PORT];
@@ -820,18 +712,19 @@
msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
max_input_size = get_frame_size(
-inst, &inst->fmts[fmt->type], f->type, 0);
+ inst, &inst->fmts[fmt->type], f->type, 0);
if (f->fmt.pix_mp.plane_fmt[0].sizeimage > max_input_size ||
!f->fmt.pix_mp.plane_fmt[0].sizeimage) {
f->fmt.pix_mp.plane_fmt[0].sizeimage = max_input_size;
}
- f->fmt.pix_mp.num_planes = inst->fmts[fmt->type].num_planes;
- for (i = 0; i < inst->fmts[fmt->type].num_planes; ++i) {
+ f->fmt.pix_mp.num_planes = inst->bufq[fmt->type].num_planes;
+ for (i = 0; i < inst->bufq[fmt->type].num_planes; ++i) {
inst->bufq[OUTPUT_PORT].plane_sizes[i] =
f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
+ rc = msm_comm_try_get_bufreqs(inst);
}
err_invalid_fmt:
return rc;
@@ -868,516 +761,6 @@
return rc;
}
-static int set_actual_buffer_count(struct msm_vidc_inst *inst,
- int count, enum hal_buffer type)
-{
- int rc = 0;
- struct hfi_device *hdev;
- struct hal_buffer_count_actual buf_count;
-
- hdev = inst->core->device;
-
- buf_count.buffer_type = type;
- buf_count.buffer_count_actual = count;
- rc = call_hfi_op(hdev, session_set_property,
- inst->session, HAL_PARAM_BUFFER_COUNT_ACTUAL, &buf_count);
- if (rc)
- dprintk(VIDC_ERR,
- "Failed to set actual buffer count %d for buffer type %d\n",
- count, type);
- return rc;
-}
-
-static int msm_vdec_queue_setup(
- struct vb2_queue *q,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- int i, rc = 0;
- struct msm_vidc_inst *inst;
- struct hal_buffer_requirements *bufreq;
- int extra_idx = 0;
- int min_buff_count = 0;
-
- if (!q || !num_buffers || !num_planes
- || !sizes || !q->drv_priv) {
- dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n",
- q, num_buffers, num_planes);
- return -EINVAL;
- }
- inst = q->drv_priv;
-
- if (!inst || !inst->core || !inst->core->device) {
- dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
- return -EINVAL;
- }
-
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s: Failed : Buffer requirements\n", __func__);
- goto exit;
- }
-
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- *num_planes = inst->fmts[OUTPUT_PORT].num_planes;
- if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
- *num_buffers > MAX_NUM_OUTPUT_BUFFERS)
- *num_buffers = MIN_NUM_OUTPUT_BUFFERS;
- for (i = 0; i < *num_planes; i++) {
- sizes[i] = get_frame_size(inst,
- &inst->fmts[OUTPUT_PORT], q->type, i);
- }
- rc = set_actual_buffer_count(inst, *num_buffers,
- HAL_BUFFER_INPUT);
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- dprintk(VIDC_DBG, "Getting bufreqs on capture plane\n");
- *num_planes = inst->fmts[CAPTURE_PORT].num_planes;
- rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to open instance\n");
- break;
- }
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to get buffer requirements: %d\n", rc);
- break;
- }
-
- bufreq = get_buff_req_buffer(inst,
- msm_comm_get_hal_output_buffer(inst));
- if (!bufreq) {
- dprintk(VIDC_ERR,
- "No buffer requirement for buffer type %x\n",
- HAL_BUFFER_OUTPUT);
- rc = -EINVAL;
- break;
- }
-
- /* Pretend as if FW itself is asking for
- * additional buffers.
- * *num_buffers += MSM_VIDC_ADDITIONAL_BUFS_FOR_DCVS
- * is wrong since it will end up increasing the count
- * on every call to reqbufs if *num_bufs is larger
- * than min requirement.
- */
- *num_buffers = max(*num_buffers, bufreq->buffer_count_min
- + msm_dcvs_get_extra_buff_count(inst));
-
- min_buff_count = (!!(inst->flags & VIDC_THUMBNAIL)) ?
- MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS :
- MIN_NUM_CAPTURE_BUFFERS;
-
- *num_buffers = clamp_val(*num_buffers,
- min_buff_count, VB2_MAX_FRAME);
-
- dprintk(VIDC_DBG, "Set actual output buffer count: %d\n",
- *num_buffers);
- rc = set_actual_buffer_count(inst, *num_buffers,
- msm_comm_get_hal_output_buffer(inst));
- if (rc)
- break;
-
- if (*num_buffers != bufreq->buffer_count_actual) {
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_WARN,
- "Failed to get buf req, %d\n", rc);
- break;
- }
- }
- dprintk(VIDC_DBG, "count = %d, size = %d, alignment = %d\n",
- inst->buff_req.buffer[1].buffer_count_actual,
- inst->buff_req.buffer[1].buffer_size,
- inst->buff_req.buffer[1].buffer_alignment);
- sizes[0] = inst->bufq[CAPTURE_PORT].plane_sizes[0];
-
- /*
- * Set actual buffer count to firmware for DPB buffers.
- * Firmware mandates setting of minimum buffer size
- * and actual buffer count for both OUTPUT and OUTPUT2.
- * Hence we are setting back the same buffer size
- * information back to firmware.
- */
- if (msm_comm_get_stream_output_mode(inst) ==
- HAL_VIDEO_DECODER_SECONDARY) {
- bufreq = get_buff_req_buffer(inst,
- HAL_BUFFER_OUTPUT);
- if (!bufreq) {
- rc = -EINVAL;
- break;
- }
-
- rc = set_actual_buffer_count(inst,
- bufreq->buffer_count_actual,
- HAL_BUFFER_OUTPUT);
- if (rc)
- break;
- }
-
- extra_idx =
- EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
- if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
- sizes[extra_idx] =
- VENUS_EXTRADATA_SIZE(
- inst->prop.height[CAPTURE_PORT],
- inst->prop.width[CAPTURE_PORT]);
- }
- break;
- default:
- dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
- rc = -EINVAL;
- }
-exit:
- return rc;
-}
-
-static inline int set_max_internal_buffers_size(struct msm_vidc_inst *inst)
-{
- int rc = 0;
- struct {
- enum hal_buffer type;
- struct hal_buffer_requirements *req;
- size_t size;
- } internal_buffers[] = {
- { HAL_BUFFER_INTERNAL_SCRATCH, NULL, 0},
- { HAL_BUFFER_INTERNAL_SCRATCH_1, NULL, 0},
- { HAL_BUFFER_INTERNAL_SCRATCH_2, NULL, 0},
- { HAL_BUFFER_INTERNAL_PERSIST, NULL, 0},
- { HAL_BUFFER_INTERNAL_PERSIST_1, NULL, 0},
- };
-
- struct hal_frame_size frame_sz;
- int i;
-
- frame_sz.buffer_type = HAL_BUFFER_INPUT;
- frame_sz.width = inst->capability.width.max;
- frame_sz.height =
- (inst->capability.mbs_per_frame.max * 256) /
- inst->capability.width.max;
-
- dprintk(VIDC_DBG,
- "Max buffer reqs, buffer type = %d width = %d, height = %d, max_mbs_per_frame = %d\n",
- frame_sz.buffer_type, frame_sz.width,
- frame_sz.height, inst->capability.mbs_per_frame.max);
-
- msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s Failed to get max buf req, %d\n", __func__, rc);
- return 0;
- }
-
- for (i = 0; i < ARRAY_SIZE(internal_buffers); i++) {
- internal_buffers[i].req =
- get_buff_req_buffer(inst, internal_buffers[i].type);
- internal_buffers[i].size = internal_buffers[i].req ?
- internal_buffers[i].req->buffer_size : 0;
- }
-
- frame_sz.buffer_type = HAL_BUFFER_INPUT;
- frame_sz.width = inst->prop.width[OUTPUT_PORT];
- frame_sz.height = inst->prop.height[OUTPUT_PORT];
-
- msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s Failed to get back old buf req, %d\n",
- __func__, rc);
- return rc;
- }
-
- dprintk(VIDC_DBG,
- "Old buffer reqs, buffer type = %d width = %d, height = %d\n",
- frame_sz.buffer_type, frame_sz.width,
- frame_sz.height);
-
- for (i = 0; i < ARRAY_SIZE(internal_buffers); i++) {
- if (internal_buffers[i].req) {
- internal_buffers[i].req->buffer_size =
- internal_buffers[i].size;
- dprintk(VIDC_DBG,
- "Changing buffer type : %d size to : %zd\n",
- internal_buffers[i].type,
- internal_buffers[i].size);
- }
- }
- return 0;
-}
-
-static inline int start_streaming(struct msm_vidc_inst *inst)
-{
- int rc = 0;
- struct hfi_device *hdev;
- bool slave_side_cp = inst->core->resources.slave_side_cp;
- struct hal_buffer_size_minimum b;
- unsigned int buffer_size;
- struct msm_vidc_format *fmt = NULL;
-
- fmt = &inst->fmts[CAPTURE_PORT];
- buffer_size = fmt->get_frame_size(0,
- inst->prop.height[CAPTURE_PORT],
- inst->prop.width[CAPTURE_PORT]);
- hdev = inst->core->device;
-
- if (msm_comm_get_stream_output_mode(inst) ==
- HAL_VIDEO_DECODER_SECONDARY) {
- rc = msm_vidc_check_scaling_supported(inst);
- b.buffer_type = HAL_BUFFER_OUTPUT2;
- } else {
- b.buffer_type = HAL_BUFFER_OUTPUT;
- }
-
- b.buffer_size = buffer_size;
- rc = call_hfi_op(hdev, session_set_property,
- inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
- &b);
- if (rc) {
- dprintk(VIDC_ERR, "H/w scaling is not in valid range\n");
- return -EINVAL;
- }
- if ((inst->flags & VIDC_SECURE) && !inst->in_reconfig &&
- !slave_side_cp) {
- rc = set_max_internal_buffers_size(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to set max scratch buffer size: %d\n",
- rc);
- goto fail_start;
- }
- }
- rc = msm_comm_set_scratch_buffers(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to set scratch buffers: %d\n", rc);
- goto fail_start;
- }
- rc = msm_comm_set_persist_buffers(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to set persist buffers: %d\n", rc);
- goto fail_start;
- }
-
- if (msm_comm_get_stream_output_mode(inst) ==
- HAL_VIDEO_DECODER_SECONDARY) {
- rc = msm_comm_set_output_buffers(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to set output buffers: %d\n", rc);
- goto fail_start;
- }
- }
-
- /*
- * For seq_changed_insufficient, driver should set session_continue
- * to firmware after the following sequence
- * - driver raises insufficient event to v4l2 client
- * - all output buffers have been flushed and freed
- * - v4l2 client queries buffer requirements and splits/combines OPB-DPB
- * - v4l2 client sets new set of buffers to firmware
- * - v4l2 client issues CONTINUE to firmware to resume decoding of
- * submitted ETBs.
- */
- if (inst->in_reconfig) {
- dprintk(VIDC_DBG, "send session_continue after reconfig\n");
- rc = call_hfi_op(hdev, session_continue,
- (void *) inst->session);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s - failed to send session_continue\n",
- __func__);
- goto fail_start;
- }
- }
- inst->in_reconfig = false;
-
- msm_comm_scale_clocks_and_bus(inst);
-
- rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to move inst: %pK to start done state\n", inst);
- goto fail_start;
- }
- msm_dcvs_init_load(inst);
- if (msm_comm_get_stream_output_mode(inst) ==
- HAL_VIDEO_DECODER_SECONDARY) {
- rc = msm_comm_queue_output_buffers(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to queue output buffers: %d\n", rc);
- goto fail_start;
- }
- }
-
-fail_start:
- return rc;
-}
-
-static inline int stop_streaming(struct msm_vidc_inst *inst)
-{
- int rc = 0;
-
- rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
- if (rc)
- dprintk(VIDC_ERR,
- "Failed to move inst: %pK to start done state\n", inst);
- return rc;
-}
-
-static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct msm_vidc_inst *inst;
- int rc = 0;
- struct hfi_device *hdev;
-
- if (!q || !q->drv_priv) {
- dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
- return -EINVAL;
- }
- inst = q->drv_priv;
- if (!inst || !inst->core || !inst->core->device) {
- dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
- return -EINVAL;
- }
- hdev = inst->core->device;
- dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
- q->type, inst);
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
- rc = start_streaming(inst);
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
- rc = start_streaming(inst);
- break;
- default:
- dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
- rc = -EINVAL;
- goto stream_start_failed;
- }
- if (rc) {
- dprintk(VIDC_ERR,
- "Streamon failed on: %d capability for inst: %pK\n",
- q->type, inst);
- goto stream_start_failed;
- }
-
- rc = msm_comm_qbuf(inst, NULL);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to commit buffers queued before STREAM_ON to hardware: %d\n",
- rc);
- goto stream_start_failed;
- }
-
-stream_start_failed:
- return rc;
-}
-
-static void msm_vdec_stop_streaming(struct vb2_queue *q)
-{
- struct msm_vidc_inst *inst;
- int rc = 0;
-
- if (!q || !q->drv_priv) {
- dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
- return;
- }
-
- inst = q->drv_priv;
- dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
- rc = stop_streaming(inst);
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
- rc = stop_streaming(inst);
- break;
- default:
- dprintk(VIDC_ERR,
- "Q-type is not supported: %d\n", q->type);
- rc = -EINVAL;
- break;
- }
-
- msm_comm_scale_clocks_and_bus(inst);
-
- if (rc)
- dprintk(VIDC_ERR,
- "Failed to move inst: %pK, cap = %d to state: %d\n",
- inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE);
-}
-
-static void msm_vdec_buf_queue(struct vb2_buffer *vb)
-{
- int rc = msm_comm_qbuf(vb2_get_drv_priv(vb->vb2_queue), vb);
-
- if (rc)
- dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
-}
-
-static void msm_vdec_buf_cleanup(struct vb2_buffer *vb)
-{
- int rc = 0;
- struct buf_queue *q = NULL;
- struct msm_vidc_inst *inst = NULL;
-
- if (!vb) {
- dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK",
- __func__, vb);
- return;
- }
-
- inst = vb2_get_drv_priv(vb->vb2_queue);
- if (!inst) {
- dprintk(VIDC_ERR, "%s : Invalid inst pointer",
- __func__);
- return;
- }
-
- q = msm_comm_get_vb2q(inst, vb->type);
- if (!q) {
- dprintk(VIDC_ERR,
- "%s : Failed to find buffer queue for type = %d\n",
- __func__, vb->type);
- return;
- }
-
- if (q->vb2_bufq.streaming) {
- dprintk(VIDC_DBG, "%d PORT is streaming\n",
- vb->type);
- return;
- }
-
- rc = msm_vidc_release_buffers(inst, vb->type);
- if (rc)
- dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n",
- __func__, rc);
-}
-
-static const struct vb2_ops msm_vdec_vb2q_ops = {
- .queue_setup = msm_vdec_queue_setup,
- .start_streaming = msm_vdec_start_streaming,
- .buf_queue = msm_vdec_buf_queue,
- .buf_cleanup = msm_vdec_buf_cleanup,
- .stop_streaming = msm_vdec_stop_streaming,
-};
-
-const struct vb2_ops *msm_vdec_get_vb2q_ops(void)
-{
- return &msm_vdec_vb2q_ops;
-}
-
int msm_vdec_inst_init(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -1398,6 +781,9 @@
inst->capability.secure_output2_threshold.max = 0;
inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC;
inst->buffer_mode_set[CAPTURE_PORT] = HAL_BUFFER_MODE_DYNAMIC;
+ /* To start with, both ports are 1 plane each */
+ inst->bufq[OUTPUT_PORT].num_planes = 1;
+ inst->bufq[CAPTURE_PORT].num_planes = 1;
inst->prop.fps = DEFAULT_FPS;
inst->operating_rate = 0;
memcpy(&inst->fmts[OUTPUT_PORT], &vdec_formats[2],
@@ -1506,6 +892,36 @@
case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
property_id = HAL_PARAM_INDEX_EXTRADATA;
extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
+ case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
+ case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
+ case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
+ case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
+ case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
+ case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
+ case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
+ case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
+ case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA:
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
+ case V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI:
+ case V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP:
+ case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI:
+ case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
+ case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY:
+ case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE:
+ inst->bufq[CAPTURE_PORT].num_planes = 2;
+ inst->bufq[CAPTURE_PORT].plane_sizes[EXTRADATA_IDX(2)] =
+ VENUS_EXTRADATA_SIZE(
+ inst->prop.height[CAPTURE_PORT],
+ inst->prop.width[CAPTURE_PORT]);
+ break;
+ default:
+ rc = -ENOTSUPP;
+ break;
+ }
extra.enable = 1;
pdata = &extra;
break;
@@ -1606,6 +1022,7 @@
V4L2_CID_MPEG_VIDEO_H264_LEVEL,
temp_ctrl->val);
pdata = &profile_level;
+ rc = msm_comm_try_get_bufreqs(inst);
break;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
@@ -1617,6 +1034,7 @@
V4L2_CID_MPEG_VIDEO_H264_PROFILE,
temp_ctrl->val);
pdata = &profile_level;
+ rc = msm_comm_try_get_bufreqs(inst);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT:
dprintk(VIDC_DBG,
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.h b/drivers/media/platform/msm/vidc/msm_vdec.h
index a209dd5..44ba4fd 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.h
+++ b/drivers/media/platform/msm/vidc/msm_vdec.h
@@ -22,10 +22,8 @@
const struct v4l2_ctrl_ops *ctrl_ops);
int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
-int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
int msm_vdec_s_ctrl(void *instance, struct v4l2_ctrl *ctrl);
int msm_vdec_g_ctrl(void *instance, struct v4l2_ctrl *ctrl);
int msm_vdec_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
-struct vb2_ops *msm_vdec_get_vb2q_ops(void);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 8956b0e..58a9bf8 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -18,8 +18,6 @@
#include "msm_vidc_clocks.h"
#define MSM_VENC_DVC_NAME "msm_venc_8974"
-#define MIN_NUM_OUTPUT_BUFFERS 4
-#define MIN_NUM_CAPTURE_BUFFERS 4
#define MIN_BIT_RATE 32000
#define MAX_BIT_RATE 300000000
#define DEFAULT_BIT_RATE 64000
@@ -326,6 +324,31 @@
.qmenu = NULL,
},
{
+ .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
+ .name = "CAPTURE Count",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = MIN_NUM_CAPTURE_BUFFERS,
+ .maximum = MAX_NUM_CAPTURE_BUFFERS,
+ .default_value = MIN_NUM_CAPTURE_BUFFERS,
+ .step = 1,
+ .menu_skip_mask = 0,
+ .qmenu = NULL,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ },
+ {
+ .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
+ .name = "OUTPUT Count",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = MIN_NUM_OUTPUT_BUFFERS,
+ .maximum = MAX_NUM_OUTPUT_BUFFERS,
+ .default_value = MIN_NUM_OUTPUT_BUFFERS,
+ .step = 1,
+ .menu_skip_mask = 0,
+ .qmenu = NULL,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ },
+
+ {
.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME,
.name = "Request I Frame",
.type = V4L2_CTRL_TYPE_BUTTON,
@@ -1098,7 +1121,6 @@
.name = "YCbCr Semiplanar 4:2:0",
.description = "Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12,
- .num_planes = 1,
.get_frame_size = get_frame_size_nv12,
.type = OUTPUT_PORT,
},
@@ -1106,7 +1128,6 @@
.name = "UBWC YCbCr Semiplanar 4:2:0",
.description = "UBWC Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12_UBWC,
- .num_planes = 1,
.get_frame_size = get_frame_size_nv12_ubwc,
.type = OUTPUT_PORT,
},
@@ -1114,7 +1135,6 @@
.name = "RGBA 8:8:8:8",
.description = "RGBA 8:8:8:8",
.fourcc = V4L2_PIX_FMT_RGB32,
- .num_planes = 1,
.get_frame_size = get_frame_size_rgba,
.type = OUTPUT_PORT,
},
@@ -1122,7 +1142,6 @@
.name = "H264",
.description = "H264 compressed format",
.fourcc = V4L2_PIX_FMT_H264,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1130,7 +1149,6 @@
.name = "VP8",
.description = "VP8 compressed format",
.fourcc = V4L2_PIX_FMT_VP8,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1138,7 +1156,6 @@
.name = "HEVC",
.description = "HEVC compressed format",
.fourcc = V4L2_PIX_FMT_HEVC,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1146,222 +1163,13 @@
.name = "YCrCb Semiplanar 4:2:0",
.description = "Y/CrCb 4:2:0",
.fourcc = V4L2_PIX_FMT_NV21,
- .num_planes = 1,
.get_frame_size = get_frame_size_nv21,
.type = OUTPUT_PORT,
},
};
-static void msm_venc_update_plane_count(struct msm_vidc_inst *inst, int type)
-{
- struct v4l2_ctrl *ctrl = NULL;
- u32 extradata = 0;
-
- if (!inst)
- return;
-
- inst->fmts[type].num_planes = 1;
-
- ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
- V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA);
-
- if (ctrl)
- extradata = v4l2_ctrl_g_ctrl(ctrl);
-
- if (type == CAPTURE_PORT) {
- switch (extradata) {
- case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
- case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
- case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
- case V4L2_MPEG_VIDC_EXTRADATA_LTR:
- case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
- inst->fmts[CAPTURE_PORT].num_planes = 2;
- default:
- break;
- }
- } else if (type == OUTPUT_PORT) {
- switch (extradata) {
- case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
- case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
- case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
- case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
- case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
- case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
- inst->fmts[OUTPUT_PORT].num_planes = 2;
- break;
- default:
- break;
- }
- }
-}
-
static int msm_venc_set_csc(struct msm_vidc_inst *inst);
-static int msm_venc_queue_setup(struct vb2_queue *q,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- int i, temp, rc = 0;
- struct msm_vidc_inst *inst;
- struct hal_buffer_count_actual new_buf_count;
- enum hal_property property_id;
- struct hfi_device *hdev;
- struct hal_buffer_requirements *buff_req;
- u32 extra_idx = 0;
- struct hal_buffer_requirements *buff_req_buffer = NULL;
-
- if (!q || !q->drv_priv) {
- dprintk(VIDC_ERR, "Invalid input\n");
- return -EINVAL;
- }
- inst = q->drv_priv;
-
- if (!inst || !inst->core || !inst->core->device) {
- dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
- return -EINVAL;
- }
- hdev = inst->core->device;
-
- rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to open instance\n");
- return rc;
- }
-
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to get buffer requirements: %d\n", rc);
- return rc;
- }
-
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- *num_planes = 1;
-
- buff_req = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
- if (buff_req) {
- /*
- * Pretend as if the FW itself is asking for additional
- * buffers, which are required for DCVS
- */
- unsigned int min_req_buffers =
- buff_req->buffer_count_min +
- msm_dcvs_get_extra_buff_count(inst);
- *num_buffers = max(*num_buffers, min_req_buffers);
- }
-
- if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
- *num_buffers > VB2_MAX_FRAME) {
- int temp = *num_buffers;
-
- *num_buffers = clamp_val(*num_buffers,
- MIN_NUM_CAPTURE_BUFFERS,
- VB2_MAX_FRAME);
- dprintk(VIDC_INFO,
- "Changing buffer count on CAPTURE_MPLANE from %d to %d for best effort encoding\n",
- temp, *num_buffers);
- }
-
- msm_venc_update_plane_count(inst, CAPTURE_PORT);
- *num_planes = inst->fmts[CAPTURE_PORT].num_planes;
-
- for (i = 0; i < *num_planes; i++) {
- int extra_idx = EXTRADATA_IDX(*num_planes);
-
- buff_req_buffer = get_buff_req_buffer(inst,
- HAL_BUFFER_OUTPUT);
-
- sizes[i] = buff_req_buffer ?
- buff_req_buffer->buffer_size : 0;
-
- if (extra_idx && i == extra_idx &&
- extra_idx < VIDEO_MAX_PLANES) {
- buff_req_buffer = get_buff_req_buffer(inst,
- HAL_BUFFER_EXTRADATA_OUTPUT);
- if (!buff_req_buffer) {
- dprintk(VIDC_ERR,
- "%s: failed - invalid buffer req\n",
- __func__);
- return -EINVAL;
- }
-
- sizes[i] = buff_req_buffer->buffer_size;
- }
- }
-
- dprintk(VIDC_DBG, "actual output buffer count set to fw = %d\n",
- *num_buffers);
- property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
- new_buf_count.buffer_type = HAL_BUFFER_OUTPUT;
- new_buf_count.buffer_count_actual = *num_buffers;
- rc = call_hfi_op(hdev, session_set_property, inst->session,
- property_id, &new_buf_count);
-
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- *num_planes = 1;
-
- *num_buffers = inst->buff_req.buffer[0].buffer_count_actual =
- max(*num_buffers, inst->buff_req.buffer[0].
- buffer_count_min);
-
- temp = *num_buffers;
-
- *num_buffers = clamp_val(*num_buffers,
- MIN_NUM_OUTPUT_BUFFERS,
- VB2_MAX_FRAME);
- dprintk(VIDC_INFO,
- "Changing buffer count on OUTPUT_MPLANE from %d to %d for best effort encoding\n",
- temp, *num_buffers);
-
- property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
- new_buf_count.buffer_type = HAL_BUFFER_INPUT;
- new_buf_count.buffer_count_actual = *num_buffers;
-
- dprintk(VIDC_DBG, "actual input buffer count set to fw = %d\n",
- *num_buffers);
-
- msm_venc_update_plane_count(inst, OUTPUT_PORT);
- *num_planes = inst->fmts[OUTPUT_PORT].num_planes;
-
- rc = call_hfi_op(hdev, session_set_property, inst->session,
- property_id, &new_buf_count);
- if (rc)
- dprintk(VIDC_ERR, "failed to set count to fw\n");
-
- dprintk(VIDC_DBG, "size = %d, alignment = %d, count = %d\n",
- inst->buff_req.buffer[0].buffer_size,
- inst->buff_req.buffer[0].buffer_alignment,
- inst->buff_req.buffer[0].buffer_count_actual);
- sizes[0] = inst->fmts[OUTPUT_PORT].get_frame_size(
- 0, inst->prop.height[OUTPUT_PORT],
- inst->prop.width[OUTPUT_PORT]);
-
- extra_idx =
- EXTRADATA_IDX(inst->fmts[OUTPUT_PORT].num_planes);
- if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
- buff_req_buffer = get_buff_req_buffer(inst,
- HAL_BUFFER_EXTRADATA_INPUT);
- if (!buff_req_buffer) {
- dprintk(VIDC_ERR,
- "%s: failed - invalid buffer req\n",
- __func__);
- return -EINVAL;
- }
-
- sizes[extra_idx] = buff_req_buffer->buffer_size;
- }
-
- break;
- default:
- dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
- rc = -EINVAL;
- break;
- }
- return rc;
-}
-
static int msm_venc_toggle_hier_p(struct msm_vidc_inst *inst, int layers)
{
int num_enh_layers = 0;
@@ -1436,190 +1244,6 @@
return rc;
}
-static inline int start_streaming(struct msm_vidc_inst *inst)
-{
- int rc = 0;
-
- if (!inst || !inst->core || !inst->core->device) {
- dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
- return -EINVAL;
- }
- msm_venc_power_save_mode_enable(inst);
- if (inst->capability.pixelprocess_capabilities &
- HAL_VIDEO_ENCODER_SCALING_CAPABILITY)
- rc = msm_vidc_check_scaling_supported(inst);
- if (rc) {
- dprintk(VIDC_ERR, "H/w scaling is not in valid range\n");
- return -EINVAL;
- }
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to get Buffer Requirements : %d\n", rc);
- goto fail_start;
- }
- rc = msm_comm_set_scratch_buffers(inst);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to set scratch buffers: %d\n", rc);
- goto fail_start;
- }
- rc = msm_comm_set_persist_buffers(inst);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to set persist buffers: %d\n", rc);
- goto fail_start;
- }
-
- msm_comm_scale_clocks_and_bus(inst);
-
- rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to move inst: %pK to start done state\n", inst);
- goto fail_start;
- }
- msm_dcvs_init_load(inst);
-
-fail_start:
- return rc;
-}
-
-static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct msm_vidc_inst *inst;
- int rc = 0;
-
- if (!q || !q->drv_priv) {
- dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
- return -EINVAL;
- }
- inst = q->drv_priv;
- dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
- q->type, inst);
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
- rc = start_streaming(inst);
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
- rc = start_streaming(inst);
- break;
- default:
- dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
- rc = -EINVAL;
- goto stream_start_failed;
- }
- if (rc) {
- dprintk(VIDC_ERR,
- "Streamon failed on: %d capability for inst: %pK\n",
- q->type, inst);
- goto stream_start_failed;
- }
-
- rc = msm_comm_qbuf(inst, NULL);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to commit buffers queued before STREAM_ON to hardware: %d\n",
- rc);
- goto stream_start_failed;
- }
-
-stream_start_failed:
- return rc;
-}
-
-static void msm_venc_stop_streaming(struct vb2_queue *q)
-{
- struct msm_vidc_inst *inst;
- int rc = 0;
-
- if (!q || !q->drv_priv) {
- dprintk(VIDC_ERR, "%s - Invalid input, q = %pK\n", __func__, q);
- return;
- }
-
- inst = q->drv_priv;
- dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
- break;
- default:
- dprintk(VIDC_ERR, "Q-type is not supported: %d\n", q->type);
- rc = -EINVAL;
- break;
- }
-
- msm_comm_scale_clocks_and_bus(inst);
-
- if (rc)
- dprintk(VIDC_ERR,
- "Failed to move inst: %pK, cap = %d to state: %d\n",
- inst, q->type, MSM_VIDC_CLOSE_DONE);
-}
-
-static void msm_venc_buf_queue(struct vb2_buffer *vb)
-{
- int rc = msm_comm_qbuf(vb2_get_drv_priv(vb->vb2_queue), vb);
-
- if (rc)
- dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
-}
-
-static void msm_venc_buf_cleanup(struct vb2_buffer *vb)
-{
- int rc = 0;
- struct buf_queue *q = NULL;
- struct msm_vidc_inst *inst = NULL;
-
- if (!vb) {
- dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK",
- __func__, vb);
- return;
- }
-
- inst = vb2_get_drv_priv(vb->vb2_queue);
- if (!inst) {
- dprintk(VIDC_ERR, "%s : Invalid inst pointer",
- __func__);
- return;
- }
-
- q = msm_comm_get_vb2q(inst, vb->type);
- if (!q) {
- dprintk(VIDC_ERR,
- "%s : Failed to find buffer queue for type = %d\n",
- __func__, vb->type);
- return;
- }
-
- if (q->vb2_bufq.streaming) {
- dprintk(VIDC_DBG, "%d PORT is streaming\n",
- vb->type);
- return;
- }
-
- rc = msm_vidc_release_buffers(inst, vb->type);
- if (rc)
- dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n",
- __func__, rc);
-}
-
-static const struct vb2_ops msm_venc_vb2q_ops = {
- .queue_setup = msm_venc_queue_setup,
- .start_streaming = msm_venc_start_streaming,
- .buf_queue = msm_venc_buf_queue,
- .buf_cleanup = msm_venc_buf_cleanup,
- .stop_streaming = msm_venc_stop_streaming,
-};
-
-const struct vb2_ops *msm_venc_get_vb2q_ops(void)
-{
- return &msm_venc_vb2q_ops;
-}
-
static struct v4l2_ctrl *get_ctrl_from_cluster(int id,
struct v4l2_ctrl **cluster, int ncontrols)
{
@@ -2129,11 +1753,63 @@
dprintk(VIDC_INFO, "Setting secure mode to: %d\n",
!!(inst->flags & VIDC_SECURE));
break;
- case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
+ case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: {
+ struct hal_buffer_requirements *buff_req_buffer = NULL;
+ int extra_idx = 0;
+
property_id = HAL_PARAM_INDEX_EXTRADATA;
extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
extra.enable = 1;
+
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
+ case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
+ case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
+ case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
+ case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
+ case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
+ inst->bufq[OUTPUT_PORT].num_planes = 2;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
+ case V4L2_MPEG_VIDC_EXTRADATA_LTR:
+ case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
+ inst->bufq[CAPTURE_PORT].num_planes = 2;
+ break;
+ default:
+ rc = -ENOTSUPP;
+ break;
+ }
+
pdata = &extra;
+ rc = call_hfi_op(hdev, session_set_property,
+ (void *)inst->session, property_id, pdata);
+
+ rc = msm_comm_try_get_bufreqs(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to get buffer requirements: %d\n", rc);
+ break;
+ }
+
+ buff_req_buffer = get_buff_req_buffer(inst,
+ HAL_BUFFER_EXTRADATA_INPUT);
+
+ extra_idx = EXTRADATA_IDX(inst->bufq[OUTPUT_PORT].num_planes);
+
+ inst->bufq[OUTPUT_PORT].plane_sizes[extra_idx] =
+ buff_req_buffer ?
+ buff_req_buffer->buffer_size : 0;
+
+ buff_req_buffer = get_buff_req_buffer(inst,
+ HAL_BUFFER_EXTRADATA_OUTPUT);
+
+ extra_idx = EXTRADATA_IDX(inst->bufq[CAPTURE_PORT].num_planes);
+ inst->bufq[CAPTURE_PORT].plane_sizes[extra_idx] =
+ buff_req_buffer ?
+ buff_req_buffer->buffer_size : 0;
+
+ property_id = 0;
+ }
break;
case V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER:
property_id = HAL_PARAM_VENC_GENERATE_AUDNAL;
@@ -2694,6 +2370,9 @@
inst->buffer_mode_set[CAPTURE_PORT] = HAL_BUFFER_MODE_STATIC;
inst->prop.fps = DEFAULT_FPS;
inst->capability.pixelprocess_capabilities = 0;
+ /* To start with, both ports are 1 plane each */
+ inst->bufq[OUTPUT_PORT].num_planes = 1;
+ inst->bufq[CAPTURE_PORT].num_planes = 1;
inst->operating_rate = 0;
memcpy(&inst->fmts[CAPTURE_PORT], &venc_formats[4],
@@ -2763,8 +2442,9 @@
{
struct msm_vidc_format *fmt = NULL;
int rc = 0;
- int i;
struct hfi_device *hdev;
+ int extra_idx = 0, i = 0;
+ struct hal_buffer_requirements *buff_req_buffer;
if (!inst || !f) {
dprintk(VIDC_ERR,
@@ -2779,6 +2459,7 @@
hdev = inst->core->device;
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+
fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
CAPTURE_PORT);
@@ -2793,9 +2474,6 @@
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
- msm_venc_update_plane_count(inst, CAPTURE_PORT);
- fmt->num_planes = inst->fmts[CAPTURE_PORT].num_planes;
-
rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
if (rc) {
dprintk(VIDC_ERR, "Failed to open instance\n");
@@ -2804,11 +2482,45 @@
inst->prop.width[CAPTURE_PORT] = f->fmt.pix_mp.width;
inst->prop.height[CAPTURE_PORT] = f->fmt.pix_mp.height;
- rc = msm_vidc_check_session_supported(inst);
+
+ rc = msm_comm_try_get_bufreqs(inst);
if (rc) {
dprintk(VIDC_ERR,
- "%s: session not supported\n", __func__);
- goto exit;
+ "Failed to get buffer requirements: %d\n", rc);
+ return rc;
+ }
+
+ /*
+ * Get CAPTURE plane size from HW. This may change based on
+ * settings like Slice delivery mode. HW should decide howmuch
+ * it needs.
+ */
+
+ buff_req_buffer = get_buff_req_buffer(inst,
+ HAL_BUFFER_OUTPUT);
+
+ f->fmt.pix_mp.plane_fmt[0].sizeimage = buff_req_buffer ?
+ buff_req_buffer->buffer_size : 0;
+
+ /*
+ * Get CAPTURE plane Extradata size from HW. This may change
+ * with no of Extradata's enabled. HW should decide howmuch
+ * it needs.
+ */
+
+ extra_idx = EXTRADATA_IDX(inst->bufq[fmt->type].num_planes);
+ if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
+ buff_req_buffer = get_buff_req_buffer(inst,
+ HAL_BUFFER_EXTRADATA_OUTPUT);
+ f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
+ buff_req_buffer ?
+ buff_req_buffer->buffer_size : 0;
+ }
+
+ f->fmt.pix_mp.num_planes = inst->bufq[fmt->type].num_planes;
+ for (i = 0; i < inst->bufq[fmt->type].num_planes; i++) {
+ inst->bufq[fmt->type].plane_sizes[i] =
+ f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
struct hal_frame_size frame_sz;
@@ -2816,13 +2528,6 @@
inst->prop.width[OUTPUT_PORT] = f->fmt.pix_mp.width;
inst->prop.height[OUTPUT_PORT] = f->fmt.pix_mp.height;
- rc = msm_vidc_check_session_supported(inst);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s: session not supported\n", __func__);
- goto exit;
- }
-
frame_sz.buffer_type = HAL_BUFFER_INPUT;
frame_sz.width = inst->prop.width[OUTPUT_PORT];
frame_sz.height = inst->prop.height[OUTPUT_PORT];
@@ -2849,8 +2554,38 @@
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
- msm_venc_update_plane_count(inst, OUTPUT_PORT);
- fmt->num_planes = inst->fmts[OUTPUT_PORT].num_planes;
+ f->fmt.pix_mp.plane_fmt[0].sizeimage =
+ inst->fmts[fmt->type].get_frame_size(0,
+ f->fmt.pix_mp.height, f->fmt.pix_mp.width);
+
+ rc = msm_comm_try_get_bufreqs(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to get buffer requirements: %d\n", rc);
+ return rc;
+ }
+
+ /*
+ * Get OUTPUT plane Extradata size from HW. This may change
+ * with no of Extradata's enabled. HW should decide howmuch
+ * it needs.
+ */
+
+ extra_idx = EXTRADATA_IDX(inst->bufq[fmt->type].num_planes);
+ if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
+ buff_req_buffer = get_buff_req_buffer(inst,
+ HAL_BUFFER_EXTRADATA_INPUT);
+ f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
+ buff_req_buffer ?
+ buff_req_buffer->buffer_size : 0;
+ }
+
+ f->fmt.pix_mp.num_planes = inst->bufq[fmt->type].num_planes;
+
+ for (i = 0; i < inst->bufq[fmt->type].num_planes; i++) {
+ inst->bufq[fmt->type].plane_sizes[i] =
+ f->fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
msm_comm_set_color_format(inst, HAL_BUFFER_INPUT, fmt->fourcc);
} else {
@@ -2859,137 +2594,10 @@
rc = -EINVAL;
goto exit;
}
-
- f->fmt.pix_mp.num_planes = fmt->num_planes;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- struct hal_frame_size frame_sz = {0};
- struct hal_buffer_requirements *bufreq = NULL;
-
- frame_sz.width = inst->prop.width[CAPTURE_PORT];
- frame_sz.height = inst->prop.height[CAPTURE_PORT];
- frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
- rc = call_hfi_op(hdev, session_set_property, (void *)
- inst->session, HAL_PARAM_FRAME_SIZE,
- &frame_sz);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to set OUTPUT framesize\n");
- goto exit;
- }
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_WARN,
- "%s : Getting buffer reqs failed: %d\n",
- __func__, rc);
- goto exit;
- }
- bufreq = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
- f->fmt.pix_mp.plane_fmt[0].sizeimage =
- bufreq ? bufreq->buffer_size : 0;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- struct hal_buffer_requirements *bufreq = NULL;
- int extra_idx = 0;
-
- for (i = 0; i < inst->fmts[fmt->type].num_planes; ++i) {
- f->fmt.pix_mp.plane_fmt[i].sizeimage =
- inst->fmts[fmt->type].get_frame_size(i,
- f->fmt.pix_mp.height, f->fmt.pix_mp.width);
- }
- extra_idx = EXTRADATA_IDX(inst->fmts[fmt->type].num_planes);
- if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
- bufreq = get_buff_req_buffer(inst,
- HAL_BUFFER_EXTRADATA_INPUT);
- f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
- bufreq ? bufreq->buffer_size : 0;
- }
- }
exit:
return rc;
}
-int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
-{
- const struct msm_vidc_format *fmt = NULL;
- int rc = 0;
- int i;
- u32 height, width, num_planes;
- unsigned int extra_idx = 0;
- struct hal_buffer_requirements *bufreq = NULL;
-
- if (!inst || !f) {
- dprintk(VIDC_ERR,
- "Invalid input, inst = %pK, format = %pK\n", inst, f);
- return -EINVAL;
- }
-
- rc = msm_comm_try_get_bufreqs(inst);
- if (rc) {
- dprintk(VIDC_WARN, "Getting buffer requirements failed: %d\n",
- rc);
- return rc;
- }
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- fmt = &inst->fmts[CAPTURE_PORT];
- height = inst->prop.height[CAPTURE_PORT];
- width = inst->prop.width[CAPTURE_PORT];
- msm_venc_update_plane_count(inst, CAPTURE_PORT);
- num_planes = inst->fmts[CAPTURE_PORT].num_planes;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- fmt = &inst->fmts[OUTPUT_PORT];
- height = inst->prop.height[OUTPUT_PORT];
- width = inst->prop.width[OUTPUT_PORT];
- msm_venc_update_plane_count(inst, OUTPUT_PORT);
- num_planes = inst->fmts[OUTPUT_PORT].num_planes;
- } else {
- dprintk(VIDC_ERR, "Invalid type: %x\n", f->type);
- return -ENOTSUPP;
- }
-
- f->fmt.pix_mp.pixelformat = fmt->fourcc;
- f->fmt.pix_mp.height = height;
- f->fmt.pix_mp.width = width;
- f->fmt.pix_mp.num_planes = num_planes;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- for (i = 0; i < num_planes; ++i) {
- f->fmt.pix_mp.plane_fmt[i].sizeimage =
- fmt->get_frame_size(i, height, width);
- }
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- bufreq = get_buff_req_buffer(inst,
- HAL_BUFFER_OUTPUT);
-
- f->fmt.pix_mp.plane_fmt[0].sizeimage =
- bufreq ? bufreq->buffer_size : 0;
- }
- extra_idx = EXTRADATA_IDX(num_planes);
- if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- bufreq = get_buff_req_buffer(inst,
- HAL_BUFFER_EXTRADATA_OUTPUT);
- else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- bufreq = get_buff_req_buffer(inst,
- HAL_BUFFER_EXTRADATA_INPUT);
-
- f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
- bufreq ? bufreq->buffer_size : 0;
- }
-
- for (i = 0; i < num_planes; ++i) {
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- inst->bufq[OUTPUT_PORT].plane_sizes[i] =
- f->fmt.pix_mp.plane_fmt[i].sizeimage;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- inst->bufq[CAPTURE_PORT].plane_sizes[i] =
- f->fmt.pix_mp.plane_fmt[i].sizeimage;
- }
- }
-
- return rc;
-}
-
int msm_venc_ctrl_init(struct msm_vidc_inst *inst,
const struct v4l2_ctrl_ops *ctrl_ops)
{
diff --git a/drivers/media/platform/msm/vidc/msm_venc.h b/drivers/media/platform/msm/vidc/msm_venc.h
index 0bb7de77a..6fe1db3 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.h
+++ b/drivers/media/platform/msm/vidc/msm_venc.h
@@ -22,9 +22,7 @@
const struct v4l2_ctrl_ops *ctrl_ops);
int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
-int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
int msm_venc_s_ctrl(void *instance, struct v4l2_ctrl *ctrl);
int msm_venc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
-struct vb2_ops *msm_venc_get_vb2q_ops(void);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index e93b771..9427444 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -187,15 +187,55 @@
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
{
struct msm_vidc_inst *inst = instance;
+ int i, rc = 0, color_format = 0;
+ enum vidc_ports port;
+ u32 num_planes;
- if (!inst || !f)
+ if (!inst || !f) {
+ dprintk(VIDC_ERR,
+ "Invalid input, inst = %pK, format = %pK\n", inst, f);
return -EINVAL;
+ }
+ if (inst->in_reconfig) {
+ inst->prop.height[OUTPUT_PORT] = inst->reconfig_height;
+ inst->prop.width[OUTPUT_PORT] = inst->reconfig_width;
+ }
- if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_g_fmt(instance, f);
- else if (inst->session_type == MSM_VIDC_ENCODER)
- return msm_venc_g_fmt(instance, f);
- return -EINVAL;
+ port = f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
+ OUTPUT_PORT : CAPTURE_PORT;
+
+ f->fmt.pix_mp.pixelformat = inst->fmts[port].fourcc;
+ f->fmt.pix_mp.height = inst->prop.height[port];
+ f->fmt.pix_mp.width = inst->prop.width[port];
+ num_planes = f->fmt.pix_mp.num_planes = inst->bufq[port].num_planes;
+ for (i = 0; i < num_planes; ++i)
+ f->fmt.pix_mp.plane_fmt[i].sizeimage =
+ inst->bufq[port].plane_sizes[i];
+ switch (inst->fmts[port].fourcc) {
+ case V4L2_PIX_FMT_NV12:
+ color_format = COLOR_FMT_NV12;
+ break;
+ case V4L2_PIX_FMT_NV12_UBWC:
+ color_format = COLOR_FMT_NV12_UBWC;
+ break;
+ case V4L2_PIX_FMT_NV12_TP10_UBWC:
+ color_format = COLOR_FMT_NV12_BPP10_UBWC;
+ break;
+ default:
+ dprintk(VIDC_DBG,
+ "Invalid : g_fmt called on %s port with Invalid fourcc 0x%x\n",
+ port == OUTPUT_PORT ? "OUTPUT" : "CAPTURE",
+ inst->fmts[port].fourcc);
+ goto exit;
+ }
+
+ f->fmt.pix_mp.plane_fmt[0].bytesperline = VENUS_Y_STRIDE(color_format,
+ inst->prop.width[port]);
+ f->fmt.pix_mp.plane_fmt[0].reserved[0] = VENUS_Y_SCANLINES(color_format,
+ inst->prop.height[port]);
+
+exit:
+ return rc;
}
EXPORT_SYMBOL(msm_vidc_g_fmt);
@@ -769,7 +809,7 @@
MAX_PORT_NUM;
return port != MAX_PORT_NUM &&
- inst->fmts[port].num_planes == b->length;
+ inst->bufq[port].num_planes == b->length;
}
int msm_vidc_release_buffers(void *instance, int buffer_type)
@@ -1062,6 +1102,435 @@
.put_userptr = vidc_put_userptr,
};
+
+static void msm_vidc_cleanup_buffer(struct vb2_buffer *vb)
+{
+ int rc = 0;
+ struct buf_queue *q = NULL;
+ struct msm_vidc_inst *inst = NULL;
+
+ if (!vb) {
+ dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK",
+ __func__, vb);
+ return;
+ }
+
+ inst = vb2_get_drv_priv(vb->vb2_queue);
+ if (!inst) {
+ dprintk(VIDC_ERR, "%s : Invalid inst pointer",
+ __func__);
+ return;
+ }
+
+ q = msm_comm_get_vb2q(inst, vb->type);
+ if (!q) {
+ dprintk(VIDC_ERR,
+ "%s : Failed to find buffer queue for type = %d\n",
+ __func__, vb->type);
+ return;
+ }
+
+ if (q->vb2_bufq.streaming) {
+ dprintk(VIDC_DBG, "%d PORT is streaming\n",
+ vb->type);
+ return;
+ }
+
+ rc = msm_vidc_release_buffers(inst,
+ vb->type);
+ if (rc)
+ dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n",
+ __func__, rc);
+}
+
+static int set_buffer_count(struct msm_vidc_inst *inst,
+ int host_count, int act_count, enum hal_buffer type)
+{
+ int rc = 0;
+ struct hfi_device *hdev;
+ struct hal_buffer_count_actual buf_count;
+
+ hdev = inst->core->device;
+
+ buf_count.buffer_type = type;
+ buf_count.buffer_count_actual = act_count;
+ buf_count.buffer_count_min_host = host_count;
+ rc = call_hfi_op(hdev, session_set_property,
+ inst->session, HAL_PARAM_BUFFER_COUNT_ACTUAL, &buf_count);
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Failed to set actual buffer count %d for buffer type %d\n",
+ act_count, type);
+ return rc;
+}
+
+static int msm_vidc_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct msm_vidc_inst *inst;
+ int i, rc = 0;
+ struct hal_buffer_requirements *bufreq;
+ enum hal_buffer buffer_type;
+
+ if (!q || !num_buffers || !num_planes
+ || !sizes || !q->drv_priv) {
+ dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n",
+ q, num_buffers, num_planes);
+ return -EINVAL;
+ }
+ inst = q->drv_priv;
+
+ if (!inst || !inst->core || !inst->core->device) {
+ dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (q->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: {
+ bufreq = get_buff_req_buffer(inst,
+ HAL_BUFFER_INPUT);
+ if (!bufreq) {
+ dprintk(VIDC_ERR,
+ "Failed : No buffer requirements : %x\n",
+ HAL_BUFFER_INPUT);
+ return -EINVAL;
+ }
+ if (*num_buffers < bufreq->buffer_count_actual) {
+ dprintk(VIDC_ERR,
+ "Invalid parameters : Req = %d Act = %d\n",
+ *num_buffers, bufreq->buffer_count_actual);
+ return -EINVAL;
+ }
+ *num_planes = inst->bufq[OUTPUT_PORT].num_planes;
+ if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
+ *num_buffers > MAX_NUM_OUTPUT_BUFFERS)
+ *num_buffers = MIN_NUM_OUTPUT_BUFFERS;
+ for (i = 0; i < *num_planes; i++)
+ sizes[i] = inst->bufq[OUTPUT_PORT].plane_sizes[i];
+
+ bufreq->buffer_count_actual = *num_buffers;
+ rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
+ *num_buffers, HAL_BUFFER_INPUT);
+ }
+
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
+ buffer_type = msm_comm_get_hal_output_buffer(inst);
+ bufreq = get_buff_req_buffer(inst,
+ buffer_type);
+ if (!bufreq) {
+ dprintk(VIDC_ERR,
+ "Failed : No buffer requirements : %x\n",
+ buffer_type);
+ return -EINVAL;
+ }
+ if (*num_buffers < bufreq->buffer_count_actual) {
+ dprintk(VIDC_ERR,
+ "Invalid parameters : Req = %d Act = %d\n",
+ *num_buffers, bufreq->buffer_count_actual);
+ return -EINVAL;
+ }
+ *num_planes = inst->bufq[CAPTURE_PORT].num_planes;
+ if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
+ *num_buffers > MAX_NUM_CAPTURE_BUFFERS)
+ *num_buffers = MIN_NUM_CAPTURE_BUFFERS;
+
+ for (i = 0; i < *num_planes; i++)
+ sizes[i] = inst->bufq[CAPTURE_PORT].plane_sizes[i];
+
+ bufreq->buffer_count_actual = *num_buffers;
+ rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
+ *num_buffers, buffer_type);
+ }
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+static inline int msm_vidc_decide_core_and_power_mode(
+ struct msm_vidc_inst *inst)
+{
+ dprintk(VIDC_DBG,
+ "Core selection is not yet implemented for inst = %pK\n",
+ inst);
+ return 0;
+}
+static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst)
+{
+ int rc = 0, i = 0;
+
+ for (i = 0; i < HAL_BUFFER_MAX; i++) {
+ struct hal_buffer_requirements *req = &inst->buff_req.buffer[i];
+
+ dprintk(VIDC_DBG, "Verifying Buffer : %d\n", req->buffer_type);
+ if (!req ||
+ req->buffer_count_actual < req->buffer_count_min_host ||
+ req->buffer_count_min_host < req->buffer_count_min) {
+ dprintk(VIDC_ERR, "Invalid data : Counts mismatch\n");
+ dprintk(VIDC_ERR,
+ "Min Count = %d ", req->buffer_count_min);
+ dprintk(VIDC_ERR,
+ "Min Host Count = %d ",
+ req->buffer_count_min_host);
+ dprintk(VIDC_ERR,
+ "Min Actual Count = %d\n",
+ req->buffer_count_actual);
+ rc = -EINVAL;
+ break;
+ }
+ }
+ return rc;
+}
+
+static inline int start_streaming(struct msm_vidc_inst *inst)
+{
+ int rc = 0;
+ struct hfi_device *hdev;
+ struct hal_buffer_size_minimum b;
+ struct vb2_buf_entry *temp, *next;
+
+ hdev = inst->core->device;
+
+ /* Check if current session is under HW capability */
+ rc = msm_vidc_check_session_supported(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "This session is not supported %pK\n", inst);
+ goto fail_start;
+ }
+
+ /* Assign Core and LP mode for current session */
+ rc = msm_vidc_decide_core_and_power_mode(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "This session can't be submitted to HW%pK\n", inst);
+ goto fail_start;
+ }
+
+
+ if (msm_comm_get_stream_output_mode(inst) ==
+ HAL_VIDEO_DECODER_SECONDARY) {
+ b.buffer_type = HAL_BUFFER_OUTPUT2;
+ } else {
+ b.buffer_type = HAL_BUFFER_OUTPUT;
+ }
+
+ b.buffer_size = inst->bufq[CAPTURE_PORT].plane_sizes[0];
+ rc = call_hfi_op(hdev, session_set_property,
+ inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
+ &b);
+
+ rc = msm_comm_try_get_bufreqs(inst);
+
+ /* Check if current session is under HW capability */
+ rc = msm_vidc_verify_buffer_counts(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "This session has mis-match buffer counts%pK\n", inst);
+ goto fail_start;
+ }
+
+ rc = msm_comm_set_scratch_buffers(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to set scratch buffers: %d\n", rc);
+ goto fail_start;
+ }
+ rc = msm_comm_set_persist_buffers(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to set persist buffers: %d\n", rc);
+ goto fail_start;
+ }
+
+ if (msm_comm_get_stream_output_mode(inst) ==
+ HAL_VIDEO_DECODER_SECONDARY) {
+ rc = msm_comm_set_output_buffers(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to set output buffers: %d\n", rc);
+ goto fail_start;
+ }
+ }
+
+ /*
+ * For seq_changed_insufficient, driver should set session_continue
+ * to firmware after the following sequence
+ * - driver raises insufficient event to v4l2 client
+ * - all output buffers have been flushed and freed
+ * - v4l2 client queries buffer requirements and splits/combines OPB-DPB
+ * - v4l2 client sets new set of buffers to firmware
+ * - v4l2 client issues CONTINUE to firmware to resume decoding of
+ * submitted ETBs.
+ */
+ if (inst->in_reconfig) {
+ dprintk(VIDC_DBG, "send session_continue after reconfig\n");
+ rc = call_hfi_op(hdev, session_continue,
+ (void *) inst->session);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s - failed to send session_continue\n",
+ __func__);
+ goto fail_start;
+ }
+ }
+ inst->in_reconfig = false;
+
+ msm_comm_scale_clocks_and_bus(inst);
+
+ rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to move inst: %pK to start done state\n", inst);
+ goto fail_start;
+ }
+ msm_dcvs_init_load(inst);
+ if (msm_comm_get_stream_output_mode(inst) ==
+ HAL_VIDEO_DECODER_SECONDARY) {
+ rc = msm_comm_queue_output_buffers(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to queue output buffers: %d\n", rc);
+ goto fail_start;
+ }
+ }
+
+fail_start:
+ if (rc) {
+ mutex_lock(&inst->pendingq.lock);
+ list_for_each_entry_safe(temp, next, &inst->pendingq.list,
+ list) {
+ vb2_buffer_done(temp->vb,
+ VB2_BUF_STATE_QUEUED);
+ list_del(&temp->list);
+ kfree(temp);
+ }
+ mutex_unlock(&inst->pendingq.lock);
+ }
+ return rc;
+}
+
+
+static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct msm_vidc_inst *inst;
+ int rc = 0;
+ struct hfi_device *hdev;
+
+ if (!q || !q->drv_priv) {
+ dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
+ return -EINVAL;
+ }
+ inst = q->drv_priv;
+ if (!inst || !inst->core || !inst->core->device) {
+ dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+ hdev = inst->core->device;
+ dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
+ q->type, inst);
+ switch (q->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
+ rc = start_streaming(inst);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
+ rc = start_streaming(inst);
+ break;
+ default:
+ dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
+ rc = -EINVAL;
+ goto stream_start_failed;
+ }
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Streamon failed on: %d capability for inst: %pK\n",
+ q->type, inst);
+ goto stream_start_failed;
+ }
+
+ rc = msm_comm_qbuf(inst, NULL);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to commit buffers queued before STREAM_ON to hardware: %d\n",
+ rc);
+ goto stream_start_failed;
+ }
+
+stream_start_failed:
+ return rc;
+}
+
+static inline int stop_streaming(struct msm_vidc_inst *inst)
+{
+ int rc = 0;
+
+ rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Failed to move inst: %pK to state %d\n",
+ inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+ return rc;
+}
+
+static void msm_vidc_stop_streaming(struct vb2_queue *q)
+{
+ struct msm_vidc_inst *inst;
+ int rc = 0;
+
+ if (!q || !q->drv_priv) {
+ dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
+ return;
+ }
+
+ inst = q->drv_priv;
+ dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
+ switch (q->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
+ rc = stop_streaming(inst);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
+ rc = stop_streaming(inst);
+ break;
+ default:
+ dprintk(VIDC_ERR,
+ "Q-type is not supported: %d\n", q->type);
+ rc = -EINVAL;
+ break;
+ }
+
+ msm_comm_scale_clocks_and_bus(inst);
+
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Failed STOP Streaming inst = %pK on cap = %d\n",
+ inst, q->type);
+}
+
+static void msm_vidc_buf_queue(struct vb2_buffer *vb)
+{
+ int rc = msm_comm_qbuf(vb2_get_drv_priv(vb->vb2_queue), vb);
+
+ if (rc)
+ dprintk(VIDC_ERR, "Failed to queue buffer: %d\n", rc);
+}
+
+static const struct vb2_ops msm_vidc_vb2q_ops = {
+ .queue_setup = msm_vidc_queue_setup,
+ .start_streaming = msm_vidc_start_streaming,
+ .buf_queue = msm_vidc_buf_queue,
+ .buf_cleanup = msm_vidc_cleanup_buffer,
+ .stop_streaming = msm_vidc_stop_streaming,
+};
+
static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
enum v4l2_buf_type type, enum session_type sess)
{
@@ -1079,11 +1548,8 @@
q->type = type;
q->io_modes = VB2_MMAP | VB2_USERPTR;
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ q->ops = &msm_vidc_vb2q_ops;
- if (sess == MSM_VIDC_DECODER)
- q->ops = msm_vdec_get_vb2q_ops();
- else if (sess == MSM_VIDC_ENCODER)
- q->ops = msm_venc_get_vb2q_ops();
q->mem_ops = &msm_vidc_vb2_mem_ops;
q->drv_priv = inst;
q->allow_zero_bytesused = 1;
@@ -1214,9 +1680,152 @@
return rc;
}
+static int set_actual_buffer_count(struct msm_vidc_inst *inst,
+ int count, enum hal_buffer type)
+{
+ int rc = 0;
+ struct hfi_device *hdev;
+ struct hal_buffer_count_actual buf_count;
+
+ hdev = inst->core->device;
+
+ buf_count.buffer_type = type;
+ buf_count.buffer_count_min_host = count;
+ buf_count.buffer_count_actual = count;
+ rc = call_hfi_op(hdev, session_set_property,
+ inst->session, HAL_PARAM_BUFFER_COUNT_ACTUAL,
+ &buf_count);
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Failed to set actual count %d for buffer type %d\n",
+ count, type);
+ return rc;
+}
+
+
+static int msm_vdec_get_count(struct msm_vidc_inst *inst,
+ struct v4l2_ctrl *ctrl)
+{
+ int rc = 0;
+ struct hal_buffer_requirements *bufreq, *newreq;
+ enum hal_buffer buffer_type;
+
+ if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT) {
+ bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
+ if (!bufreq) {
+ dprintk(VIDC_ERR,
+ "Failed to find bufreqs for buffer type = %d\n",
+ HAL_BUFFER_INPUT);
+ return 0;
+ }
+ if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) {
+ ctrl->val = bufreq->buffer_count_min_host;
+ return 0;
+ }
+ if (ctrl->val > bufreq->buffer_count_min_host) {
+ dprintk(VIDC_DBG,
+ "Interesting : Usually shouldn't happen\n");
+ bufreq->buffer_count_min_host = ctrl->val;
+ }
+ rc = set_actual_buffer_count(inst, ctrl->val,
+ HAL_BUFFER_INPUT);
+ return rc;
+
+ } else if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE) {
+ int count = 0;
+
+ buffer_type = msm_comm_get_hal_output_buffer(inst);
+ bufreq = get_buff_req_buffer(inst,
+ buffer_type);
+ if (!bufreq) {
+ dprintk(VIDC_ERR,
+ "Failed to find bufreqs for buffer type = %d\n",
+ buffer_type);
+ return 0;
+ }
+ if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming) {
+ if (ctrl->val != bufreq->buffer_count_min_host)
+ return -EINVAL;
+ else
+ return 0;
+ }
+ count = bufreq->buffer_count_min_host;
+
+ if (inst->in_reconfig) {
+ rc = msm_comm_try_get_bufreqs(inst);
+ newreq = get_buff_req_buffer(inst,
+ buffer_type);
+ if (!newreq) {
+ dprintk(VIDC_ERR,
+ "Failed to find new bufreqs = %d\n",
+ buffer_type);
+ return 0;
+ }
+ newreq->buffer_count_min_host = count =
+ newreq->buffer_count_min +
+ msm_dcvs_get_extra_buff_count(inst);
+ }
+ if (!inst->in_reconfig &&
+ inst->state < MSM_VIDC_LOAD_RESOURCES_DONE) {
+ dprintk(VIDC_DBG, "Clients will correct this\n");
+ rc = set_actual_buffer_count(inst, ctrl->val,
+ buffer_type);
+ bufreq->buffer_count_min_host = ctrl->val;
+ return 0;
+ }
+ bufreq->buffer_count_min_host = ctrl->val = count;
+ rc = set_actual_buffer_count(inst, ctrl->val,
+ buffer_type);
+
+ return rc;
+ }
+ return -EINVAL;
+}
+
static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
- return 0;
+ int rc = 0;
+
+ /*
+ * HACK: unlock the control prior to querying the hardware. Otherwise
+ * lower level code that attempts to do g_ctrl() will end up deadlocking
+ * us.
+ */
+ v4l2_ctrl_unlock(ctrl);
+
+ switch (ctrl->id) {
+
+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
+ case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
+ ctrl->val = inst->profile;
+ break;
+
+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
+ ctrl->val = inst->level;
+ break;
+
+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+ ctrl->val = inst->entropy_mode;
+ break;
+
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
+ rc = msm_vdec_get_count(inst, ctrl);
+ break;
+ default:
+ /*
+ * Other controls aren't really volatile, shouldn't need to
+ * modify ctrl->value
+ */
+ break;
+ }
+ v4l2_ctrl_lock(ctrl);
+
+ return rc;
}
static int msm_vidc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 8a7c6a3..14725de 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -2450,7 +2450,7 @@
vb->timestamp = (time_usec * NSEC_PER_USEC);
extra_idx =
- EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
+ EXTRADATA_IDX(inst->bufq[CAPTURE_PORT].num_planes);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
vb->planes[extra_idx].m.userptr =
(unsigned long)fill_buf_done->extra_data_buffer;
@@ -4009,7 +4009,7 @@
data->buffer_type = msm_comm_get_hal_output_buffer(inst);
}
- extra_idx = EXTRADATA_IDX(inst->fmts[port].num_planes);
+ extra_idx = EXTRADATA_IDX(inst->bufq[port].num_planes);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
vb->planes[extra_idx].m.userptr) {
data->extradata_addr = vb->planes[extra_idx].m.userptr;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index f418260..5514c66 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -296,7 +296,7 @@
write_str(&dbg_buf, "capability: %s\n", i == OUTPUT_PORT ?
"Output" : "Capture");
write_str(&dbg_buf, "name : %s\n", inst->fmts[i].name);
- write_str(&dbg_buf, "planes : %d\n", inst->fmts[i].num_planes);
+ write_str(&dbg_buf, "planes : %d\n", inst->bufq[i].num_planes);
write_str(
&dbg_buf, "type: %s\n", inst->fmts[i].type == OUTPUT_PORT ?
"Output" : "Capture");
@@ -314,7 +314,7 @@
write_str(&dbg_buf, "count: %u\n",
inst->bufq[i].vb2_bufq.num_buffers);
- for (j = 0; j < inst->fmts[i].num_planes; j++)
+ for (j = 0; j < inst->bufq[i].num_planes; j++)
write_str(&dbg_buf, "size for plane %d: %u\n", j,
inst->bufq[i].plane_sizes[j]);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 4a14ca3..bebb5de 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -45,6 +45,11 @@
#define MIN_SUPPORTED_WIDTH 32
#define MIN_SUPPORTED_HEIGHT 32
#define DEFAULT_FPS 15
+#define MIN_NUM_OUTPUT_BUFFERS 1
+#define MIN_NUM_CAPTURE_BUFFERS 1
+#define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME
+#define MAX_NUM_CAPTURE_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME
+
/* Maintains the number of FTB's between each FBD over a window */
#define DCVS_FTB_WINDOW 32
@@ -145,7 +150,6 @@
char name[MAX_NAME_LENGTH];
u8 description[32];
u32 fourcc;
- int num_planes;
int type;
u32 (*get_frame_size)(int plane, u32 height, u32 width);
bool defer_outputs;
@@ -175,7 +179,8 @@
struct buf_queue {
struct vb2_queue vb2_bufq;
struct mutex lock;
- unsigned int plane_sizes[VB2_MAX_PLANES];
+ unsigned int plane_sizes[VB2_MAX_PLANES];
+ int num_planes;
};
enum profiling_points {
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index 3267999..7caff53 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -251,6 +251,7 @@
struct hfi_buffer_count_actual {
u32 buffer_type;
u32 buffer_count_actual;
+ u32 buffer_count_min_host;
};
struct hfi_buffer_size_minimum {
@@ -262,8 +263,8 @@
u32 buffer_type;
u32 buffer_size;
u32 buffer_region_size;
- u32 buffer_hold_count;
u32 buffer_count_min;
+ u32 buffer_count_min_host;
u32 buffer_count_actual;
u32 contiguous;
u32 buffer_alignment;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 11c4b98..151a82a 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -607,6 +607,7 @@
struct hal_buffer_count_actual {
enum hal_buffer buffer_type;
u32 buffer_count_actual;
+ u32 buffer_count_min_host;
};
struct hal_buffer_size_minimum {
@@ -826,8 +827,8 @@
enum hal_buffer buffer_type;
u32 buffer_size;
u32 buffer_region_size;
- u32 buffer_hold_count;
u32 buffer_count_min;
+ u32 buffer_count_min_host;
u32 buffer_count_actual;
u32 contiguous;
u32 buffer_alignment;