media: iris: Add V4L2 streaming support for encoder video device

Add support for V4L2 streaming operations on the encoder video device.
During stream-on, configure mandatory properties on the respective
planes and notify the firmware to initiate an encode session.

Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # X1E80100
Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e80100-crd
[bod: add sm8750 enc/dec declarations during merge process]
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
Dikshita Agarwal
2025-08-25 12:30:46 +05:30
committed by Hans Verkuil
parent 6bdfa3f947
commit 92e007ca5a
17 changed files with 790 additions and 410 deletions

View File

@@ -1,5 +1,5 @@
qcom-iris-objs += \
iris_buffer.o \
qcom-iris-objs += iris_buffer.o \
iris_common.o \
iris_core.o \
iris_ctrls.o \
iris_firmware.o \

View File

@@ -0,0 +1,196 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <media/v4l2-mem2mem.h>
#include "iris_common.h"
#include "iris_ctrls.h"
#include "iris_instance.h"
#include "iris_power.h"
int iris_process_streamon_input(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
enum iris_inst_sub_state set_sub_state = 0;
int ret;
iris_scale_power(inst);
ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
if (ret)
return ret;
}
if (inst->domain == DECODER &&
(inst->sub_state & IRIS_INST_SUB_DRC ||
inst->sub_state & IRIS_INST_SUB_DRAIN ||
inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) {
if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
if (hfi_ops->session_pause) {
ret = hfi_ops->session_pause(inst,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
}
set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
}
}
ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
inst->last_buffer_dequeued = false;
return iris_inst_change_sub_state(inst, 0, set_sub_state);
}
int iris_process_streamon_output(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
bool drain_active = false, drc_active = false;
enum iris_inst_sub_state clear_sub_state = 0;
int ret = 0;
iris_scale_power(inst);
drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN &&
inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
drc_active = inst->sub_state & IRIS_INST_SUB_DRC &&
inst->sub_state & IRIS_INST_SUB_DRC_LAST;
if (drc_active)
clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
else if (drain_active)
clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
if (inst->domain == DECODER && inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
ret = iris_alloc_and_queue_input_int_bufs(inst);
if (ret)
return ret;
ret = iris_set_stage(inst, STAGE);
if (ret)
return ret;
ret = iris_set_pipe(inst, PIPE);
if (ret)
return ret;
}
if (inst->state == IRIS_INST_INPUT_STREAMING &&
inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
if (!drain_active)
ret = hfi_ops->session_resume_drc(inst,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
else if (hfi_ops->session_resume_drain)
ret = hfi_ops->session_resume_drain(inst,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
}
if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC;
ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (ret)
return ret;
if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (ret)
return ret;
inst->last_buffer_dequeued = false;
return iris_inst_change_sub_state(inst, clear_sub_state, 0);
}
static void iris_flush_deferred_buffers(struct iris_inst *inst,
enum iris_buffer_type type)
{
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
struct v4l2_m2m_buffer *buffer, *n;
struct iris_buffer *buf;
if (type == BUF_INPUT) {
v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
buf = to_iris_buffer(&buffer->vb);
if (buf->attr & BUF_ATTR_DEFERRED) {
if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
buf->attr |= BUF_ATTR_BUFFER_DONE;
buf->data_size = 0;
iris_vb2_buffer_done(inst, buf);
}
}
}
} else {
v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
buf = to_iris_buffer(&buffer->vb);
if (buf->attr & BUF_ATTR_DEFERRED) {
if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
buf->attr |= BUF_ATTR_BUFFER_DONE;
buf->data_size = 0;
iris_vb2_buffer_done(inst, buf);
}
}
}
}
}
static void iris_kill_session(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
if (!inst->session_id)
return;
hfi_ops->session_close(inst);
iris_inst_change_state(inst, IRIS_INST_ERROR);
}
int iris_session_streamoff(struct iris_inst *inst, u32 plane)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
enum iris_buffer_type buffer_type;
int ret;
switch (plane) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
buffer_type = BUF_INPUT;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
buffer_type = BUF_OUTPUT;
break;
default:
return -EINVAL;
}
ret = hfi_ops->session_stop(inst, plane);
if (ret)
goto error;
ret = iris_inst_state_change_streamoff(inst, plane);
if (ret)
goto error;
iris_flush_deferred_buffers(inst, buffer_type);
return 0;
error:
iris_kill_session(inst);
iris_flush_deferred_buffers(inst, buffer_type);
return ret;
}

View File

@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __IRIS_COMMON_H__
#define __IRIS_COMMON_H__
struct iris_inst;
struct iris_buffer;
int iris_process_streamon_input(struct iris_inst *inst);
int iris_process_streamon_output(struct iris_inst *inst);
int iris_session_streamoff(struct iris_inst *inst, u32 plane);
#endif

View File

