video: driver: add enumerate format support

Add below configuration
- format enumeration
- set format for encoder
- get inst capabilities based on codec from core

Change-Id: I2484056ae688cf7b634c5137631197a83c382950
Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
This commit is contained in:
Maheshwar Ajja
2020-08-20 09:26:07 -07:00
parent 25f6fd7e7e
commit cd536c944c
13 ha cambiato i file con 638 aggiunte e 116 eliminazioni

Vedi File

@@ -82,9 +82,23 @@ static struct msm_platform_core_capability core_data_waipio[] = {
};
static struct msm_platform_inst_capability instance_data_waipio[] = {
/* {type, domains, codecs, min, max, step_or_menu, value} */
/* {type, domains, codecs, min, max, step_or_mask, value} */
{FRAME_WIDTH, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1920},
{FRAME_HEIGHT, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1080},
{PIX_FMTS, ENC, CODECS_ALL,
MSM_VIDC_FMT_NV12,
MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS,
MSM_VIDC_FMT_NV12 | MSM_VIDC_FMT_NV21 | MSM_VIDC_FMT_NV12_UBWC |
MSM_VIDC_FMT_NV12_P010_UBWC | MSM_VIDC_FMT_NV12_TP10_UBWC |
MSM_VIDC_FMT_RGBA8888_UBWC | MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS,
MSM_VIDC_FMT_NV12_UBWC},
{PIX_FMTS, DEC, CODECS_ALL,
MSM_VIDC_FMT_NV12,
MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS,
MSM_VIDC_FMT_NV12 | MSM_VIDC_FMT_NV21 | MSM_VIDC_FMT_NV12_UBWC |
MSM_VIDC_FMT_NV12_P010_UBWC | MSM_VIDC_FMT_NV12_TP10_UBWC |
MSM_VIDC_FMT_RGBA8888_UBWC | MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS,
MSM_VIDC_FMT_NV12_UBWC},
/* (8192 * 4320) / 256 */
{MBPF, ENC|DEC, CODECS_ALL, 64, 138240, 1, 138240},
/* ((1920 * 1088) / 256) * 960 fps */

Vedi File

@@ -15,6 +15,7 @@ int msm_vdec_stop_output(struct msm_vidc_inst *inst);
int msm_vdec_start_output(struct msm_vidc_inst *inst);
int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
int msm_vdec_inst_init(struct msm_vidc_inst *inst);
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);

Vedi File

@@ -9,6 +9,9 @@
#include "msm_vidc_core.h"
#include "msm_vidc_inst.h"
int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
int msm_venc_inst_init(struct msm_vidc_inst *inst);
int msm_venc_ctrl_init(struct msm_vidc_inst *inst);

Vedi File

@@ -76,6 +76,7 @@ struct msm_vidc_core {
u32 spur_count;
u32 reg_count;
bool power_enabled;
u32 codecs_count;
struct msm_vidc_core_capability *capabilities;
struct msm_vidc_inst_capability *inst_caps;
struct msm_vidc_mem_addr sfr;

Vedi File

@@ -66,6 +66,11 @@ static inline bool is_thumbnail_session(struct msm_vidc_inst *inst)
return false; // TODO: fix it
}
u32 get_v4l2_codec_from_vidc(enum msm_vidc_codec_type codec);
enum msm_vidc_codec_type get_vidc_codec_from_v4l2(u32 v4l2_codec);
u32 get_v4l2_colorformat_from_vidc(enum msm_vidc_colorformat_type colorformat);
enum msm_vidc_colorformat_type get_vidc_colorformat_from_v4l2(u32 colorformat);
u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt);
int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
enum msm_vidc_inst_state state);
int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
@@ -87,7 +92,6 @@ void msm_vidc_fw_unload_handler(struct work_struct *work);
void msm_vidc_batch_handler(struct work_struct *work);
int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst);
int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst);
u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt);
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl);
int msm_vidc_get_port_from_v4l2_type(u32 type);
u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,

Vedi File

