summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 5959f61c677c..691fd2b89b5c 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -605,6 +605,9 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
static int vdec_hal_to_v4l2(int id, int value);
+static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
+ struct v4l2_ext_controls *ctrl);
+
static u32 get_frame_size_nv12(int plane,
u32 height, u32 width)
{
@@ -1583,6 +1586,11 @@ static int set_max_internal_buffers_size(struct msm_vidc_inst *inst)
{
int rc = 0;
struct msm_vidc_list *buf_list = &inst->scratchbufs;
+ enum multi_stream stream_mode;
+ struct hfi_device *hdev;
+ struct hal_buffer_requirements *output_buf;
+ u32 output_count_actual;
+
struct {
enum hal_buffer type;
struct hal_buffer_requirements *req;
@@ -1594,6 +1602,10 @@ static int set_max_internal_buffers_size(struct msm_vidc_inst *inst)
struct hal_frame_size frame_sz;
int i;
+ struct v4l2_ext_controls ext_ctrls;
+ struct v4l2_ext_control controls[2];
+
+ hdev = inst->core->device;
mutex_lock(&buf_list->lock);
if (!list_empty(&buf_list->list)) {
dprintk(VIDC_DBG, "Scratch list already has allocated buf\n");
@@ -1613,6 +1625,36 @@ static int set_max_internal_buffers_size(struct msm_vidc_inst *inst)
frame_sz.buffer_type, frame_sz.width,
frame_sz.height, inst->capability.mbs_per_frame.max);
+ stream_mode = msm_comm_get_stream_output_mode(inst);
+
+ if (stream_mode == HAL_VIDEO_DECODER_PRIMARY) {
+ output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
+ if (!output_buf) {
+ dprintk(VIDC_ERR,
+ "No buffer requirement for buffer type %x\n",
+ HAL_BUFFER_OUTPUT);
+ rc = -EINVAL;
+ goto alloc_fail;
+ }
+ output_count_actual = output_buf->buffer_count_actual;
+ ext_ctrls.count = 2;
+ ext_ctrls.controls = controls;
+ controls[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
+ controls[0].value =
+ V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
+ controls[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
+ controls[1].value = V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC;
+ rc = try_set_ext_ctrl(inst, &ext_ctrls);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s Failed to move to split mode %d\n",
+ __func__, rc);
+ goto alloc_fail;
+ }
+ }
+
+ msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
+ frame_sz.buffer_type = HAL_BUFFER_OUTPUT2;
msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
rc = msm_comm_try_get_bufreqs(inst);
if (rc) {
@@ -1639,6 +1681,31 @@ static int set_max_internal_buffers_size(struct msm_vidc_inst *inst)
internal_buffers[i].type, internal_buffers[i].size);
}
+ if (stream_mode == HAL_VIDEO_DECODER_PRIMARY) {
+ ext_ctrls.count = 2;
+ ext_ctrls.controls = controls;
+ controls[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
+ controls[0].value =
+ V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
+ controls[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
+ controls[1].value = V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE;
+ rc = try_set_ext_ctrl(inst, &ext_ctrls);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to move to split mode %d\n",
+ rc);
+ goto alloc_fail;
+ }
+ rc = set_actual_buffer_count(inst, output_count_actual,
+ HAL_BUFFER_OUTPUT);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to set output buffer count(%u): %d\n",
+ output_count_actual, rc);
+ goto alloc_fail;
+ }
+ }
+
frame_sz.buffer_type = HAL_BUFFER_INPUT;
frame_sz.width = inst->prop.width[OUTPUT_PORT];
frame_sz.height = inst->prop.height[OUTPUT_PORT];