@@ -102,7 +102,7 @@ enum hfi_matrix_coefficients {
struct iris_hfi_prop_type_handle {
u32 type;
int (*handle)(struct iris_inst *inst);
int (*handle)(struct iris_inst *inst, u32 plane);
};
struct iris_hfi_command_ops {

View File

@@ -189,38 +189,65 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
u32 flush_type = 0;
int ret = 0;
if (inst->state == IRIS_INST_STREAMING) {
if (V4L2_TYPE_IS_OUTPUT(plane))
flush_type = HFI_FLUSH_ALL;
else if (V4L2_TYPE_IS_CAPTURE(plane))
flush_type = HFI_FLUSH_OUTPUT;
if (inst->domain == DECODER) {
if (inst->state == IRIS_INST_STREAMING) {
if (V4L2_TYPE_IS_OUTPUT(plane))
flush_type = HFI_FLUSH_ALL;
else if (V4L2_TYPE_IS_CAPTURE(plane))
flush_type = HFI_FLUSH_OUTPUT;
reinit_completion(&inst->flush_completion);
reinit_completion(&inst->flush_completion);
flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
flush_pkt.shdr.session_id = inst->session_id;
flush_pkt.flush_type = flush_type;
flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
flush_pkt.shdr.session_id = inst->session_id;
flush_pkt.flush_type = flush_type;
ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
if (!ret) {
inst->flush_responses_pending++;
ret = iris_wait_for_session_response(inst, true);
ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
if (!ret) {
inst->flush_responses_pending++;
ret = iris_wait_for_session_response(inst, true);
}
} else if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) {
reinit_completion(&inst->completion);
iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
if (!ret)
ret = iris_wait_for_session_response(inst, false);
reinit_completion(&inst->completion);
iris_hfi_gen1_packet_session_cmd(inst, &pkt,
HFI_CMD_SESSION_RELEASE_RESOURCES);
ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
if (!ret)
ret = iris_wait_for_session_response(inst, false);
iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
VB2_BUF_STATE_ERROR);
iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
VB2_BUF_STATE_ERROR);
}
} else if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) {
reinit_completion(&inst->completion);
iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
if (!ret)
ret = iris_wait_for_session_response(inst, false);
} else {
if (inst->state == IRIS_INST_STREAMING ||
inst->state == IRIS_INST_INPUT_STREAMING ||
inst->state == IRIS_INST_ERROR) {
reinit_completion(&inst->completion);
iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
if (!ret)
ret = iris_wait_for_session_response(inst, false);
reinit_completion(&inst->completion);
iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RESOURCES);
ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
if (!ret)
ret = iris_wait_for_session_response(inst, false);
reinit_completion(&inst->completion);
iris_hfi_gen1_packet_session_cmd(inst, &pkt,
HFI_CMD_SESSION_RELEASE_RESOURCES);
ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
if (!ret)
ret = iris_wait_for_session_response(inst, false);
iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
}
iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
VB2_BUF_STATE_ERROR);
@@ -549,7 +576,7 @@ static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet
return hfi_gen1_set_property(inst, packet_type, payload, payload_size);
}
static int iris_hfi_gen1_set_resolution(struct iris_inst *inst)
static int iris_hfi_gen1_set_resolution(struct iris_inst *inst, u32 plane)
{
u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
struct hfi_framesize fs;
@@ -564,14 +591,18 @@ static int iris_hfi_gen1_set_resolution(struct iris_inst *inst)
if (ret)
return ret;
}
fs.buffer_type = HFI_BUFFER_OUTPUT2;
if (inst->domain == DECODER)
fs.buffer_type = HFI_BUFFER_OUTPUT2;
else
fs.buffer_type = HFI_BUFFER_OUTPUT;
fs.width = inst->fmt_dst->fmt.pix_mp.width;
fs.height = inst->fmt_dst->fmt.pix_mp.height;
return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
}
static int iris_hfi_gen1_decide_core(struct iris_inst *inst)
static int iris_hfi_gen1_decide_core(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
struct hfi_videocores_usage_type cu;
@@ -581,36 +612,45 @@ static int iris_hfi_gen1_decide_core(struct iris_inst *inst)
return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu));
}
static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst)
static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
struct hfi_uncompressed_format_select fmt;
u32 pixelformat;
int ret;
if (iris_split_mode_enabled(inst)) {
fmt.buffer_type = HFI_BUFFER_OUTPUT;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0;
if (inst->domain == DECODER) {
pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
if (iris_split_mode_enabled(inst)) {
fmt.buffer_type = HFI_BUFFER_OUTPUT;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ?
HFI_COLOR_FORMAT_NV12_UBWC : 0;
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
if (ret)
return ret;
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
if (ret)
return ret;
fmt.buffer_type = HFI_BUFFER_OUTPUT2;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
fmt.buffer_type = HFI_BUFFER_OUTPUT2;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
} else {
fmt.buffer_type = HFI_BUFFER_OUTPUT;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
}
} else {
fmt.buffer_type = HFI_BUFFER_OUTPUT;
pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
fmt.buffer_type = HFI_BUFFER_INPUT;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
}
return ret;
}
static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst)
static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO;
struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
@@ -630,7 +670,7 @@ static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst)
return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint));
}
static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst, u32 plane)
{
u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
struct hfi_buffer_count_actual buf_count;
@@ -644,20 +684,28 @@ static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
if (ret)
return ret;
if (iris_split_mode_enabled(inst)) {
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = VIDEO_MAX_FRAME;
buf_count.count_min_host = VIDEO_MAX_FRAME;
if (inst->domain == DECODER) {
if (iris_split_mode_enabled(inst)) {
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = VIDEO_MAX_FRAME;
buf_count.count_min_host = VIDEO_MAX_FRAME;
ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
if (ret)
return ret;
ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
if (ret)
return ret;
buf_count.type = HFI_BUFFER_OUTPUT2;
buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB);
buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB);
buf_count.type = HFI_BUFFER_OUTPUT2;
buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB);
buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB);
ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
} else {
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = VIDEO_MAX_FRAME;
buf_count.count_min_host = VIDEO_MAX_FRAME;
ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
}
} else {
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = VIDEO_MAX_FRAME;
@@ -669,7 +717,7 @@ static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
return ret;
}
static int iris_hfi_gen1_set_multistream(struct iris_inst *inst)
static int iris_hfi_gen1_set_multistream(struct iris_inst *inst, u32 plane)
{
u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
struct hfi_multi_stream multi = {0};
@@ -704,7 +752,7 @@ static int iris_hfi_gen1_set_multistream(struct iris_inst *inst)
return ret;
}
static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
struct hfi_buffer_size_actual bufsz;
@@ -739,14 +787,49 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
return ret;
}
static int iris_hfi_gen1_set_frame_rate(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE;
struct hfi_framerate frate;
if (V4L2_TYPE_IS_OUTPUT(plane))
return 0;
frate.buffer_type = HFI_BUFFER_OUTPUT;
frate.framerate = inst->frame_rate << 16;
return hfi_gen1_set_property(inst, ptype, &frate, sizeof(frate));
}
static int iris_hfi_gen1_set_stride(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO;
struct hfi_uncompressed_plane_actual_info plane_actual_info;
plane_actual_info.buffer_type = HFI_BUFFER_INPUT;
plane_actual_info.num_planes = 2;
plane_actual_info.plane_format[0].actual_stride =
ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
plane_actual_info.plane_format[0].actual_plane_buffer_height =
ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
plane_actual_info.plane_format[1].actual_stride =
ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
plane_actual_info.plane_format[1].actual_plane_buffer_height =
(ALIGN(inst->fmt_src->fmt.pix_mp.height, 32)) / 2;
return hfi_gen1_set_property(inst, ptype, &plane_actual_info, sizeof(plane_actual_info));
}
static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane)
{
struct iris_hfi_prop_type_handle const *handler = NULL;
u32 handler_size = 0;
struct iris_core *core = inst->core;
u32 config_params_size, i, j;
const u32 *config_params;
int ret;
static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = {
static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_inp_arr[] = {
{HFI_PROPERTY_PARAM_FRAME_SIZE,
iris_hfi_gen1_set_resolution},
{HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE,
@@ -763,7 +846,7 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p
iris_hfi_gen1_set_bufsize},
};
static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = {
static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_out_arr[] = {
{HFI_PROPERTY_PARAM_FRAME_SIZE,
iris_hfi_gen1_set_resolution},
{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
@@ -778,29 +861,43 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p
iris_hfi_gen1_set_bufsize},
};
config_params = core->iris_platform_data->input_config_params_default;
config_params_size = core->iris_platform_data->input_config_params_default_size;
static const struct iris_hfi_prop_type_handle venc_prop_type_handle_inp_arr[] = {
{HFI_PROPERTY_CONFIG_FRAME_RATE,
iris_hfi_gen1_set_frame_rate},
{HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO,
iris_hfi_gen1_set_stride},
{HFI_PROPERTY_PARAM_FRAME_SIZE,
iris_hfi_gen1_set_resolution},
{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
iris_hfi_gen1_set_raw_format},
{HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
iris_hfi_gen1_set_num_bufs},
};
if (V4L2_TYPE_IS_OUTPUT(plane)) {
for (i = 0; i < config_params_size; i++) {
for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) {
if (prop_type_handle_inp_arr[j].type == config_params[i]) {
ret = prop_type_handle_inp_arr[j].handle(inst);
if (ret)
return ret;
break;
}
}
if (inst->domain == DECODER) {
config_params = core->iris_platform_data->dec_input_config_params_default;
config_params_size = core->iris_platform_data->dec_input_config_params_default_size;
if (V4L2_TYPE_IS_OUTPUT(plane)) {
handler = vdec_prop_type_handle_inp_arr;
handler_size = ARRAY_SIZE(vdec_prop_type_handle_inp_arr);
} else if (V4L2_TYPE_IS_CAPTURE(plane)) {
handler = vdec_prop_type_handle_out_arr;
handler_size = ARRAY_SIZE(vdec_prop_type_handle_out_arr);
}
} else if (V4L2_TYPE_IS_CAPTURE(plane)) {
for (i = 0; i < config_params_size; i++) {
for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) {
if (prop_type_handle_out_arr[j].type == config_params[i]) {
ret = prop_type_handle_out_arr[j].handle(inst);
if (ret)
return ret;
break;
}
} else {
config_params = core->iris_platform_data->enc_input_config_params;
config_params_size = core->iris_platform_data->enc_input_config_params_size;
handler = venc_prop_type_handle_inp_arr;
handler_size = ARRAY_SIZE(venc_prop_type_handle_inp_arr);
}
for (i = 0; i < config_params_size; i++) {
for (j = 0; j < handler_size; j++) {
if (handler[j].type == config_params[i]) {
ret = handler[j].handle(inst, plane);
if (ret)
return ret;
break;
}
}
}

View File

@@ -82,10 +82,12 @@
#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6
#define HFI_PROPERTY_PARAM_FRAME_SIZE 0x1001
#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO 0x1002
#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT 0x1003
#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT 0x1005
#define HFI_PROPERTY_PARAM_WORK_MODE 0x1015
#define HFI_PROPERTY_PARAM_WORK_ROUTE 0x1017
#define HFI_PROPERTY_CONFIG_FRAME_RATE 0x2001
#define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE 0x2002
#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM 0x1003001
@@ -348,6 +350,17 @@ struct hfi_uncompressed_plane_actual_constraints_info {
struct hfi_uncompressed_plane_constraints plane_format[2];
};
struct hfi_uncompressed_plane_actual {
int actual_stride;
u32 actual_plane_buffer_height;
};
struct hfi_uncompressed_plane_actual_info {
u32 buffer_type;
u32 num_planes;
struct hfi_uncompressed_plane_actual plane_format[2];
};
struct hfi_buffer_count_actual {
u32 type;
u32 count_actual;
@@ -375,6 +388,11 @@ struct hfi_buffer_requirements {
u32 alignment;
};
struct hfi_framerate {
u32 buffer_type;
u32 framerate;
};
struct hfi_event_data {
u32 error;
u32 height;

View File

@@ -88,15 +88,26 @@ static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core)
return ret;
}
static u32 iris_hfi_gen2_get_port(u32 plane)
static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane)
{
switch (plane) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
return HFI_PORT_BITSTREAM;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
return HFI_PORT_RAW;
default:
return HFI_PORT_NONE;
if (inst->domain == DECODER) {
switch (plane) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
return HFI_PORT_BITSTREAM;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
return HFI_PORT_RAW;
default:
return HFI_PORT_NONE;
}
} else {
switch (plane) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
return HFI_PORT_RAW;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
return HFI_PORT_BITSTREAM;
default:
return HFI_PORT_NONE;
}
}
}
@@ -136,34 +147,77 @@ static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet
inst_hfi_gen2->packet->size);
}
static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst)
static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
inst->fmt_src->fmt.pix_mp.height;
u32 port = iris_hfi_gen2_get_port(inst, plane);
inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
return iris_hfi_gen2_session_set_property(inst,
HFI_PROP_RAW_RESOLUTION,
HFI_HOST_FLAGS_NONE,
port,
HFI_PAYLOAD_32_PACKED,
&resolution,
sizeof(u32));
}
static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(inst, plane);
enum hfi_packet_payload_info payload_type;
u32 resolution, codec_align;
if (inst->domain == DECODER) {
resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
inst->fmt_src->fmt.pix_mp.height;
inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
payload_type = HFI_PAYLOAD_U32;
} else {
codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
resolution = ALIGN(inst->fmt_dst->fmt.pix_mp.width, codec_align) << 16 |
ALIGN(inst->fmt_dst->fmt.pix_mp.height, codec_align);
inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
payload_type = HFI_PAYLOAD_32_PACKED;
}
return iris_hfi_gen2_session_set_property(inst,
HFI_PROP_BITSTREAM_RESOLUTION,
HFI_HOST_FLAGS_NONE,
port,
HFI_PAYLOAD_U32,
payload_type,
&resolution,
sizeof(u32));
}
static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst)
static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
{
u32 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
u32 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 left_offset = inst->crop.left;
u32 top_offset = inst->crop.top;
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 bottom_offset, right_offset;
u32 left_offset, top_offset;
u32 payload[2];
if (inst->domain == DECODER) {
if (V4L2_TYPE_IS_OUTPUT(plane)) {
bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
left_offset = inst->crop.left;
top_offset = inst->crop.top;
} else {
bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height);
right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width);
left_offset = inst->compose.left;
top_offset = inst->compose.top;
}
} else {
bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
left_offset = inst->crop.left;
top_offset = inst->crop.top;
}
payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
@@ -178,10 +232,10 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst)
sizeof(u64));
}
static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 bitdepth = BIT_DEPTH_8;
inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
@@ -195,10 +249,10 @@ static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst)
static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 coded_frames = 0;
if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
@@ -214,11 +268,11 @@ static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst)
static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
u32 port = iris_hfi_gen2_get_port(inst, plane);
inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
@@ -231,10 +285,10 @@ static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst)
static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 poc = 0;
inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
@@ -248,16 +302,16 @@ static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst)
static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
u32 video_signal_type_present_flag = 0, color_info;
u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
u32 video_format = UNSPECIFIED_COLOR_FORMAT;
u32 full_range = V4L2_QUANTIZATION_DEFAULT;
u32 transfer_char = HFI_TRANSFER_RESERVED;
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 colour_description_present_flag = 0;
u32 primaries = HFI_PRIMARIES_RESERVED;
@@ -291,10 +345,10 @@ static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_profile(struct iris_inst *inst)
static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 profile = 0;
switch (inst->codec) {
@@ -320,10 +374,10 @@ static int iris_hfi_gen2_set_profile(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_level(struct iris_inst *inst)
static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 level = 0;
switch (inst->codec) {
@@ -349,33 +403,47 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst)
static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
{
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 hfi_colorformat, pixelformat;
pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
if (inst->domain == DECODER) {
pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
} else {
pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
}
return iris_hfi_gen2_session_set_property(inst,
HFI_PROP_COLOR_FORMAT,
HFI_HOST_FLAGS_NONE,
port,
HFI_PAYLOAD_U32,
HFI_PAYLOAD_U32_ENUM,
&hfi_colorformat,
sizeof(u32));
}
static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane)
{
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height;
u32 stride_y = inst->fmt_dst->fmt.pix_mp.width;
u32 scanline_uv = scanline_y / 2;
u32 stride_uv = stride_y;
u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv;
u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 payload[2];
if (inst->domain == DECODER) {
pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
stride_y = inst->fmt_dst->fmt.pix_mp.width;
scanline_y = inst->fmt_dst->fmt.pix_mp.height;
} else {
pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
}
stride_uv = stride_y;
scanline_uv = scanline_y / 2;
if (pixelformat != V4L2_PIX_FMT_NV12)
return 0;
@@ -386,15 +454,15 @@ static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
HFI_PROP_LINEAR_STRIDE_SCANLINE,
HFI_HOST_FLAGS_NONE,
port,
HFI_PAYLOAD_U64,
HFI_PAYLOAD_64_PACKED,
&payload,
sizeof(u64));
}
static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 tier = inst->fw_caps[TIER].value;
inst_hfi_gen2->src_subcr_params.tier = tier;
@@ -408,14 +476,29 @@ static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
sizeof(u32));
}
static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane)
{
u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
u32 frame_rate = inst->frame_rate << 16;
return iris_hfi_gen2_session_set_property(inst,
HFI_PROP_FRAME_RATE,
HFI_HOST_FLAGS_NONE,
port,
HFI_PAYLOAD_Q16,
&frame_rate,
sizeof(u32));
}
static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
{
struct iris_core *core = inst->core;
const struct iris_platform_data *pdata = inst->core->iris_platform_data;
u32 config_params_size = 0, i, j;
const u32 *config_params = NULL;
int ret;
static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
{HFI_PROP_RAW_RESOLUTION, iris_hfi_gen2_set_raw_resolution },
{HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },
{HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },
{HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames },
@@ -428,29 +511,35 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
{HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },
{HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },
{HFI_PROP_TIER, iris_hfi_gen2_set_tier },
{HFI_PROP_FRAME_RATE, iris_hfi_gen2_set_frame_rate },
};
if (V4L2_TYPE_IS_OUTPUT(plane)) {
switch (inst->codec) {
case V4L2_PIX_FMT_H264:
config_params = core->iris_platform_data->input_config_params_default;
config_params_size =
core->iris_platform_data->input_config_params_default_size;
break;
case V4L2_PIX_FMT_HEVC:
config_params = core->iris_platform_data->input_config_params_hevc;
config_params_size =
core->iris_platform_data->input_config_params_hevc_size;
break;
case V4L2_PIX_FMT_VP9:
config_params = core->iris_platform_data->input_config_params_vp9;
config_params_size =
core->iris_platform_data->input_config_params_vp9_size;
break;
if (inst->domain == DECODER) {
if (V4L2_TYPE_IS_OUTPUT(plane)) {
if (inst->codec == V4L2_PIX_FMT_H264) {
config_params = pdata->dec_input_config_params_default;
config_params_size = pdata->dec_input_config_params_default_size;
} else if (inst->codec == V4L2_PIX_FMT_HEVC) {
config_params = pdata->dec_input_config_params_hevc;
config_params_size = pdata->dec_input_config_params_hevc_size;
} else if (inst->codec == V4L2_PIX_FMT_VP9) {
config_params = pdata->dec_input_config_params_vp9;
config_params_size = pdata->dec_input_config_params_vp9_size;
} else {
return -EINVAL;
}
} else {
config_params = pdata->dec_output_config_params;
config_params_size = pdata->dec_output_config_params_size;
}
} else {
config_params = core->iris_platform_data->output_config_params;
config_params_size = core->iris_platform_data->output_config_params_size;
if (V4L2_TYPE_IS_OUTPUT(plane)) {
config_params = pdata->enc_input_config_params;
config_params_size = pdata->enc_input_config_params_size;
} else {
config_params = pdata->enc_output_config_params;
config_params_size = pdata->enc_output_config_params_size;
}
}
if (!config_params || !config_params_size)
@@ -459,7 +548,7 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
for (i = 0; i < config_params_size; i++) {
for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
if (prop_type_handle_arr[j].type == config_params[i]) {
ret = prop_type_handle_arr[j].handle(inst);
ret = prop_type_handle_arr[j].handle(inst, plane);
if (ret)
return ret;
break;
@@ -477,14 +566,19 @@ static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
switch (inst->codec) {
case V4L2_PIX_FMT_H264:
codec = HFI_CODEC_DECODE_AVC;
if (inst->domain == ENCODER)
codec = HFI_CODEC_ENCODE_AVC;
else
codec = HFI_CODEC_DECODE_AVC;
break;
case V4L2_PIX_FMT_HEVC:
codec = HFI_CODEC_DECODE_HEVC;
if (inst->domain == ENCODER)
codec = HFI_CODEC_ENCODE_HEVC;
else
codec = HFI_CODEC_DECODE_HEVC;
break;
case V4L2_PIX_FMT_VP9:
codec = HFI_CODEC_DECODE_VP9;
break;
}
iris_hfi_gen2_packet_session_property(inst,
@@ -550,9 +644,11 @@ static int iris_hfi_gen2_session_open(struct iris_inst *inst)
if (ret)
goto fail_free_packet;
ret = iris_hfi_gen2_session_set_default_header(inst);
if (ret)
goto fail_free_packet;
if (inst->domain == DECODER) {
ret = iris_hfi_gen2_session_set_default_header(inst);
if (ret)
goto fail_free_packet;
}
return 0;
@@ -601,7 +697,7 @@ static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
cmd,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
payload_type,
payload,
@@ -623,6 +719,9 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
u32 hfi_port = 0, i;
int ret;
if (inst->domain == ENCODER)
return 0;
if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
(V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
dev_err(core->dev, "invalid plane\n");
@@ -631,19 +730,19 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
switch (inst->codec) {
case V4L2_PIX_FMT_H264:
change_param = core->iris_platform_data->input_config_params_default;
change_param = core->iris_platform_data->dec_input_config_params_default;
change_param_size =
core->iris_platform_data->input_config_params_default_size;
core->iris_platform_data->dec_input_config_params_default_size;
break;
case V4L2_PIX_FMT_HEVC:
change_param = core->iris_platform_data->input_config_params_hevc;
change_param = core->iris_platform_data->dec_input_config_params_hevc;
change_param_size =
core->iris_platform_data->input_config_params_hevc_size;
core->iris_platform_data->dec_input_config_params_hevc_size;
break;
case V4L2_PIX_FMT_VP9:
change_param = core->iris_platform_data->input_config_params_vp9;
change_param = core->iris_platform_data->dec_input_config_params_vp9;
change_param_size =
core->iris_platform_data->input_config_params_vp9_size;
core->iris_platform_data->dec_input_config_params_vp9_size;
break;
}
@@ -664,7 +763,7 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
if (V4L2_TYPE_IS_OUTPUT(plane)) {
inst_hfi_gen2->ipsc_properties_set = true;
} else {
hfi_port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
memcpy(&inst_hfi_gen2->dst_subcr_params,
&inst_hfi_gen2->src_subcr_params,
sizeof(inst_hfi_gen2->src_subcr_params));
@@ -759,6 +858,9 @@ static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
payload[0] = HFI_MODE_PROPERTY;
if (inst->domain == ENCODER)
return 0;
if (V4L2_TYPE_IS_OUTPUT(plane)) {
subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
subcribe_prop = core->iris_platform_data->dec_input_prop;
@@ -810,7 +912,7 @@ static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
HFI_CMD_START,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -832,7 +934,7 @@ static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -854,7 +956,7 @@ static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
HFI_CMD_PAUSE,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -873,7 +975,7 @@ static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
HFI_CMD_RESUME,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_U32,
&payload,
@@ -892,7 +994,7 @@ static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
HFI_CMD_RESUME,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_U32,
&payload,
@@ -914,7 +1016,7 @@ static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
iris_hfi_gen2_get_port(plane),
iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,

View File

@@ -49,6 +49,7 @@
#define HFI_PROP_TIER 0x03000109
#define HFI_PROP_STAGE 0x0300010a
#define HFI_PROP_PIPE 0x0300010b
#define HFI_PROP_FRAME_RATE 0x0300010c
#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f
#define HFI_PROP_CODED_FRAMES 0x03000120
#define HFI_PROP_CABAC_SESSION 0x03000121
@@ -69,6 +70,8 @@
#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
#define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169
#define HFI_PROP_NO_OUTPUT 0x0300016a
#define HFI_PROP_BUFFER_MARK 0x0300016c
#define HFI_PROP_RAW_RESOLUTION 0x03000178
#define HFI_PROP_TOTAL_PEAK_BITRATE 0x0300017C
#define HFI_PROP_COMV_BUFFER_COUNT 0x03000193
#define HFI_PROP_END 0x03FFFFFF

View File

@@ -227,14 +227,18 @@ struct iris_platform_data {
u32 max_core_mbpf;
/* max number of macroblocks per second supported */
u32 max_core_mbps;
const u32 *input_config_params_default;
unsigned int input_config_params_default_size;
const u32 *input_config_params_hevc;
unsigned int input_config_params_hevc_size;
const u32 *input_config_params_vp9;
unsigned int input_config_params_vp9_size;
const u32 *output_config_params;
unsigned int output_config_params_size;
const u32 *dec_input_config_params_default;
unsigned int dec_input_config_params_default_size;
const u32 *dec_input_config_params_hevc;
unsigned int dec_input_config_params_hevc_size;
const u32 *dec_input_config_params_vp9;
unsigned int dec_input_config_params_vp9_size;
const u32 *dec_output_config_params;
unsigned int dec_output_config_params_size;
const u32 *enc_input_config_params;
unsigned int enc_input_config_params_size;
const u32 *enc_output_config_params;
unsigned int enc_output_config_params_size;
const u32 *dec_input_prop;
unsigned int dec_input_prop_size;
const u32 *dec_output_prop_avc;

View File

@@ -658,11 +658,25 @@ static const u32 sm8550_vdec_input_config_param_vp9[] = {
HFI_PROP_LEVEL,
};
static const u32 sm8550_venc_input_config_params[] = {
HFI_PROP_COLOR_FORMAT,
HFI_PROP_RAW_RESOLUTION,
HFI_PROP_CROP_OFFSETS,
HFI_PROP_LINEAR_STRIDE_SCANLINE,
HFI_PROP_SIGNAL_COLOR_INFO,
};
static const u32 sm8550_vdec_output_config_params[] = {
HFI_PROP_COLOR_FORMAT,
HFI_PROP_LINEAR_STRIDE_SCANLINE,
};
static const u32 sm8550_venc_output_config_params[] = {
HFI_PROP_BITSTREAM_RESOLUTION,
HFI_PROP_CROP_OFFSETS,
HFI_PROP_FRAME_RATE,
};
static const u32 sm8550_vdec_subscribe_input_properties[] = {
HFI_PROP_NO_OUTPUT,
};
@@ -726,22 +740,32 @@ struct iris_platform_data sm8550_data = {
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K * 2,
.max_core_mbps = ((7680 * 4320) / 256) * 60,
.input_config_params_default =
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.input_config_params_default_size =
.dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
.input_config_params_hevc =
.dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
.input_config_params_hevc_size =
.dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
.input_config_params_vp9 =
.dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
.input_config_params_vp9_size =
.dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
.output_config_params =
.dec_output_config_params =
sm8550_vdec_output_config_params,
.output_config_params_size =
.dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
.enc_input_config_params =
sm8550_venc_input_config_params,
.enc_input_config_params_size =
ARRAY_SIZE(sm8550_venc_input_config_params),
.enc_output_config_params =
sm8550_venc_output_config_params,
.enc_output_config_params_size =
ARRAY_SIZE(sm8550_venc_output_config_params),
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
@@ -804,22 +828,32 @@ struct iris_platform_data sm8650_data = {
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K * 2,
.max_core_mbps = ((7680 * 4320) / 256) * 60,
.input_config_params_default =
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.input_config_params_default_size =
.dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
.input_config_params_hevc =
.dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
.input_config_params_hevc_size =
.dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
.input_config_params_vp9 =
.dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
.input_config_params_vp9_size =
.dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
.output_config_params =
.dec_output_config_params =
sm8550_vdec_output_config_params,
.output_config_params_size =
.dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
.enc_input_config_params =
sm8550_venc_input_config_params,
.enc_input_config_params_size =
ARRAY_SIZE(sm8550_venc_input_config_params),
.enc_output_config_params =
sm8550_venc_output_config_params,
.enc_output_config_params_size =
ARRAY_SIZE(sm8550_venc_output_config_params),
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
@@ -872,22 +906,32 @@ struct iris_platform_data sm8750_data = {
.num_vpp_pipe = 4,
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K * 2,
.input_config_params_default =
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.input_config_params_default_size =
.dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
.input_config_params_hevc =
.dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
.input_config_params_hevc_size =
.dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
.input_config_params_vp9 =
.dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
.input_config_params_vp9_size =
.dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
.output_config_params =
.dec_output_config_params =
sm8550_vdec_output_config_params,
.output_config_params_size =
.dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
.enc_input_config_params =
sm8550_venc_input_config_params,
.enc_input_config_params_size =
ARRAY_SIZE(sm8550_venc_input_config_params),
.enc_output_config_params =
sm8550_venc_output_config_params,
.enc_output_config_params_size =
ARRAY_SIZE(sm8550_venc_output_config_params),
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
@@ -946,22 +990,32 @@ struct iris_platform_data qcs8300_data = {
.max_session_count = 16,
.max_core_mbpf = ((4096 * 2176) / 256) * 4,
.max_core_mbps = (((3840 * 2176) / 256) * 120),
.input_config_params_default =
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.input_config_params_default_size =
.dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
.input_config_params_hevc =
.dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
.input_config_params_hevc_size =
.dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
.input_config_params_vp9 =
.dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
.input_config_params_vp9_size =
.dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
.output_config_params =
.dec_output_config_params =
sm8550_vdec_output_config_params,
.output_config_params_size =
.dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
.enc_input_config_params =
sm8550_venc_input_config_params,
.enc_input_config_params_size =
ARRAY_SIZE(sm8550_venc_input_config_params),
.enc_output_config_params =
sm8550_venc_output_config_params,
.enc_output_config_params_size =
ARRAY_SIZE(sm8550_venc_output_config_params),
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,

View File

@@ -38,6 +38,14 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = {
};
static struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
{
.cap_id = STAGE,
.min = STAGE_1,
.max = STAGE_2,
.step_or_mask = 1,
.value = STAGE_2,
.hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
},
{
.cap_id = PROFILE_H264,
.min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
@@ -268,6 +276,14 @@ static const u32 sm8250_vdec_input_config_param_default[] = {
HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE,
};
static const u32 sm8250_venc_input_config_param[] = {
HFI_PROPERTY_CONFIG_FRAME_RATE,
HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO,
HFI_PROPERTY_PARAM_FRAME_SIZE,
HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
};
static const u32 sm8250_dec_ip_int_buf_tbl[] = {
BUF_BIN,
BUF_SCRATCH_1,
@@ -310,10 +326,13 @@ struct iris_platform_data sm8250_data = {
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K,
.max_core_mbps = ((7680 * 4320) / 256) * 60,
.input_config_params_default =
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
.input_config_params_default_size =
.dec_input_config_params_default_size =
ARRAY_SIZE(sm8250_vdec_input_config_param_default),
.enc_input_config_params = sm8250_venc_input_config_param,
.enc_input_config_params_size =
ARRAY_SIZE(sm8250_venc_input_config_param),
.dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl,
.dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl),

View File

@@ -7,9 +7,11 @@
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include "iris_common.h"
#include "iris_instance.h"
#include "iris_vb2.h"
#include "iris_vdec.h"
#include "iris_venc.h"
#include "iris_power.h"
static int iris_check_inst_mbpf(struct iris_inst *inst)
@@ -174,19 +176,35 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
if (ret)
goto error;
if (V4L2_TYPE_IS_OUTPUT(q->type))
ret = iris_vdec_streamon_input(inst);
else if (V4L2_TYPE_IS_CAPTURE(q->type))
ret = iris_vdec_streamon_output(inst);
if (V4L2_TYPE_IS_OUTPUT(q->type)) {
if (inst->domain == DECODER)
ret = iris_vdec_streamon_input(inst);
else
ret = iris_venc_streamon_input(inst);
} else if (V4L2_TYPE_IS_CAPTURE(q->type)) {
if (inst->domain == DECODER)
ret = iris_vdec_streamon_output(inst);
else
ret = iris_venc_streamon_output(inst);
}
if (ret)
goto error;
buf_type = iris_v4l2_type_to_driver(q->type);
if (inst->state == IRIS_INST_STREAMING)
ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB);
if (!ret)
ret = iris_queue_deferred_buffers(inst, buf_type);
if (inst->domain == DECODER) {
if (inst->state == IRIS_INST_STREAMING)
ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB);
if (!ret)
ret = iris_queue_deferred_buffers(inst, buf_type);
} else {
if (inst->state == IRIS_INST_STREAMING) {
ret = iris_queue_deferred_buffers(inst, BUF_INPUT);
if (!ret)
ret = iris_queue_deferred_buffers(inst, BUF_OUTPUT);
}
}
if (ret)
goto error;
@@ -218,7 +236,7 @@ void iris_vb2_stop_streaming(struct vb2_queue *q)
!V4L2_TYPE_IS_CAPTURE(q->type))
goto exit;
ret = iris_vdec_session_streamoff(inst, q->type);
ret = iris_session_streamoff(inst, q->type);
if (ret)
goto exit;

View File

@@ -7,6 +7,7 @@
#include <media/v4l2-mem2mem.h>
#include "iris_buffer.h"
#include "iris_common.h"
#include "iris_ctrls.h"
#include "iris_instance.h"
#include "iris_power.h"
@@ -312,125 +313,6 @@ void iris_vdec_src_change(struct iris_inst *inst)
v4l2_event_queue_fh(&inst->fh, &event);
}
static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,
enum iris_buffer_type type)
{
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
struct v4l2_m2m_buffer *buffer, *n;
struct iris_buffer *buf;
if (type == BUF_INPUT) {
v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
buf = to_iris_buffer(&buffer->vb);
if (buf->attr & BUF_ATTR_DEFERRED) {
if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
buf->attr |= BUF_ATTR_BUFFER_DONE;
buf->data_size = 0;
iris_vb2_buffer_done(inst, buf);
}
}
}
} else {
v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
buf = to_iris_buffer(&buffer->vb);
if (buf->attr & BUF_ATTR_DEFERRED) {
if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
buf->attr |= BUF_ATTR_BUFFER_DONE;
buf->data_size = 0;
iris_vb2_buffer_done(inst, buf);
}
}
}
}
}
static void iris_vdec_kill_session(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
if (!inst->session_id)
return;
hfi_ops->session_close(inst);
iris_inst_change_state(inst, IRIS_INST_ERROR);
}
int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
enum iris_buffer_type buffer_type;
int ret;
switch (plane) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
buffer_type = BUF_INPUT;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
buffer_type = BUF_OUTPUT;
break;
default:
return -EINVAL;
}
ret = hfi_ops->session_stop(inst, plane);
if (ret)
goto error;
ret = iris_inst_state_change_streamoff(inst, plane);
if (ret)
goto error;
iris_vdec_flush_deferred_buffers(inst, buffer_type);
return 0;
error:
iris_vdec_kill_session(inst);
iris_vdec_flush_deferred_buffers(inst, buffer_type);
return ret;
}
static int iris_vdec_process_streamon_input(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
enum iris_inst_sub_state set_sub_state = 0;
int ret;
iris_scale_power(inst);
ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
if (ret)
return ret;
}
if (inst->sub_state & IRIS_INST_SUB_DRC ||
inst->sub_state & IRIS_INST_SUB_DRAIN ||
inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) {
if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
if (hfi_ops->session_pause) {
ret = hfi_ops->session_pause(inst,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
}
set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
}
}
ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
return iris_inst_change_sub_state(inst, 0, set_sub_state);
}
int iris_vdec_streamon_input(struct iris_inst *inst)
{
int ret;
@@ -457,71 +339,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
if (ret)
return ret;
return iris_vdec_process_streamon_input(inst);
}
static int iris_vdec_process_streamon_output(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
bool drain_active = false, drc_active = false;
enum iris_inst_sub_state clear_sub_state = 0;
int ret = 0;
iris_scale_power(inst);
drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN &&
inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
drc_active = inst->sub_state & IRIS_INST_SUB_DRC &&
inst->sub_state & IRIS_INST_SUB_DRC_LAST;
if (drc_active)
clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
else if (drain_active)
clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
ret = iris_alloc_and_queue_input_int_bufs(inst);
if (ret)
return ret;
ret = iris_set_stage(inst, STAGE);
if (ret)
return ret;
ret = iris_set_pipe(inst, PIPE);
if (ret)
return ret;
}
if (inst->state == IRIS_INST_INPUT_STREAMING &&
inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
if (!drain_active)
ret = hfi_ops->session_resume_drc(inst,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
else if (hfi_ops->session_resume_drain)
ret = hfi_ops->session_resume_drain(inst,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
}
if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC;
ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (ret)
return ret;
if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (ret)
return ret;
inst->last_buffer_dequeued = false;
return iris_inst_change_sub_state(inst, clear_sub_state, 0);
return iris_process_streamon_input(inst);
}
int iris_vdec_streamon_output(struct iris_inst *inst)
@@ -543,7 +361,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
if (ret)
return ret;
ret = iris_vdec_process_streamon_output(inst);
ret = iris_process_streamon_output(inst);
if (ret)
goto error;
@@ -554,7 +372,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
return ret;
error:
iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
return ret;
}

View File

@@ -21,6 +21,5 @@ int iris_vdec_streamon_output(struct iris_inst *inst);
int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
int iris_vdec_start_cmd(struct iris_inst *inst);
int iris_vdec_stop_cmd(struct iris_inst *inst);
int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane);
#endif

View File

@@ -7,6 +7,7 @@
#include <media/v4l2-mem2mem.h>
#include "iris_buffer.h"
#include "iris_common.h"
#include "iris_ctrls.h"
#include "iris_instance.h"
#include "iris_venc.h"
@@ -425,3 +426,34 @@ int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
return 0;
}
int iris_venc_streamon_input(struct iris_inst *inst)
{
int ret;
ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
return iris_process_streamon_input(inst);
}
int iris_venc_streamon_output(struct iris_inst *inst)
{
int ret;
ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (ret)
goto error;
ret = iris_process_streamon_output(inst);
if (ret)
goto error;
return ret;
error:
iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
return ret;
}

View File

@@ -18,5 +18,7 @@ int iris_venc_subscribe_event(struct iris_inst *inst, const struct v4l2_event_su
int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s);
int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm);
int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm);
int iris_venc_streamon_input(struct iris_inst *inst);
int iris_venc_streamon_output(struct iris_inst *inst);
#endif

View File

@@ -656,6 +656,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_enc = {
.vidioc_s_selection = iris_s_selection,
.vidioc_s_parm = iris_s_parm,
.vidioc_g_parm = iris_g_parm,
.vidioc_streamon = v4l2_m2m_ioctl_streamon,
.vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
};
void iris_init_ops(struct iris_core *core)