@@ -169,6 +169,7 @@ enum msm_vidc_inst_capability_type {
INST_CAP_NONE = 0,
FRAME_WIDTH,
FRAME_HEIGHT,
PIX_FMTS,
MBPF,
MBPS,
FRAME_RATE,
@@ -223,7 +224,7 @@ struct msm_vidc_inst_cap {
enum msm_vidc_inst_capability_type cap;
s32 min;
s32 max;
u32 step_or_menu;
u32 step_or_mask;
s32 value;
enum msm_vidc_inst_capability_flags flags;
u32 v4l2_id;

Vedi File

@@ -21,7 +21,7 @@ struct msm_platform_inst_capability {
enum msm_vidc_codec_type codec;
s32 min;
s32 max;
u32 step_or_menu;
u32 step_or_mask;
s32 value;
enum msm_vidc_inst_capability_flags flags;
u32 v4l2_id;

Vedi File

@@ -18,6 +18,7 @@
static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
{
int rc = 0;
int i;
struct msm_vidc_core *core;
d_vpr_h("%s()\n", __func__);
@@ -27,6 +28,20 @@ static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
}
core = inst->core;
inst->capabilities = NULL;
for (i = 0; i < core->codecs_count; i++) {
if (core->inst_caps[i].domain == MSM_VIDC_DECODER &&
core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
inst->fmts[INPUT_PORT].fmt.pix.pixelformat)) {
s_vpr_h(inst->sid, "%s: changed capabilities to %#x caps\n",
__func__, inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
inst->capabilities = &core->inst_caps[i];
}
}
if (!inst->capabilities) {
s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
return -EINVAL;
}
return rc;
}
@@ -300,7 +315,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
}
inst->buffers.input.size = fmt->fmt.pix.sizeimage;
// update crop dimensions
/* update crop dimensions */
inst->crop.x = inst->crop.y = 0;
inst->crop.width = f->fmt.pix.width;
inst->crop.height = f->fmt.pix.height;
@@ -351,10 +366,10 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
fmt->type = OUTPUT_PLANE;
fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat;
fmt->fmt.pix.width = VENUS_Y_STRIDE(
msm_vidc_convert_color_fmt(fmt->fmt.pix.pixelformat),
get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat),
f->fmt.pix.width);
fmt->fmt.pix.height = VENUS_Y_SCANLINES(
msm_vidc_convert_color_fmt(fmt->fmt.pix.pixelformat),
get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat),
f->fmt.pix.height);
fmt->fmt.pix.bytesperline = fmt->fmt.pix.width;
fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size,
@@ -416,7 +431,7 @@ err_invalid_fmt:
int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
{
int rc = 0;
u32 index;
int port;
d_vpr_h("%s()\n", __func__);
if (!inst) {
@@ -424,19 +439,58 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
return -EINVAL;
}
if (f->type == OUTPUT_PLANE) {
index = OUTPUT_PORT;
} else if (f->type == INPUT_PLANE) {
index = OUTPUT_PORT;
} else if (f->type == OUTPUT_META_PLANE) {
index = OUTPUT_PORT;
} else if (f->type == OUTPUT_META_PLANE) {
index = OUTPUT_PORT;
} else {
d_vpr_e("%s: invalid type %d\n", __func__, f->type);
port = msm_vidc_get_port_from_v4l2_type(f->type);
if (port < 0) {
d_vpr_e("%s: invalid format type %d\n", __func__, f->type);
return -EINVAL;
}
memcpy(f, &inst->fmts[index], sizeof(struct v4l2_format));
memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
return rc;
}
int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
{
int rc = 0;
enum msm_vidc_codec_type codec;
enum msm_vidc_colorformat_type colorformat;
struct msm_vidc_core *core;
if (!inst || !inst->core || !inst->capabilities || !f) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (f->index >=
sizeof(inst->capabilities->cap[PIX_FMTS].step_or_mask) * 8) {
d_vpr_e("%s: invalid index %d\n", __func__, f->index);
return -EINVAL;
}
memset(f->reserved, 0, sizeof(f->reserved));
if (f->type == INPUT_PLANE) {
codec = core->capabilities[DEC_CODECS].value & f->index;
f->pixelformat = get_v4l2_codec_from_vidc(codec);
if (!f->pixelformat)
return -EINVAL;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strlcpy(f->description, "codec", sizeof(f->description));
} else if (f->type == OUTPUT_PLANE) {
colorformat = f->index &
inst->capabilities->cap[PIX_FMTS].step_or_mask;
f->pixelformat = get_v4l2_colorformat_from_vidc(colorformat);
if (!f->pixelformat)
return -EINVAL;
strlcpy(f->description, "colorformat", sizeof(f->description));
} else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
if (!f->index) {
f->pixelformat = V4L2_PIX_FMT_VIDC_META;
strlcpy(f->description, "metadata", sizeof(f->description));
} else {
return -EINVAL;
}
}
return rc;
}
@@ -444,6 +498,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
int msm_vdec_inst_init(struct msm_vidc_inst *inst)
{
int rc = 0;
int i;
struct msm_vidc_core *core;
struct v4l2_format *f;
@@ -473,6 +528,10 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
inst->buffers.input.extra_count;
inst->buffers.input.size = f->fmt.pix.sizeimage;
inst->crop.x = inst->crop.y = 0;
inst->crop.width = f->fmt.pix.width;
inst->crop.height = f->fmt.pix.height;
f = &inst->fmts[INPUT_META_PORT];
f->type = INPUT_META_PLANE;
f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
@@ -487,9 +546,9 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
f->type = OUTPUT_PLANE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12_UBWC;
f->fmt.pix.width = VENUS_Y_STRIDE(
msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
f->fmt.pix.height = VENUS_Y_SCANLINES(
msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
f->fmt.pix.bytesperline = f->fmt.pix.width;
f->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_OUTPUT);
@@ -515,6 +574,21 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
inst->prop.frame_rate = DEFAULT_FPS << 16;
inst->prop.operating_rate = DEFAULT_FPS << 16;
inst->capabilities = NULL;
for (i = 0; i < core->codecs_count; i++) {
if (core->inst_caps[i].domain == MSM_VIDC_DECODER &&
core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
inst->fmts[INPUT_PORT].fmt.pix.pixelformat)) {
s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
__func__, inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
inst->capabilities = &core->inst_caps[i];
}
}
if (!inst->capabilities) {
s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
return -EINVAL;
}
return rc;
}

