mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
media: amphion: Trigger source change if colorspace changed
After encountering a colorspace change in the stream, the decoder sends a V4L2_EVENT_SOURCE_CHANGE event with changes set to V4L2_EVENT_SRC_CH_RESOLUTION. Then the client can detect and handle the colorspace change without any buffer reallocation Signed-off-by: Ming Qian <ming.qian@oss.nxp.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
parent
d85f3207d7
commit
bb22847d11
|
|
@ -950,7 +950,7 @@ static void vdec_stop_done(struct vpu_inst *inst)
|
|||
vpu_inst_unlock(inst);
|
||||
}
|
||||
|
||||
static bool vdec_check_source_change(struct vpu_inst *inst)
|
||||
static bool vdec_check_source_change(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
|
||||
{
|
||||
struct vdec_t *vdec = inst->priv;
|
||||
const struct vpu_format *sibling;
|
||||
|
|
@ -962,26 +962,35 @@ static bool vdec_check_source_change(struct vpu_inst *inst)
|
|||
return false;
|
||||
|
||||
sibling = vpu_helper_find_sibling(inst, inst->cap_format.type, inst->cap_format.pixfmt);
|
||||
if (sibling && vdec->codec_info.pixfmt == sibling->pixfmt)
|
||||
vdec->codec_info.pixfmt = inst->cap_format.pixfmt;
|
||||
if (sibling && hdr->pixfmt == sibling->pixfmt)
|
||||
hdr->pixfmt = inst->cap_format.pixfmt;
|
||||
|
||||
if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
|
||||
return true;
|
||||
if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
|
||||
if (inst->cap_format.pixfmt != hdr->pixfmt)
|
||||
return true;
|
||||
if (inst->cap_format.width != vdec->codec_info.decoded_width)
|
||||
if (inst->cap_format.width != hdr->decoded_width)
|
||||
return true;
|
||||
if (inst->cap_format.height != vdec->codec_info.decoded_height)
|
||||
if (inst->cap_format.height != hdr->decoded_height)
|
||||
return true;
|
||||
if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
|
||||
return true;
|
||||
if (inst->crop.left != vdec->codec_info.offset_x)
|
||||
if (inst->crop.left != hdr->offset_x)
|
||||
return true;
|
||||
if (inst->crop.top != vdec->codec_info.offset_y)
|
||||
if (inst->crop.top != hdr->offset_y)
|
||||
return true;
|
||||
if (inst->crop.width != vdec->codec_info.width)
|
||||
if (inst->crop.width != hdr->width)
|
||||
return true;
|
||||
if (inst->crop.height != vdec->codec_info.height)
|
||||
if (inst->crop.height != hdr->height)
|
||||
return true;
|
||||
if (!hdr->progressive)
|
||||
return true;
|
||||
|
||||
if (vdec->seq_hdr_found &&
|
||||
(hdr->color_primaries != vdec->codec_info.color_primaries ||
|
||||
hdr->transfer_chars != vdec->codec_info.transfer_chars ||
|
||||
hdr->matrix_coeffs != vdec->codec_info.matrix_coeffs ||
|
||||
hdr->full_range != vdec->codec_info.full_range))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -1333,20 +1342,25 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info
|
|||
struct vdec_t *vdec = inst->priv;
|
||||
|
||||
vpu_inst_lock(inst);
|
||||
memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
|
||||
|
||||
vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n",
|
||||
vpu_trace(inst->dev,
|
||||
"[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d, colorspace: %d, %d, %d, %d\n",
|
||||
inst->id,
|
||||
vdec->codec_info.decoded_width,
|
||||
vdec->codec_info.decoded_height,
|
||||
vdec->codec_info.offset_x,
|
||||
vdec->codec_info.offset_y,
|
||||
vdec->codec_info.width,
|
||||
vdec->codec_info.height,
|
||||
hdr->decoded_width,
|
||||
hdr->decoded_height,
|
||||
hdr->offset_x,
|
||||
hdr->offset_y,
|
||||
hdr->width,
|
||||
hdr->height,
|
||||
hdr->num_ref_frms,
|
||||
hdr->num_dpb_frms);
|
||||
hdr->num_dpb_frms,
|
||||
hdr->color_primaries,
|
||||
hdr->transfer_chars,
|
||||
hdr->matrix_coeffs,
|
||||
hdr->full_range);
|
||||
inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
|
||||
vdec->is_source_changed = vdec_check_source_change(inst);
|
||||
vdec->is_source_changed = vdec_check_source_change(inst, hdr);
|
||||
memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
|
||||
vdec_init_fmt(inst);
|
||||
vdec_init_crop(inst);
|
||||
vdec_init_mbi(inst);
|
||||
|
|
@ -1375,7 +1389,12 @@ static void vdec_event_resolution_change(struct vpu_inst *inst)
|
|||
{
|
||||
struct vdec_t *vdec = inst->priv;
|
||||
|
||||
vpu_trace(inst->dev, "[%d]\n", inst->id);
|
||||
vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
|
||||
inst->id,
|
||||
vdec->params.frame_count,
|
||||
vdec->decoded_frame_count,
|
||||
vdec->display_frame_count,
|
||||
vdec->sequence);
|
||||
vpu_inst_lock(inst);
|
||||
vdec->seq_tag = vdec->codec_info.tag;
|
||||
vdec_clear_fs(&vdec->mbi);
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ static int vpu_notify_eos(struct vpu_inst *inst)
|
|||
int vpu_notify_source_change(struct vpu_inst *inst)
|
||||
{
|
||||
static const struct v4l2_event ev = {
|
||||
.id = 0,
|
||||
.type = V4L2_EVENT_SOURCE_CHANGE,
|
||||
.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user