vdec: CF1 VDEC ErrorCodes Report [1/1]
PD#SWPL-167458
Problem:
VDEC ErrorCodes Report
Solution:
Added INPUT_UNDERRUN , OUTPUT_UNDERRUN,
OUTPUT_BUFFFER_NOT_READY, BAD_INPUT,
PROFILLE_LEVEL_NOT_SUPPORTED message reporting.
Verify:
S4
Change-Id: Ifd8523e81349ecf8eed424588a3c1ddf6c900684
Signed-off-by: xing.xu <xing.xu@amlogic.com>
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c
index 1f24dab..8736380 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -828,3 +828,22 @@
return;
}
+
+int vdec_get_decoder_buffer_status(struct aml_vdec_adapt *ada_ctx)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+ struct aml_vcodec_ctx *ctx = ada_ctx->ctx;
+ int buffer_status = 0;
+
+ if (!ctx->v4l_codec_dpb_ready)
+ buffer_status |= DEC_STATUS_OUTPUT_BUFFFER_NOT_READY;
+
+ if ((ctx->vpp_is_need ? ctx->picinfo.vpp_margin : ctx->picinfo.dpb_margin) <
+ (CTX_BUF_TOTAL(ctx) + ctx->out_buff_cnt - ctx->in_buff_cnt))
+ buffer_status |= DEC_STATUS_OUTPUT_UNDERRUN;
+
+ if (!vdec->input.have_frame_num)
+ buffer_status |= DEC_STATUS_INPUT_UNDERRUN;
+
+ return buffer_status;
+}
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h
index 2bed397..8e0cff4 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.h
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.h
@@ -48,6 +48,12 @@
char *frm_name;
};
+enum DEC_STATUS {
+ DEC_STATUS_INPUT_UNDERRUN = 1,
+ DEC_STATUS_OUTPUT_UNDERRUN = 2,
+ DEC_STATUS_OUTPUT_BUFFFER_NOT_READY = 4,
+};
+
int video_decoder_init(struct aml_vdec_adapt *ada_ctx);
int video_decoder_release(struct aml_vdec_adapt *ada_ctx);
@@ -102,5 +108,7 @@
void vdec_thread_wakeup(struct aml_vdec_adapt *ada_ctx);
+int vdec_get_decoder_buffer_status(struct aml_vdec_adapt *ada_ctx);
+
#endif /* VDEC_ADAPT_H */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index a3f1164..c31a02e 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -437,6 +437,7 @@
{
struct v4l2_event event = {0};
const char *event_str = event_to_string(changes);
+ int events = 0;
switch (changes) {
case V4L2_EVENT_SRC_CH_RESOLUTION:
@@ -451,12 +452,26 @@
break;
case V4L2_EVENT_SEND_ERROR:
event.type = V4L2_EVENT_PRIVATE_EXT_SEND_ERROR;
+
+#ifdef CONFIG_AMLOGIC_MEDIA_PROXY
+ if (ctx->decoder_status_info.error_type & (1 << 24)) {
+ events = MEDIA_ERRORCODES_VDEC_F_NO_MEMORY;
+ } else if (ctx->decoder_status_info.error_type & (1 << 25)) {
+ events = MEDIA_ERRORCODES_VDEC_E_PROFILELEVEL_NOT_SUPPORTED;
+ }
+
+ aml_vdec_notify_msg_to_mediaproxy(ctx, MEDIA_VIDEO_ERROR_EVENT, NULL, events);
+#endif
break;
case V4L2_EVENT_REPORT_ERROR_FRAME:
event.type = V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME;
memcpy(event.u.data, &ctx->current_timestamp, sizeof(u64));
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "report error frame timestamp: %llu\n",
ctx->current_timestamp);
+#ifdef CONFIG_AMLOGIC_MEDIA_PROXY
+ events = MEDIA_ERRORCODES_VDEC_M_BAD_INPUT;
+ aml_vdec_notify_msg_to_mediaproxy(ctx, MEDIA_VIDEO_ERROR_EVENT, NULL, events);
+#endif
break;
case V4L2_EVENT_REPORT_DEC_INFO:
event.type = V4L2_EVENT_PRIVATE_EXT_REPORT_DECINFO;
@@ -961,27 +976,32 @@
#ifdef CONFIG_AMLOGIC_MEDIA_PROXY
void aml_vdec_notify_msg_to_mediaproxy(struct aml_vcodec_ctx *ctx,
- int type, struct vframe_s *vf)
+ int type, struct vframe_s *vf, int event)
{
struct aml_video_user_data msg;
memset(&msg, 0, sizeof(struct aml_video_user_data));
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s bitstreamid: %llu instid: %u frame_index: %u time: %llu\n",
- __func__, div64_u64(vf->timestamp, 1000000000),
- vf->decoder_instid, vf->frame_index,
- ktime_get_real_ns());
-
- msg.data.frame_info.bitstreamid = div64_u64(vf->timestamp, 1000000000);
- msg.data.frame_info.decoder_instid = vf->decoder_instid;
- msg.data.frame_info.frame_index = vf->frame_index;
- msg.data.frame_info.time = ktime_get_real_ns();
- msg.data.frame_info.drop = 0;
-
- if (type == MEDIA_VIDEO_METRICS_FRAME_DECODED_INFO)
+ if (type == MEDIA_VIDEO_METRICS_FRAME_DECODED_INFO) {
msg.message_type = MEDIA_VIDEO_METRICS_FRAME_DECODED_INFO;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "%s bitstreamid: %llu instid: %u frame_index: %u time: %llu\n",
+ __func__, div64_u64(vf->timestamp, 1000000000),
+ vf->decoder_instid, vf->frame_index,
+ ktime_get_real_ns());
+
+ msg.data.frame_info.bitstreamid = div64_u64(vf->timestamp, 1000000000);
+ msg.data.frame_info.decoder_instid = vf->decoder_instid;
+ msg.data.frame_info.frame_index = vf->frame_index;
+ msg.data.frame_info.time = ktime_get_real_ns();
+ msg.data.frame_info.drop = 0;
+
+ } else if (type == MEDIA_VIDEO_ERROR_EVENT) {
+ msg.message_type = MEDIA_VIDEO_ERROR_EVENT;
+ msg.data.error_info.error_event = MEDIA_ERRORCODES_VDEC_M_BAD_INPUT;
+ }
+
notify_msg_to_mediaproxy(ctx->k_producer_session, 1, &msg);
}
#endif
@@ -1039,7 +1059,7 @@
vb2_buf->timestamp = vf->timestamp;
dstbuf->vb.flags |= vf->frame_type;
#ifdef CONFIG_AMLOGIC_MEDIA_PROXY
- aml_vdec_notify_msg_to_mediaproxy(ctx, MEDIA_VIDEO_METRICS_FRAME_DECODED_INFO, vf);
+ aml_vdec_notify_msg_to_mediaproxy(ctx, MEDIA_VIDEO_METRICS_FRAME_DECODED_INFO, vf, 0);
#endif
if ((ctx->picinfo.field == V4L2_FIELD_INTERLACED) && (!ctx->vpp_is_need)) {
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index a215f80..62478d3 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -26,6 +26,7 @@
#include <media/videobuf2-v4l2.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/media_proxy/AmlVideoUserdata.h>
+#include <linux/amlogic/media/media_proxy/AmlMediaErrorCodes.h>
//#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
#include "aml_vcodec_util.h"
#include "aml_task_chain.h"
@@ -265,7 +266,7 @@
#ifdef CONFIG_AMLOGIC_MEDIA_PROXY
void aml_vdec_notify_msg_to_mediaproxy(struct aml_vcodec_ctx *ctx, int type,
- struct vframe_s *vf);
+ struct vframe_s *vf, int event);
#endif
#endif /* _AML_VCODEC_DEC_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec_infoserver.c b/drivers/amvdec_ports/aml_vcodec_dec_infoserver.c
index 8e63990..c83fdfd 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_infoserver.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_infoserver.c
@@ -23,6 +23,8 @@
#include "aml_vcodec_adapt.h"
#include "./decoder/utils.h"
#include "../frame_provider/decoder/utils/vdec.h"
+#include "aml_vcodec_adapt.h"
+#include "vdec_drv_if.h"
#ifndef MAX
#define MAX(a, b) ({ \
@@ -407,6 +409,11 @@
static int vcodec_get_data_stream(struct aml_vcodec_ctx *ctx,
struct vdec_common_s *data)
{
+ int status = 0;
+
+ vdec_if_get_param(ctx, GET_PARAM_DECODER_STATUS, &status);
+ ctx->dec_intf.dec_stream.decode_status = status;
+
memcpy(&data->u.stream_info, &ctx->dec_intf.dec_stream,
sizeof(struct dec_stream_info_s));
data->u.stream_info.info_type = AML_STREAM_TYPE;
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index d4d66cd..9e0301f 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -186,6 +186,7 @@
enum E_ASPECT_RATIO eu_aspect_ratio; /* aspect ratio (4:3 or 16:9) */
struct aspect_ratio_size ratio_size; /* sar width/height, dar width/height */
__u32 frame_dur;
+ __u32 decode_status;
char reserved[60];
};
diff --git a/drivers/amvdec_ports/decoder/vdec_av1_if.c b/drivers/amvdec_ports/decoder/vdec_av1_if.c
index 4facd47..4abbd7f 100644
--- a/drivers/amvdec_ports/decoder/vdec_av1_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_av1_if.c
@@ -1132,6 +1132,7 @@
{
int ret = 0;
struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
if (!inst) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
@@ -1178,6 +1179,13 @@
get_param_comp_buf_info(inst, out);
break;
+ case GET_PARAM_DECODER_STATUS:
+ {
+ int *mode = out;
+ *mode = vdec_get_decoder_buffer_status(vdec);
+ break;
+ }
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index c64cffa..3129ef2 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -959,6 +959,7 @@
{
int ret = 0;
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
if (!inst) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
@@ -1004,6 +1005,14 @@
*mode = vdec_get_dec_mode(w, h, m);
break;
}
+ case GET_PARAM_DECODER_STATUS:
+ {
+ int *mode = out;
+
+ *mode = vdec_get_decoder_buffer_status(vdec);
+
+ break;
+ }
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
index d2a9503..4f0379a 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -558,6 +558,7 @@
{
int ret = 0;
struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
if (!inst) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
@@ -603,6 +604,12 @@
case GET_PARAM_CFG_INFO:
get_cfg_info(inst, out);
break;
+ case GET_PARAM_DECODER_STATUS:
+ {
+ int *mode = out;
+ *mode = vdec_get_decoder_buffer_status(vdec);
+ break;
+ }
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index 0f30899..9d18e20 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -779,6 +779,7 @@
{
int ret = 0;
struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
if (!inst) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
@@ -821,6 +822,13 @@
get_param_comp_buf_info(inst, out);
break;
+ case GET_PARAM_DECODER_STATUS:
+ {
+ int *mode = out;
+ *mode = vdec_get_decoder_buffer_status(vdec);
+ break;
+ }
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h
index ea08aa9..c7acb10 100644
--- a/drivers/amvdec_ports/vdec_drv_if.h
+++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -84,7 +84,8 @@
GET_PARAM_COMP_BUF_INFO,
GET_PARAM_CFG_INFO,
GET_PARAM_TW_MODE,
- GET_PARAM_TIME_STAMP
+ GET_PARAM_TIME_STAMP,
+ GET_PARAM_DECODER_STATUS
};
/*
diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
index 7241a9b..212d0d3 100644
--- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
+++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
@@ -23,7 +23,6 @@
#include <linux/printk.h>
#include <linux/version.h>
-
int vdec_v4l_get_pic_info(struct aml_vcodec_ctx *ctx,
struct vdec_pic_info *pic)
{
@@ -268,7 +267,6 @@
}
EXPORT_SYMBOL(vdec_v4l_get_tw_mode);
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
void v4l2_m2m_job_pause(struct v4l2_m2m_dev *m2m_dev,
struct v4l2_m2m_ctx *m2m_ctx)
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c b/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c
index c5b5b0b..7652a8d 100644
--- a/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c
@@ -1217,9 +1217,10 @@
return RES_RET_ABNORMAL;
base_csd_valid = is_base_csd_valid(hw, param4);
- if (!base_csd_valid)
+ if (!base_csd_valid) {
+ vdec_v4l_post_error_event(hw->v4l2_ctx, DECODER_EMERGENCY_UNSUPPORT);
return RES_RET_ABNORMAL;
-
+ }
curr_info.frame_width = mb_width << 4;
curr_info.frame_height = mb_height << 4;
over_size = is_oversize(curr_info.frame_width, curr_info.frame_height);
@@ -3500,6 +3501,7 @@
if (frame->data_flag & ERROR_FLAG ||
frame->data_flag & NODISP_FLAG) {
vf->frame_type |= V4L2_BUF_FLAG_ERROR;
+ vdec_v4l_post_error_frame_event(hw->v4l2_ctx);
}
if ((hw->crop_bottom != 0) || (hw->crop_right != 0) ||
diff --git a/drivers/frame_provider/decoder_v4l/h265/vh265.c b/drivers/frame_provider/decoder_v4l/h265/vh265.c
index 669c584..9cc6c92 100644
--- a/drivers/frame_provider/decoder_v4l/h265/vh265.c
+++ b/drivers/frame_provider/decoder_v4l/h265/vh265.c
@@ -10013,6 +10013,7 @@
if ((pic->error_mark) && (hevc->PB_skip_mode != 0)) {
vf->frame_type |= V4L2_BUF_FLAG_ERROR;
+ vdec_v4l_post_error_frame_event(hevc->v4l2_ctx);
}
vf->v4l_mem_handle = hevc->m_BUF[pic->index].v4l_ref_buf_addr;
@@ -13629,9 +13630,8 @@
else
ret = 0;
- if (ret < 0) {
+ if (ret < 0)
vdec_v4l_post_error_event(ctx, DECODER_EMERGENCY_NO_MEM);
- }
return ret;
}
@@ -15468,7 +15468,6 @@
vh265_work_implement(hevc, vdec, 1);
}
-
static int vh265_hw_ctx_restore(struct hevc_state_s *hevc)
{
/* new to do ... */
diff --git a/drivers/frame_provider/decoder_v4l/h265_fb/vh265_fb_v4l.c b/drivers/frame_provider/decoder_v4l/h265_fb/vh265_fb_v4l.c
index 98c3ee9..b9f5187 100644
--- a/drivers/frame_provider/decoder_v4l/h265_fb/vh265_fb_v4l.c
+++ b/drivers/frame_provider/decoder_v4l/h265_fb/vh265_fb_v4l.c
@@ -18708,6 +18708,7 @@
if (init_mmu_buffers(hevc, 1) < 0) {
hevc_print(hevc, 0, "\n 265 mmu init failed!\n");
+ vdec_v4l_post_error_event(ctx, DECODER_EMERGENCY_NO_MEM);
mutex_unlock(&vh265_mutex);
if (hevc)
vfree((void *)hevc);
@@ -18720,6 +18721,7 @@
DRIVER_NAME, &hevc->buf_start);
if (ret < 0) {
uninit_mmu_buffers(hevc);
+ vdec_v4l_post_error_event(ctx, DECODER_EMERGENCY_NO_MEM);
/* devm_kfree(&pdev->dev, (void *)hevc); */
if (hevc)
vfree((void *)hevc);
diff --git a/drivers/frame_provider/decoder_v4l/vav1_fb/vav1_fb_v4l.c b/drivers/frame_provider/decoder_v4l/vav1_fb/vav1_fb_v4l.c
index 2d6d496..5349307 100644
--- a/drivers/frame_provider/decoder_v4l/vav1_fb/vav1_fb_v4l.c
+++ b/drivers/frame_provider/decoder_v4l/vav1_fb/vav1_fb_v4l.c
@@ -13003,6 +13003,7 @@
hw->cma_alloc_count * PAGE_SIZE, DRIVER_NAME,
&hw->cma_alloc_addr);
if (ret < 0) {
+ vdec_v4l_post_error_event(ctx, DECODER_EMERGENCY_NO_MEM);
pdata->dec_status = NULL;
ret = -ENOMEM;
goto multi_probe_failed2;