Vedi File

@@ -14,10 +14,277 @@
#include "msm_vidc_platform.h"
#include "msm_vidc_debug.h"
static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 codec)
{
int rc = 0;
int i;
struct msm_vidc_core *core;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
inst->capabilities = NULL;
for (i = 0; i < core->codecs_count; i++) {
if (core->inst_caps[i].domain == MSM_VIDC_ENCODER &&
core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat)) {
s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
__func__, inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
inst->capabilities = &core->inst_caps[i];
}
}
if (!inst->capabilities) {
s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
return -EINVAL;
}
return rc;
}
int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
{
int rc = 0;
struct msm_vidc_core *core;
struct v4l2_format *fmt;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (inst->state == MSM_VIDC_START) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
if (f->type == INPUT_PLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[INPUT_PORT];
fmt->type = INPUT_PLANE;
fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat;
fmt->fmt.pix.width = VENUS_Y_STRIDE(
get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat),
f->fmt.pix.width);
fmt->fmt.pix.height = VENUS_Y_SCANLINES(
get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat),
f->fmt.pix.height);
fmt->fmt.pix.bytesperline = fmt->fmt.pix.width;
fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT);
if (inst->buffers.input.actual_count <
inst->buffers.input.min_count +
inst->buffers.input.extra_count) {
inst->buffers.input.actual_count =
inst->buffers.input.min_count +
inst->buffers.input.extra_count;
}
inst->buffers.input.size = fmt->fmt.pix.sizeimage;
//rc = msm_vidc_check_session_supported(inst);
if (rc)
goto err_invalid_fmt;
//update_log_ctxt(inst->sid, inst->session_type,
// mplane->pixelformat);
s_vpr_h(inst->sid,
"%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n",
__func__, f->fmt.pix.pixelformat, f->fmt.pix.width,
f->fmt.pix.height, fmt->fmt.pix.sizeimage,
inst->buffers.input.min_count,
inst->buffers.input.extra_count);
//msm_vidc_update_dcvs(inst);
//msm_vidc_update_batching(inst);
} else if (f->type == INPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[INPUT_META_PORT];
fmt->type = INPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_INPUT_META);
inst->buffers.input_meta.min_count =
inst->buffers.input.min_count;
inst->buffers.input_meta.extra_count =
inst->buffers.input.extra_count;
inst->buffers.input_meta.actual_count =
inst->buffers.input.actual_count;
inst->buffers.input_meta.size = fmt->fmt.meta.buffersize;
s_vpr_h(inst->sid,
"%s: input meta: size %d min_count %d extra_count %d\n",
__func__, fmt->fmt.meta.buffersize,
inst->buffers.input_meta.min_count,
inst->buffers.input_meta.extra_count);
} else if (f->type == OUTPUT_PLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[OUTPUT_PORT];
if (fmt->fmt.pix.pixelformat != f->fmt.pix.pixelformat) {
s_vpr_e(inst->sid,
"%s: codec changed from %#x to %#x\n", __func__,
fmt->fmt.pix.pixelformat, f->fmt.pix.pixelformat);
rc = msm_venc_codec_change(inst, f->fmt.pix.pixelformat);
if (rc)
goto err_invalid_fmt;
}
fmt->type = OUTPUT_PLANE;
fmt->fmt.pix.width = ALIGN(f->fmt.pix.width, 16);
fmt->fmt.pix.height = ALIGN(f->fmt.pix.height, 16);
fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat;
fmt->fmt.pix.bytesperline = 0;
fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT);
if (inst->buffers.output.actual_count <
inst->buffers.output.min_count +
inst->buffers.output.extra_count) {
inst->buffers.output.actual_count =
inst->buffers.output.min_count +
inst->buffers.output.extra_count;
}
inst->buffers.output.size = fmt->fmt.pix.sizeimage;
//rc = msm_vidc_check_session_supported(inst);
if (rc)
goto err_invalid_fmt;
/* update crop dimensions */
inst->crop.x = inst->crop.y = 0;
inst->crop.width = f->fmt.pix.width;
inst->crop.height = f->fmt.pix.height;
//update_log_ctxt(inst->sid, inst->session_type,
// mplane->pixelformat);
s_vpr_h(inst->sid,
"%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n",
__func__, fmt->fmt.pix.pixelformat, fmt->fmt.pix.width,
fmt->fmt.pix.height, fmt->fmt.pix.sizeimage,
inst->buffers.output.min_count,
inst->buffers.output.extra_count);
} else if (f->type == OUTPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[OUTPUT_META_PORT];
fmt->type = OUTPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_OUTPUT_META);
inst->buffers.output_meta.min_count =
inst->buffers.output.min_count;
inst->buffers.output_meta.extra_count =
inst->buffers.output.extra_count;
inst->buffers.output_meta.actual_count =
inst->buffers.output.actual_count;
inst->buffers.output_meta.size = fmt->fmt.meta.buffersize;
s_vpr_h(inst->sid,
"%s: input meta: size %d min_count %d extra_count %d\n",
__func__, fmt->fmt.meta.buffersize,
inst->buffers.output_meta.min_count,
inst->buffers.output_meta.extra_count);
} else {
s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, f->type);
goto err_invalid_fmt;
}
memcpy(f, fmt, sizeof(struct v4l2_format));
err_invalid_fmt:
return rc;
}
int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
{
int rc = 0;
int port;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
port = msm_vidc_get_port_from_v4l2_type(f->type);
if (port < 0) {
d_vpr_e("%s: invalid format type %d\n", __func__, f->type);
return -EINVAL;
}
memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
return rc;
}
int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
{
int rc = 0;
enum msm_vidc_codec_type codec;
enum msm_vidc_colorformat_type colorformat;
struct msm_vidc_core *core;
if (!inst || !inst->core || !inst->capabilities || !f) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (f->index >=
sizeof(inst->capabilities->cap[PIX_FMTS].step_or_mask) * 8) {
d_vpr_e("%s: invalid index %d\n", __func__, f->index);
return -EINVAL;
}
memset(f->reserved, 0, sizeof(f->reserved));
if (f->type == OUTPUT_PLANE) {
codec = core->capabilities[DEC_CODECS].value & f->index;
f->pixelformat = get_v4l2_codec_from_vidc(codec);
if (!f->pixelformat)
return -EINVAL;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strlcpy(f->description, "codec", sizeof(f->description));
} else if (f->type == INPUT_PLANE) {
colorformat = f->index &
inst->capabilities->cap[PIX_FMTS].step_or_mask;
f->pixelformat = get_v4l2_colorformat_from_vidc(colorformat);
if (!f->pixelformat)
return -EINVAL;
strlcpy(f->description, "colorformat", sizeof(f->description));
} else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
if (!f->index) {
f->pixelformat = V4L2_PIX_FMT_VIDC_META;
strlcpy(f->description, "metadata", sizeof(f->description));
} else {
return -EINVAL;
}
}
return rc;
}
int msm_venc_inst_init(struct msm_vidc_inst *inst)
{
int rc = 0;
int i;
struct msm_vidc_core *core;
struct v4l2_format *f;
@@ -45,6 +312,10 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
inst->buffers.output.extra_count;
inst->buffers.output.size = f->fmt.pix.sizeimage;
inst->crop.x = inst->crop.y = 0;
inst->crop.width = f->fmt.pix.width;
inst->crop.height = f->fmt.pix.height;
f = &inst->fmts[OUTPUT_META_PORT];
f->type = OUTPUT_META_PLANE;
f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
@@ -59,9 +330,9 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
f->type = INPUT_PLANE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12_UBWC;
f->fmt.pix.width = VENUS_Y_STRIDE(
msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
f->fmt.pix.height = VENUS_Y_SCANLINES(
msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
f->fmt.pix.bytesperline = f->fmt.pix.width;
f->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_INPUT);
@@ -87,6 +358,21 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
inst->prop.frame_rate = DEFAULT_FPS << 16;
inst->prop.operating_rate = DEFAULT_FPS << 16;
inst->capabilities = NULL;
for (i = 0; i < core->codecs_count; i++) {
if (core->inst_caps[i].domain == MSM_VIDC_ENCODER &&
core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat)) {
s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
__func__, inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
inst->capabilities = &core->inst_caps[i];
}
}
if (!inst->capabilities) {
s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
return -EINVAL;
}
return rc;
}

Vedi File

@@ -25,61 +25,63 @@ bool valid_v4l2_buffer(struct v4l2_buffer *b,
{
return true;
}
/*
static int get_poll_flags(struct msm_vidc_inst *inst)
static int get_poll_flags(struct msm_vidc_inst *inst, u32 port)
{
int rc = 0;
struct vb2_queue *outq = &inst->bufq[PORT_INPUT].vb2_bufq;
struct vb2_queue *capq = &inst->bufq[PORT_OUTPUT].vb2_bufq;
struct vb2_buffer *out_vb = NULL;
struct vb2_buffer *cap_vb = NULL;
int poll = 0;
struct vb2_queue *q = NULL;
struct vb2_buffer *vb = NULL;
unsigned long flags = 0;
if (v4l2_event_pending(&inst->event_handler))
rc |= POLLPRI;
if (!inst || port >= MAX_PORT) {
d_vpr_e("%s: invalid params, inst %pK, port %d\n",
__func__, inst, port);
return poll;
}
q = &inst->vb2q[port];
spin_lock_irqsave(&capq->done_lock, flags);
if (!list_empty(&capq->done_list))
cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
done_entry);
if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE
|| cap_vb->state == VB2_BUF_STATE_ERROR))
rc |= POLLIN | POLLRDNORM;
spin_unlock_irqrestore(&capq->done_lock, flags);
spin_lock_irqsave(&q->done_lock, flags);
if (!list_empty(&q->done_list))
vb = list_first_entry(&q->done_list, struct vb2_buffer,
done_entry);
if (vb && (vb->state == VB2_BUF_STATE_DONE ||
vb->state == VB2_BUF_STATE_ERROR)) {
if (port == OUTPUT_PORT || port == OUTPUT_META_PORT)
poll |= POLLIN | POLLRDNORM;
else if (port == INPUT_PORT || port == INPUT_META_PORT)
poll |= POLLOUT | POLLWRNORM;
}
spin_unlock_irqrestore(&q->done_lock, flags);
spin_lock_irqsave(&outq->done_lock, flags);
if (!list_empty(&outq->done_list))
out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
done_entry);
if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE
|| out_vb->state == VB2_BUF_STATE_ERROR))
rc |= POLLOUT | POLLWRNORM;
spin_unlock_irqrestore(&outq->done_lock, flags);
return rc;
return poll;
}
*/
int msm_vidc_poll(void *instance, struct file *filp,
struct poll_table_struct *wait)
{
/*
int poll = 0;
struct msm_vidc_inst *inst = instance;
struct vb2_queue *outq = NULL;
struct vb2_queue *capq = NULL;
if (!inst)
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
outq = &inst->bufq[PORT_INPUT].vb2_bufq;
capq = &inst->bufq[PORT_OUTPUT].vb2_bufq;
}
poll_wait(filp, &inst->event_handler.wait, wait);
poll_wait(filp, &capq->done_wq, wait);
poll_wait(filp, &outq->done_wq, wait);
return get_poll_flags(inst);
*/
return 0;
poll_wait(filp, &inst->vb2q[INPUT_META_PORT].done_wq, wait);
poll_wait(filp, &inst->vb2q[OUTPUT_META_PORT].done_wq, wait);
poll_wait(filp, &inst->vb2q[INPUT_PORT].done_wq, wait);
poll_wait(filp, &inst->vb2q[OUTPUT_PORT].done_wq, wait);
if (v4l2_event_pending(&inst->event_handler))
poll |= POLLPRI;
poll |= get_poll_flags(inst, INPUT_META_PORT);
poll |= get_poll_flags(inst, OUTPUT_META_PORT);
poll |= get_poll_flags(inst, INPUT_PORT);
poll |= get_poll_flags(inst, OUTPUT_PORT);
return poll;
}
EXPORT_SYMBOL(msm_vidc_poll);
@@ -87,14 +89,16 @@ int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
{
struct msm_vidc_inst *inst = instance;
if (!inst || !cap)
if (!inst || !cap) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
cap->bus_info[0] = 0;
cap->version = MSM_VIDC_VERSION;
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
V4L2_CAP_VIDEO_OUTPUT_MPLANE |
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE |
V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_META_OUTPUT |
V4L2_CAP_STREAMING;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -115,13 +119,16 @@ int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
{
struct msm_vidc_inst *inst = instance;
if (!inst || !f)
if (!inst || !f) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->domain == MSM_VIDC_DECODER)
return -EINVAL;//msm_vdec_enum_fmt(instance, f);
else if (inst->domain == MSM_VIDC_ENCODER)
return -EINVAL;//msm_venc_enum_fmt(instance, f);
return msm_vdec_enum_fmt(inst, f);
if (inst->domain == MSM_VIDC_ENCODER)
return msm_venc_enum_fmt(inst, f);
return -EINVAL;
}
EXPORT_SYMBOL(msm_vidc_enum_fmt);
@@ -200,8 +207,10 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
int rc = 0;
struct msm_vidc_inst *inst = instance;
if (!inst || !f)
if (!inst || !f) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (f->type == INPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
@@ -225,7 +234,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
if (inst->domain == MSM_VIDC_DECODER)
rc = msm_vdec_s_fmt(inst, f);
if (inst->domain == MSM_VIDC_ENCODER)
rc = 0;//msm_venc_s_fmt(instance, f);
rc = msm_venc_s_fmt(inst, f);
return rc;
}
@@ -236,13 +245,15 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
int rc = 0;
struct msm_vidc_inst *inst = instance;
if (!inst || !f)
if (!inst || !f) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->domain == MSM_VIDC_DECODER)
rc = msm_vdec_g_fmt(inst, f);
if (inst->domain == MSM_VIDC_ENCODER)
rc = 0;//msm_venc_g_fmt(instance, f);
rc = msm_venc_g_fmt(inst, f);
return rc;
}
@@ -265,9 +276,10 @@ int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
struct v4l2_ctrl *ctrl = NULL;
int rc = 0;
if (!inst || !control)
if (!inst || !control) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
ctrl = v4l2_ctrl_find(&inst->ctrl_handler, control->id);
if (ctrl) {
rc = msm_vidc_get_control(inst, ctrl);
@@ -285,8 +297,10 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
struct msm_vidc_inst *inst = instance;
int port;
if (!inst || !b)
if (!inst || !b) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
mutex_lock(&inst->lock);
@@ -347,8 +361,10 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
enum msm_vidc_inst_state new_state = 0;
int port;
if (!inst)
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
mutex_lock(&inst->lock);
@@ -425,8 +441,10 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
enum msm_vidc_inst_state new_state = 0;
int port;
if (!inst)
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
mutex_lock(&inst->lock);
@@ -524,10 +542,11 @@ int msm_vidc_subscribe_event(void *instance,
int rc = 0;
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
if (!inst || !sub)
if (!inst || !sub) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
s_vpr_e(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
}
s_vpr_h(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
rc = v4l2_event_subscribe(&inst->event_handler,
sub, MAX_EVENTS, NULL);
return rc;
@@ -540,10 +559,11 @@ int msm_vidc_unsubscribe_event(void *instance,
int rc = 0;
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
if (!inst || !sub)
if (!inst || !sub) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
s_vpr_e(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
}
s_vpr_h(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
rc = v4l2_event_unsubscribe(&inst->event_handler, sub);
return rc;
}
@@ -554,9 +574,10 @@ int msm_vidc_dqevent(void *instance, struct v4l2_event *event)
int rc = 0;
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
if (!inst || !event)
if (!inst || !event) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = v4l2_event_dequeue(&inst->event_handler, event, false);
return rc;
}

Vedi File

@@ -148,7 +148,7 @@ u32 msm_vidc_decoder_output_size(struct msm_vidc_inst *inst)
struct v4l2_format *f;
f = &inst->fmts[OUTPUT_PORT];
format = msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat);
format = get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat);
return VENUS_BUFFER_SIZE(format, f->fmt.pix.width,
f->fmt.pix.height);
}
@@ -169,7 +169,7 @@ u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst)
struct v4l2_format *f;
f = &inst->fmts[INPUT_PORT];
format = msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat);
format = get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat);
return VENUS_BUFFER_SIZE(format, f->fmt.pix.width,
f->fmt.pix.height);
}

Vedi File

@@ -26,6 +26,145 @@ void print_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *b)
{
}
enum msm_vidc_codec_type get_vidc_codec_from_v4l2(u32 v4l2_codec)
{
enum msm_vidc_codec_type codec = 0;
switch (v4l2_codec) {
case V4L2_PIX_FMT_H264:
codec = MSM_VIDC_H264;
break;
case V4L2_PIX_FMT_HEVC:
codec = MSM_VIDC_HEVC;
break;
case V4L2_PIX_FMT_VP9:
codec = MSM_VIDC_VP9;
break;
case V4L2_PIX_FMT_MPEG2:
codec = MSM_VIDC_MPEG2;
break;
default:
d_vpr_e("%s: vidc codec not found for %#x\n", __func__, v4l2_codec);
break;
}
return codec;
}
u32 get_v4l2_codec_from_vidc(enum msm_vidc_codec_type codec)
{
u32 v4l2_codec = 0;
switch (codec) {
case MSM_VIDC_H264:
v4l2_codec = V4L2_PIX_FMT_H264;
break;
case MSM_VIDC_HEVC:
v4l2_codec = V4L2_PIX_FMT_HEVC;
break;
case MSM_VIDC_VP9:
v4l2_codec = V4L2_PIX_FMT_VP9;
break;
case MSM_VIDC_MPEG2:
v4l2_codec = V4L2_PIX_FMT_MPEG2;
break;
default:
d_vpr_e("%s: v4l2 codec not found for %#x\n", __func__, codec);
break;
}
return v4l2_codec;
}
enum msm_vidc_colorformat_type get_vidc_colorformat_from_v4l2(u32 v4l2_colorformat)
{
enum msm_vidc_colorformat_type colorformat = 0;
switch (v4l2_colorformat) {
case V4L2_PIX_FMT_NV12:
colorformat = MSM_VIDC_FMT_NV12;
break;
case V4L2_PIX_FMT_NV21:
colorformat = MSM_VIDC_FMT_NV21;
break;
case V4L2_PIX_FMT_NV12_UBWC:
colorformat = MSM_VIDC_FMT_NV12_UBWC;
break;
case V4L2_PIX_FMT_NV12_TP10_UBWC:
colorformat = MSM_VIDC_FMT_NV12_TP10_UBWC;
break;
case V4L2_PIX_FMT_RGBA8888_UBWC:
colorformat = MSM_VIDC_FMT_RGBA8888_UBWC;
break;
case V4L2_PIX_FMT_NV12_P010_UBWC:
colorformat = MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
break;
case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
colorformat = MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
break;
default:
d_vpr_e("%s: vidc format not found for %#x\n", __func__, v4l2_colorformat);
break;
}
return colorformat;
}
u32 get_v4l2_colorformat_from_vidc(enum msm_vidc_colorformat_type colorformat)
{
u32 v4l2_colorformat = 0;
switch (colorformat) {
case MSM_VIDC_FMT_NV12:
v4l2_colorformat = V4L2_PIX_FMT_NV12;
break;
case MSM_VIDC_FMT_NV21:
v4l2_colorformat = V4L2_PIX_FMT_NV21;
break;
case MSM_VIDC_FMT_NV12_UBWC:
v4l2_colorformat = V4L2_PIX_FMT_NV12_UBWC;
break;
case MSM_VIDC_FMT_NV12_TP10_UBWC:
v4l2_colorformat = V4L2_PIX_FMT_NV12_TP10_UBWC;
break;
case MSM_VIDC_FMT_RGBA8888_UBWC:
v4l2_colorformat = V4L2_PIX_FMT_RGBA8888_UBWC;
break;
case MSM_VIDC_FMT_NV12_P010_UBWC:
v4l2_colorformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
break;
case MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
v4l2_colorformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
break;
default:
d_vpr_e("%s: v4l2 format not found for %#x\n", __func__, colorformat);
break;
}
return v4l2_colorformat;
}
u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt)
{
switch (v4l2_fmt) {
case V4L2_PIX_FMT_NV12:
return COLOR_FMT_NV12;
case V4L2_PIX_FMT_NV21:
return COLOR_FMT_NV21;
case V4L2_PIX_FMT_NV12_512:
return COLOR_FMT_NV12_512;
case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
return COLOR_FMT_P010;
case V4L2_PIX_FMT_NV12_UBWC:
return COLOR_FMT_NV12_UBWC;
case V4L2_PIX_FMT_NV12_TP10_UBWC:
return COLOR_FMT_NV12_BPP10_UBWC;
case V4L2_PIX_FMT_RGBA8888_UBWC:
return COLOR_FMT_RGBA8888_UBWC;
default:
d_vpr_e(
"Invalid v4l2 color fmt FMT : %x, Set default(NV12)",
v4l2_fmt);
return COLOR_FMT_NV12;
}
}
int msm_vidc_get_port_from_v4l2_type(u32 type)
{
int port;
@@ -227,31 +366,6 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
return rc;
}
u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt)
{
switch (v4l2_fmt) {
case V4L2_PIX_FMT_NV12:
return COLOR_FMT_NV12;
case V4L2_PIX_FMT_NV21:
return COLOR_FMT_NV21;
case V4L2_PIX_FMT_NV12_512:
return COLOR_FMT_NV12_512;
case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
return COLOR_FMT_P010;
case V4L2_PIX_FMT_NV12_UBWC:
return COLOR_FMT_NV12_UBWC;
case V4L2_PIX_FMT_NV12_TP10_UBWC:
return COLOR_FMT_NV12_BPP10_UBWC;
case V4L2_PIX_FMT_RGBA8888_UBWC:
return COLOR_FMT_RGBA8888_UBWC;
default:
d_vpr_e(
"Invalid v4l2 color fmt FMT : %x, Set default(NV12)",
v4l2_fmt);
return COLOR_FMT_NV12;
}
}
int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
@@ -609,7 +723,7 @@ static void update_inst_capability(struct msm_platform_inst_capability *in,
capability->cap[in->cap].cap = in->cap;
capability->cap[in->cap].min = in->min;
capability->cap[in->cap].max = in->max;
capability->cap[in->cap].step_or_menu = in->step_or_menu;
capability->cap[in->cap].step_or_mask = in->step_or_mask;
capability->cap[in->cap].value = in->value;
capability->cap[in->cap].flags = in->flags;
capability->cap[in->cap].v4l2_id = in->v4l2_id;
@@ -658,6 +772,8 @@ static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
count_bits = dec_valid_codecs;
COUNT_BITS(count_bits, codecs_count);
core->codecs_count = codecs_count;
if (!core->inst_caps) {
core->inst_caps = kcalloc(codecs_count,
sizeof(struct msm_vidc_inst_capability),

Vedi File

@@ -118,7 +118,8 @@ static int msm_vidc_register_video_device(struct msm_vidc_core *core,
core->vdev[index].type = type;
core->vdev[index].vdev.v4l2_dev = &core->v4l2_dev;
core->vdev[index].vdev.device_caps =
V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE |
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE |
V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_META_OUTPUT |
V4L2_CAP_STREAMING;
rc = video_register_device(&core->vdev[index].vdev,
VFL_TYPE_GRABBER, nr);