summaryrefslogtreecommitdiff
authorapollo.ling <apollo.ling@amlogic.com>2019-09-29 06:57:18 (GMT)
committer Hui Zhang <hui.zhang@amlogic.com>2020-01-20 10:50:35 (GMT)
commitcc41710a669925611987cf923431128c04bc5f9c (patch)
tree148c3f069ba380fdc6d359701b0aa963f292eed2
parent0fbadf023b5f11c49b07a1723fdc5253ce9e7c3b (diff)
downloadmedia_modules-cc41710a669925611987cf923431128c04bc5f9c.zip
media_modules-cc41710a669925611987cf923431128c04bc5f9c.tar.gz
media_modules-cc41710a669925611987cf923431128c04bc5f9c.tar.bz2
vdec: add struct for getting multi-vdec information modules part [1/4]
PD#SWPL-1449 Problem: need to implement a way to get multi-vdec information Solution: add new data struct to dynamically record each VDEC's information Verify: u212 Change-Id: I03cf0ff013e64b865dbd83cce85ff7abc43b15a4 Signed-off-by: apollo.ling <apollo.ling@amlogic.com>
Diffstat
-rw-r--r--drivers/frame_provider/decoder/avs2/avs2_global.h3
-rw-r--r--drivers/frame_provider/decoder/avs2/vavs2.c73
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avs_multi.c28
-rw-r--r--drivers/frame_provider/decoder/h264/vh264.c36
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.c5
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.h2
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c33
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c148
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c167
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c18
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c250
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.h11
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c77
-rw-r--r--drivers/stream_input/amports/amstream.c71
14 files changed, 671 insertions, 251 deletions
diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h
index e6c28cf..3e7fcb8 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_global.h
+++ b/drivers/frame_provider/decoder/avs2/avs2_global.h
@@ -811,6 +811,9 @@ struct avs2_frame_s {
int max_mv;
int min_mv;
int avg_mv;
+
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode
};
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c
index f90fee6..4b88db3 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.c
+++ b/drivers/frame_provider/decoder/avs2/vavs2.c
@@ -4258,7 +4258,10 @@ static void fill_frame_info(struct AVS2Decoder_s *dec,
/*
#define SHOW_QOS_INFO
*/
- vframe_qos->size = framesize;
+ if (input_frame_based(hw_to_vdec(dec)))
+ vframe_qos->size = pic->frame_size;
+ else
+ vframe_qos->size = framesize;
vframe_qos->pts = pts;
#ifdef SHOW_QOS_INFO
avs2_print(dec, 0, "slice:%d\n", pic->slice_type);
@@ -4297,8 +4300,6 @@ static void fill_frame_info(struct AVS2Decoder_s *dec,
vframe_qos->num++;
- if (dec->frameinfo_enable)
- vdec_fill_frame_info(vframe_qos, 1);
}
static void set_vframe(struct AVS2Decoder_s *dec,
@@ -4306,7 +4307,7 @@ static void set_vframe(struct AVS2Decoder_s *dec,
{
unsigned long flags;
int stream_offset;
- unsigned int frame_size;
+ unsigned int frame_size = 0;
int pts_discontinue;
stream_offset = pic->stream_offset;
avs2_print(dec, AVS2_DBG_BUFMGR,
@@ -4534,6 +4535,22 @@ static void set_vframe(struct AVS2Decoder_s *dec,
dec->vf_pre_count++;
}
+static inline void dec_update_gvs(struct AVS2Decoder_s *dec)
+{
+ if (dec->gvs->frame_height != dec->frame_height) {
+ dec->gvs->frame_width = dec->frame_width;
+ dec->gvs->frame_height = dec->frame_height;
+ }
+ if (dec->gvs->frame_dur != dec->frame_dur) {
+ dec->gvs->frame_dur = dec->frame_dur;
+ if (dec->frame_dur != 0)
+ dec->gvs->frame_rate = 96000 / dec->frame_dur;
+ else
+ dec->gvs->frame_rate = -1;
+ }
+ dec->gvs->status = dec->stat | dec->fatal_error;
+}
+
static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
{
@@ -4541,6 +4558,7 @@ static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
struct vframe_s *vf = NULL;
/*unsigned short slice_type;*/
struct avs2_frame_s *pic;
+ struct vdec_s *pvdec = hw_to_vdec(dec);
while (1) {
pic = get_disp_pic(dec);
if (pic == NULL)
@@ -4575,17 +4593,20 @@ static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
}
if (vf) {
+ int stream_offset = pic->stream_offset;
set_vframe(dec, vf, pic, 0);
- decoder_do_frame_check(hw_to_vdec(dec), vf);
+ decoder_do_frame_check(pvdec, vf);
kfifo_put(&dec->display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
- #ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+ dec_update_gvs(dec);
/*count info*/
- gvs->frame_dur = dec->frame_dur;
- vdec_count_info(gvs, 0, stream_offset);
- #endif
- hw_to_vdec(dec)->vdec_fps_detec(hw_to_vdec(dec)->id);
+ vdec_count_info(dec->gvs, 0, stream_offset);
+ dec->gvs->bit_rate = bit_depth_luma;
+ dec->gvs->frame_data = bit_depth_chroma;
+ dec->gvs->samp_cnt = get_double_write_mode(dec);
+ vdec_fill_vdec_frame(pvdec, &dec->vframe_qos, dec->gvs, vf, pic->hw_decode_time);
+ pvdec->vdec_fps_detec(pvdec->id);
if (without_display_mode == 0) {
vf_notify_receiver(dec->provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -4774,12 +4795,18 @@ we can call this function to get qos info*/
static void get_picture_qos_info(struct AVS2Decoder_s *dec)
{
struct avs2_frame_s *picture = dec->avs2_dec.hc.cur_pic;
+ struct vdec_s *vdec = hw_to_vdec(dec);
if (!picture) {
avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
"%s decode picture is none exist\n");
return;
}
+ if (vdec->mvfrm) {
+ picture->frame_size = vdec->mvfrm->frame_size;
+ picture->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+ }
/*
#define DEBUG_QOS
@@ -6111,19 +6138,17 @@ int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
vstatus->error_count = 0;
vstatus->status = dec->stat | dec->fatal_error;
vstatus->frame_dur = dec->frame_dur;
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- vstatus->bit_rate = gvs->bit_rate;
- vstatus->frame_data = gvs->frame_data;
- vstatus->total_data = gvs->total_data;
- vstatus->frame_count = gvs->frame_count;
- vstatus->error_frame_count = gvs->error_frame_count;
- vstatus->drop_frame_count = gvs->drop_frame_count;
- vstatus->total_data = gvs->total_data;
- vstatus->samp_cnt = gvs->samp_cnt;
- vstatus->offset = gvs->offset;
+ vstatus->bit_rate = dec->gvs->bit_rate;
+ vstatus->frame_data = dec->gvs->frame_data;
+ vstatus->total_data = dec->gvs->total_data;
+ vstatus->frame_count = dec->gvs->frame_count;
+ vstatus->error_frame_count = dec->gvs->error_frame_count;
+ vstatus->drop_frame_count = dec->gvs->drop_frame_count;
+ vstatus->total_data = dec->gvs->total_data;
+ vstatus->samp_cnt = dec->gvs->samp_cnt;
+ vstatus->offset = dec->gvs->offset;
snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
"%s", DRIVER_NAME);
-#endif
return 0;
}
@@ -6292,6 +6317,8 @@ static s32 vavs2_init(struct vdec_s *vdec)
if (vavs2_local_init(dec) < 0)
return -EBUSY;
+ vdec_set_vframe_comm(vdec, DRIVER_NAME);
+
fw = vmalloc(sizeof(struct firmware_s) + fw_size);
if (IS_ERR_OR_NULL(fw))
return -ENOMEM;
@@ -7055,6 +7082,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
r = dec->chunk->size +
(dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = dec->chunk->size;
}
WRITE_VREG(HEVC_DECODE_SIZE, r);
@@ -7072,6 +7101,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
mod_timer(&dec->timer, jiffies);
dec->stat |= STAT_TIMER_ARM;
dec->stat |= STAT_ISR_REG;
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
amhevc_start();
dec->stat |= STAT_VDEC_RUN;
}
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
index ada05c5..f717244 100644
--- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
@@ -906,6 +906,27 @@ static u8 UserDataHandler(struct vdec_avs_hw_s *hw)
}
#endif
+
+static inline void avs_update_gvs(struct vdec_avs_hw_s *hw)
+{
+ if (hw->gvs->frame_height != hw->frame_height) {
+ hw->gvs->frame_width = hw->frame_width;
+ hw->gvs->frame_height = hw->frame_height;
+ }
+ if (hw->gvs->frame_dur != hw->frame_dur) {
+ hw->gvs->frame_dur = hw->frame_dur;
+ if (hw->frame_dur != 0)
+ hw->gvs->frame_rate = 96000 / hw->frame_dur;
+ else
+ hw->gvs->frame_rate = -1;
+ }
+
+ hw->gvs->status = hw->stat;
+ hw->gvs->error_count = READ_VREG(AV_SCRATCH_C);
+ hw->gvs->drop_frame_count = hw->drop_frame_count;
+
+}
+
#ifdef HANDLE_AVS_IRQ
static irqreturn_t vavs_isr(int irq, void *dev_id)
#else
@@ -913,7 +934,7 @@ static void vavs_isr(void)
#endif
{
u32 reg;
- struct vframe_s *vf;
+ struct vframe_s *vf = NULL;
u32 dur;
u32 repeat_count;
u32 picture_type;
@@ -1369,8 +1390,9 @@ static void vavs_isr(void)
}
/*count info*/
- hw->gvs->frame_dur = hw->frame_dur;
vdec_count_info(hw->gvs, 0, offset);
+ avs_update_gvs(hw);
+ vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0);
/* pr_info("PicType = %d, PTS = 0x%x\n",
* picture_type, vf->pts);
@@ -3930,6 +3952,8 @@ static void vmavs_dump_state(struct vdec_s *vdec)
vdec_set_prepare_level(pdata, start_decode_buf_level);
+ vdec_set_vframe_comm(pdata, DRIVER_NAME);
+
if (pdata->parallel_dec == 1)
vdec_core_request(pdata, CORE_MASK_VDEC_1);
else {
diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c
index a6acc03..dc774b9 100644
--- a/drivers/frame_provider/decoder/h264/vh264.c
+++ b/drivers/frame_provider/decoder/h264/vh264.c
@@ -2570,6 +2570,36 @@ static inline bool vh264_isr_parser(struct vframe_s *vf,
}
return true;
}
+
+static inline void h264_update_gvs(void)
+{
+ u32 ratio_control;
+ u32 ar;
+
+ if (gvs->frame_height != frame_height) {
+ gvs->frame_width = frame_width;
+ gvs->frame_height = frame_height;
+ }
+ if (gvs->frame_dur != frame_dur) {
+ gvs->frame_dur = frame_dur;
+ if (frame_dur != 0)
+ gvs->frame_rate = 96000 / frame_dur;
+ else
+ gvs->frame_rate = -1;
+ }
+ gvs->error_count = READ_VREG(AV_SCRATCH_D);
+ gvs->status = stat;
+ if (fatal_error_reset)
+ gvs->status |= fatal_error_flag;
+ ar = min_t(u32,
+ h264_ar,
+ DISP_RATIO_ASPECT_RATIO_MAX);
+ ratio_control =
+ ar << DISP_RATIO_ASPECT_RATIO_BIT;
+ gvs->ratio_control = ratio_control;
+}
+
+
#ifdef HANDLE_H264_IRQ
static irqreturn_t vh264_isr(int irq, void *dev_id)
#else
@@ -2875,7 +2905,7 @@ static void vh264_isr(void)
frame_count++;
s_vframe_qos.num = frame_count;
- vdec_fill_frame_info(&s_vframe_qos, 1);
+ //vdec_fill_frame_info(&s_vframe_qos, 1);
/* on second IDR frame,check the diff between pts
* compute from duration and pts from lookup ,
@@ -3011,8 +3041,9 @@ static void vh264_isr(void)
*/
/*count info*/
- gvs->frame_dur = frame_dur;
+ h264_update_gvs();
vdec_count_info(gvs, error, b_offset);
+ vdec_fill_vdec_frame(vdec_h264, &s_vframe_qos, gvs, vf, 0);
if ((pts_valid) && (check_pts_discontinue)
&& (!error)) {
@@ -4325,6 +4356,7 @@ static int amvdec_h264_probe(struct platform_device *pdev)
atomic_set(&vh264_active, 1);
mutex_unlock(&vh264_mutex);
+ vdec_set_vframe_comm(pdata, DRIVER_NAME);
return 0;
}
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
index a408b0e..314b240 100644
--- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
+++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
@@ -1612,6 +1612,7 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
struct StorablePicture *p,
unsigned char data_flag)
{
+ struct vdec_frames_s *mvfrm = p_H264_Dpb->vdec->mvfrm;
struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
/* InputParameters *p_Inp = p_Vid->p_Inp;
* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
@@ -1761,6 +1762,10 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
//fs->pts64 = p->pts64;
}
fs->timestamp = p->timestamp;
+ if (mvfrm) {
+ fs->frame_size2 = mvfrm->frame_size;
+ fs->hw_decode_time = mvfrm->hw_decode_time;
+ }
}
void reset_frame_store(struct h264_dpb_stru *p_H264_Dpb,
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
index e9a7489..5c7645f 100644
--- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
+++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
@@ -809,6 +809,8 @@ struct FrameStore {
int min_mv;
int avg_mv;
int dpb_frame_count;
+ u32 hw_decode_time;
+ u32 frame_size2; // For recording the chunk->size in frame mode
};
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
index 0426bd9..4dd8bf1 100644
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -2538,6 +2538,7 @@ static int check_force_interlace(struct vdec_h264_hw_s *hw,
static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
{
struct vframe_qos_s *vframe_qos = &hw->vframe_qos;
+
if (frame->slice_type == I_SLICE)
vframe_qos->type = 1;
else if (frame->slice_type == P_SLICE)
@@ -2545,7 +2546,10 @@ static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
else if (frame->slice_type == B_SLICE)
vframe_qos->type = 3;
- vframe_qos->size = frame->frame_size;
+ if (input_frame_based(hw_to_vdec(hw)))
+ vframe_qos->size = frame->frame_size2;
+ else
+ vframe_qos->size = frame->frame_size;
vframe_qos->pts = frame->pts64;
vframe_qos->max_mv = frame->max_mv;
@@ -2578,8 +2582,6 @@ static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
vframe_qos->min_skip);
*/
vframe_qos->num++;
- if (hw->frameinfo_enable)
- vdec_fill_frame_info(vframe_qos, 1);
}
static int is_iframe(struct FrameStore *frame) {
@@ -2866,8 +2868,16 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
vf->duration = vf->duration/2;
}
- if (i == 0)
- decoder_do_frame_check(hw_to_vdec(hw), vf);
+ if (i == 0) {
+ struct vdec_s *pvdec;
+ struct vdec_info vs;
+
+ pvdec = hw_to_vdec(hw);
+ memset(&vs, 0, sizeof(struct vdec_info));
+ pvdec->dec_status(pvdec, &vs);
+ decoder_do_frame_check(pvdec, vf);
+ vdec_fill_vdec_frame(pvdec, &hw->vframe_qos, &vs, vf, frame->hw_decode_time);
+ }
/*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/
vf->sar_width = hw->width_aspect_ratio;
@@ -5514,6 +5524,10 @@ static int vh264_pic_done_proc(struct vdec_s *vdec)
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int ret;
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+
if (input_frame_based(vdec) &&
(!(hw->i_only & 0x2)) &&
frmbase_cont_bitlevel != 0 &&
@@ -6818,8 +6832,10 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
vstatus->frame_width = hw->frame_width;
vstatus->frame_height = hw->frame_height;
- if (hw->frame_dur != 0)
+ if (hw->frame_dur != 0) {
+ vstatus->frame_dur = hw->frame_dur;
vstatus->frame_rate = 96000 / hw->frame_dur;
+ }
else
vstatus->frame_rate = -1;
vstatus->error_count = 0;
@@ -8724,6 +8740,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
WRITE_VREG(H264_DECODE_INFO, (1<<13));
WRITE_VREG(H264_DECODE_SIZE, decode_size);
WRITE_VREG(VIFF_BIT_CNT, decode_size * 8);
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = hw->chunk->size;
} else {
if (size <= 0)
size = 0x7fffffff; /*error happen*/
@@ -8757,6 +8775,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
else
CLEAR_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3);
}
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
amvdec_start();
if (hw->mmu_enable /*&& !hw->frame_busy && !hw->frame_done*/) {
WRITE_VREG(HEVC_ASSIST_SCRATCH_0, 0x0);
@@ -9338,6 +9358,7 @@ static int ammvdec_h264_probe(struct platform_device *pdev)
| CORE_MASK_COMBINE);
atomic_set(&hw->vh264_active, 1);
+ vdec_set_vframe_comm(pdata, DRIVER_NAME);
return 0;
}
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c
index eeb893e..0721437 100644
--- a/drivers/frame_provider/decoder/h265/vh265.c
+++ b/drivers/frame_provider/decoder/h265/vh265.c
@@ -537,7 +537,7 @@ static DEFINE_MUTEX(vh265_mutex);
static DEFINE_MUTEX(vh265_log_mutex);
-static struct vdec_info *gvs;
+//static struct vdec_info *gvs;
static u32 without_display_mode;
@@ -1403,6 +1403,8 @@ struct PIC_s {
int min_mv;
int avg_mv;
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode
bool vframe_bound;
} /*PIC_t */;
@@ -1736,6 +1738,7 @@ struct hevc_state_s {
void *v4l2_ctx;
bool v4l_params_parsed;
u32 mem_map_mode;
+ struct vdec_info *gvs;
} /*hevc_stru_t */;
#ifdef AGAIN_HAS_THRESHOLD
@@ -6066,6 +6069,8 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc,
pic = get_pic_by_POC(hevc, decoded_poc);
if (pic && (pic->POC != INVALID_POC)) {
+ struct vdec_s *vdec = hw_to_vdec(hevc);
+
/*PB skip control */
if (pic->error_mark == 0
&& hevc->PB_skip_mode == 1) {
@@ -6114,6 +6119,10 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc,
pic->output_mark = 1;
pic->recon_mark = 1;
pic->dis_mark = 1;
+ if (vdec->mvfrm) {
+ pic->frame_size = vdec->mvfrm->frame_size;
+ pic->hw_decode_time = (u32)vdec->mvfrm->hw_decode_time;
+ }
}
do {
pic_display = output_pic(hevc, 0);
@@ -7299,11 +7308,9 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
if (hevc->cur_pic->error_mark
&& ((hevc->ignore_bufmgr_error & 0x1) == 0)) {
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
/*count info*/
- vdec_count_info(gvs, hevc->cur_pic->error_mark,
+ vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark,
hevc->cur_pic->stream_offset);
-#endif
}
if (is_skip_decoding(hevc,
@@ -7331,11 +7338,9 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
hevc_print(hevc, 0,
"Discard this picture index %d\n",
hevc->cur_pic->index);
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
/*count info*/
- vdec_count_info(gvs, hevc->cur_pic->error_mark,
+ vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark,
hevc->cur_pic->stream_offset);
-#endif
return 2;
}
#ifdef MCRCC_ENABLE
@@ -7471,8 +7476,10 @@ static void hevc_local_uninit(struct hevc_state_s *hevc)
hevc->frame_mmu_map_addr = NULL;
}
- kfree(gvs);
- gvs = NULL;
+ //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs);
+ if (hevc->gvs)
+ kfree(hevc->gvs);
+ hevc->gvs = NULL;
}
static int hevc_local_init(struct hevc_state_s *hevc)
@@ -8517,7 +8524,10 @@ static void fill_frame_info(struct hevc_state_s *hevc,
/*
#define SHOW_QOS_INFO
*/
- vframe_qos->size = framesize;
+ if (input_frame_based(hw_to_vdec(hevc)))
+ vframe_qos->size = pic->frame_size;
+ else
+ vframe_qos->size = framesize;
vframe_qos->pts = pts;
#ifdef SHOW_QOS_INFO
hevc_print(hevc, 0, "slice:%d, poc:%d\n", pic->slice_type, pic->POC);
@@ -8556,19 +8566,33 @@ static void fill_frame_info(struct hevc_state_s *hevc,
vframe_qos->num++;
- if (hevc->frameinfo_enable)
- vdec_fill_frame_info(vframe_qos, 1);
+}
+
+static inline void hevc_update_gvs(struct hevc_state_s *hevc)
+{
+ if (hevc->gvs->frame_height != hevc->frame_height) {
+ hevc->gvs->frame_width = hevc->frame_width;
+ hevc->gvs->frame_height = hevc->frame_height;
+ }
+ if (hevc->gvs->frame_dur != hevc->frame_dur) {
+ hevc->gvs->frame_dur = hevc->frame_dur;
+ if (hevc->frame_dur != 0)
+ hevc->gvs->frame_rate = 96000 / hevc->frame_dur;
+ else
+ hevc->gvs->frame_rate = -1;
+ }
+ hevc->gvs->status = hevc->stat | hevc->fatal_error;
+ if (hevc->gvs->ratio_control != hevc->ratio_control)
+ hevc->gvs->ratio_control = hevc->ratio_control;
}
static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
struct vdec_s *vdec = hw_to_vdec(hevc);
-#endif
struct vframe_s *vf = NULL;
int stream_offset = pic->stream_offset;
unsigned short slice_type = pic->slice_type;
- u32 frame_size;
+ u32 frame_size = 0;
if (force_disp_pic_index & 0x100) {
/*recycle directly*/
@@ -8598,7 +8622,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
}
#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec_frame_based(hw_to_vdec(hevc))) {
+ if (vdec_frame_based(vdec)) {
vf->pts = pic->pts;
vf->pts_us64 = pic->pts64;
vf->timestamp = pic->timestamp;
@@ -8905,7 +8929,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
| VIDTYPE_VIU_NV21;
}
hevc->vf_pre_count++;
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
+ decoder_do_frame_check(vdec, vf);
kfifo_put(&hevc->display_q,
(const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -8954,7 +8978,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
| VIDTYPE_VIU_NV21;
}
hevc->vf_pre_count++;
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
+ decoder_do_frame_check(vdec, vf);
kfifo_put(&hevc->display_q,
(const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -8980,7 +9004,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
process_pending_vframe(hevc,
pic, (pic->pic_struct == 9));
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
+ decoder_do_frame_check(vdec, vf);
/* process current vf */
kfifo_put(&hevc->pending_q,
(const struct vframe_s *)vf);
@@ -9029,7 +9053,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD;
vf->index = (pic->index << 8) | 0xff;
}
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
+ decoder_do_frame_check(vdec, vf);
kfifo_put(&hevc->pending_q,
(const struct vframe_s *)vf);
if (hevc->vf_pre_count == 0)
@@ -9074,7 +9098,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
break;
}
hevc->vf_pre_count++;
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
+ decoder_do_frame_check(vdec, vf);
kfifo_put(&hevc->display_q,
(const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -9083,7 +9107,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
vf->type_original = vf->type;
pic->vf_ref = 1;
hevc->vf_pre_count++;
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
+ decoder_do_frame_check(vdec, vf);
kfifo_put(&hevc->display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -9096,11 +9120,14 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
vf->pts, vf->pts_us64,
vf->duration);
#endif
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
/*count info*/
- vdec_count_info(gvs, 0, stream_offset);
-#endif
- hw_to_vdec(hevc)->vdec_fps_detec(hw_to_vdec(hevc)->id);
+ vdec_count_info(hevc->gvs, 0, stream_offset);
+ hevc_update_gvs(hevc);
+ hevc->gvs->bit_rate = hevc->bit_depth_luma;
+ hevc->gvs->frame_data = hevc->bit_depth_chroma;
+ hevc->gvs->samp_cnt = get_double_write_mode(hevc);
+ vdec_fill_vdec_frame(vdec, &hevc->vframe_qos, hevc->gvs, vf, pic->hw_decode_time);
+ vdec->vdec_fps_detec(vdec->id);
if (without_display_mode == 0) {
vf_notify_receiver(hevc->provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -9662,6 +9689,10 @@ static irqreturn_t vh265_isr_thread_fn(int irq, void *data)
struct PIC_s *pic;
struct PIC_s *pic_display;
int decoded_poc;
+
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
#ifdef DETREFILL_ENABLE
if (hevc->is_swap &&
get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
@@ -9757,6 +9788,12 @@ pic_done:
pic->output_mark = 1;
pic->recon_mark = 1;
+ if (vdec->mvfrm) {
+ pic->frame_size =
+ vdec->mvfrm->frame_size;
+ pic->hw_decode_time =
+ (u32)vdec->mvfrm->hw_decode_time;
+ }
}
check_pic_decoded_error(hevc,
READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff);
@@ -10236,9 +10273,7 @@ force_output:
&hevc->notify_work);
hevc->get_frame_dur = true;
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- gvs->frame_dur = hevc->frame_dur;
-#endif
+ //hevc->gvs->frame_dur = hevc->frame_dur;
}
if (hevc->video_signal_type !=
@@ -10379,9 +10414,7 @@ force_output:
#endif
} else {
/* skip, search next start code */
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- gvs->drop_frame_count++;
-#endif
+ hevc->gvs->drop_frame_count++;
WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2));
hevc->skip_flag = 1;
WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
@@ -10832,23 +10865,21 @@ int vh265_dec_status(struct vdec_info *vstatus)
vstatus->frame_rate = -1;
vstatus->error_count = 0;
vstatus->status = hevc->stat | hevc->fatal_error;
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- vstatus->bit_rate = gvs->bit_rate;
+ vstatus->bit_rate = hevc->gvs->bit_rate;
vstatus->frame_dur = hevc->frame_dur;
- if (gvs) {
- vstatus->bit_rate = gvs->bit_rate;
- vstatus->frame_data = gvs->frame_data;
- vstatus->total_data = gvs->total_data;
- vstatus->frame_count = gvs->frame_count;
- vstatus->error_frame_count = gvs->error_frame_count;
- vstatus->drop_frame_count = gvs->drop_frame_count;
- vstatus->total_data = gvs->total_data;
- vstatus->samp_cnt = gvs->samp_cnt;
- vstatus->offset = gvs->offset;
+ if (hevc->gvs) {
+ vstatus->bit_rate = hevc->gvs->bit_rate;
+ vstatus->frame_data = hevc->gvs->frame_data;
+ vstatus->total_data = hevc->gvs->total_data;
+ vstatus->frame_count = hevc->gvs->frame_count;
+ vstatus->error_frame_count = hevc->gvs->error_frame_count;
+ vstatus->drop_frame_count = hevc->gvs->drop_frame_count;
+ vstatus->samp_cnt = hevc->gvs->samp_cnt;
+ vstatus->offset = hevc->gvs->offset;
}
+
snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
"%s", DRIVER_NAME);
-#endif
vstatus->ratio_control = hevc->ratio_control;
return 0;
}
@@ -10859,13 +10890,15 @@ int vh265_set_isreset(struct vdec_s *vdec, int isreset)
return 0;
}
-static int vh265_vdec_info_init(void)
+static int vh265_vdec_info_init(struct hevc_state_s *hevc)
{
- gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
- if (NULL == gvs) {
+ hevc->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
+ //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs);
+ if (NULL == hevc->gvs) {
pr_info("the struct of vdec status malloc failed.\n");
return -ENOMEM;
}
+ vdec_set_vframe_comm(hw_to_vdec(hevc), DRIVER_NAME);
return 0;
}
@@ -11050,9 +11083,7 @@ static int vh265_local_init(struct hevc_state_s *hevc)
hevc->frame_dur =
(hevc->vh265_amstream_dec_info.rate ==
0) ? 3600 : hevc->vh265_amstream_dec_info.rate;
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- gvs->frame_dur = hevc->frame_dur;
-#endif
+ //hevc->gvs->frame_dur = hevc->frame_dur;
if (hevc->frame_width && hevc->frame_height)
hevc->frame_ar = hevc->frame_height * 0x100 / hevc->frame_width;
@@ -11427,8 +11458,10 @@ static int vh265_stop(struct hevc_state_s *hevc)
uninit_mmu_buffers(hevc);
amhevc_disable();
- kfree(gvs);
- gvs = NULL;
+ //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs);
+ if (hevc->gvs)
+ kfree(hevc->gvs);
+ hevc->gvs = NULL;
return 0;
}
@@ -12435,6 +12468,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
r = hevc->chunk->size +
(hevc->chunk->offset & (VDEC_FIFO_ALIGN - 1));
hevc->decode_size = r;
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = hevc->chunk->size;
}
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
else {
@@ -12456,6 +12491,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
mod_timer(&hevc->timer, jiffies);
hevc->stat |= STAT_TIMER_ARM;
hevc->stat |= STAT_ISR_REG;
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
amhevc_start();
hevc->stat |= STAT_VDEC_RUN;
}
@@ -12646,7 +12683,7 @@ static int amvdec_h265_probe(struct platform_device *pdev)
workaround_enable &= ~3;
#endif
hevc->cma_dev = pdata->cma_dev;
- vh265_vdec_info_init();
+ vh265_vdec_info_init(hevc);
#ifdef MULTI_INSTANCE_SUPPORT
pdata->private = hevc;
@@ -12901,6 +12938,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
int config_val;
#endif
+ //pr_err("[%s pid=%d tgid=%d] \n",__func__, current->pid, current->tgid);
if (pdata == NULL) {
pr_info("\nammvdec_h265 memory resource undefined.\n");
return -EFAULT;
@@ -13101,6 +13139,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
hevc->double_write_mode);
hevc->cma_dev = pdata->cma_dev;
+ vh265_vdec_info_init(hevc);
if (vh265_init(pdata) < 0) {
hevc_print(hevc, 0,
@@ -13138,6 +13177,7 @@ static int ammvdec_h265_remove(struct platform_device *pdev)
if (hevc == NULL)
return 0;
+ //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
if (get_dbg_flag(hevc))
hevc_print(hevc, 0, "%s\r\n", __func__);
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
index 64e81c7..3898122 100644
--- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
+++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
@@ -203,6 +203,8 @@ struct pic_info_t {
u64 pts64;
bool pts_valid;
ulong v4l_ref_buf_addr;
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode
};
struct vdec_mpeg12_hw_s {
@@ -307,11 +309,12 @@ struct vdec_mpeg12_hw_s {
bool v4l_params_parsed;
u32 buf_num;
u32 dynamic_buf_num_margin;
+ struct vdec_info gvs;
+ struct vframe_qos_s vframe_qos;
};
static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw);
static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw);
static void reset_process_time(struct vdec_mpeg12_hw_s *hw);
-static struct vdec_info gvs;
static int debug_enable;
/*static struct work_struct userdata_push_work;*/
#undef pr_info
@@ -512,6 +515,99 @@ static u32 spec_to_index(struct vdec_mpeg12_hw_s *hw, u32 spec)
return hw->buf_num;
}
+/* +[SE][BUG-145343][huanghang] fixed:mpeg2 frame qos info notify */
+static void fill_frame_info(struct vdec_mpeg12_hw_s *hw, u32 slice_type,
+ int frame_size, u32 pts)
+{
+ unsigned char a[3];
+ unsigned char i, j, t;
+ unsigned long data;
+ struct vframe_qos_s *vframe_qos = &hw->vframe_qos;
+
+ vframe_qos->type = ((slice_type & PICINFO_TYPE_MASK) ==
+ PICINFO_TYPE_I) ? 1 :
+ ((slice_type &
+ PICINFO_TYPE_MASK) ==
+ PICINFO_TYPE_P) ? 2 : 3;
+ vframe_qos->size = frame_size;
+ vframe_qos->pts = pts;
+
+ get_random_bytes(&data, sizeof(unsigned long));
+ if (vframe_qos->type == 1)
+ data = 0;
+ a[0] = data & 0xff;
+ a[1] = (data >> 8) & 0xff;
+ a[2] = (data >> 16) & 0xff;
+
+ for (i = 0; i < 3; i++) {
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ }
+ vframe_qos->max_mv = a[2];
+ vframe_qos->avg_mv = a[1];
+ vframe_qos->min_mv = a[0];
+
+ get_random_bytes(&data, sizeof(unsigned long));
+ a[0] = data & 0x1f;
+ a[1] = (data >> 8) & 0x3f;
+ a[2] = (data >> 16) & 0x7f;
+
+ for (i = 0; i < 3; i++) {
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ }
+ vframe_qos->max_qp = a[2];
+ vframe_qos->avg_qp = a[1];
+ vframe_qos->min_qp = a[0];
+
+ get_random_bytes(&data, sizeof(unsigned long));
+ a[0] = data & 0x1f;
+ a[1] = (data >> 8) & 0x3f;
+ a[2] = (data >> 16) & 0x7f;
+
+ for (i = 0; i < 3; i++) {
+ for (j = i + 1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ }
+ vframe_qos->max_skip = a[2];
+ vframe_qos->avg_skip = a[1];
+ vframe_qos->min_skip = a[0];
+
+ vframe_qos->num++;
+
+ return;
+}
+
static void set_frame_info(struct vdec_mpeg12_hw_s *hw, struct vframe_s *vf)
{
u32 ar_bits;
@@ -1351,6 +1447,28 @@ void userdata_pushed_drop(struct vdec_mpeg12_hw_s *hw)
}
+static inline void hw_update_gvs(struct vdec_mpeg12_hw_s *hw)
+{
+ if (hw->gvs.frame_height != hw->frame_height) {
+ hw->gvs.frame_width = hw->frame_width;
+ hw->gvs.frame_height = hw->frame_height;
+ }
+ if (hw->gvs.frame_dur != hw->frame_dur) {
+ hw->gvs.frame_dur = hw->frame_dur;
+ if (hw->frame_dur != 0)
+ hw->gvs.frame_rate = 96000 / hw->frame_dur;
+ else
+ hw->gvs.frame_rate = -1;
+ }
+ if (hw->gvs.ratio_control != hw->ratio_control)
+ hw->gvs.ratio_control = hw->ratio_control;
+
+ hw->gvs.status = hw->stat;
+ hw->gvs.error_count = READ_VREG(AV_SCRATCH_C);
+ hw->gvs.drop_frame_count = hw->drop_frame_count;
+
+}
+
static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw,
struct pic_info_t *pic)
{
@@ -1460,8 +1578,14 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw,
__func__, hw->disp_num, GET_SLICE_TYPE(info), i,
vf->pts, vf->pts_us64, vf->duration, vf->type);
hw->disp_num++;
- if (i == 0)
- decoder_do_frame_check(hw_to_vdec(hw), vf);
+ if (i == 0) {
+ struct vdec_s *vdec = hw_to_vdec(hw);
+
+ decoder_do_frame_check(vdec, vf);
+ hw_update_gvs(hw);
+ vdec_fill_vdec_frame(vdec, &hw->vframe_qos,
+ &hw->gvs, vf, pic->hw_decode_time);
+ }
vdec->vdec_fps_detec(vdec->id);
vf->mem_handle =
decoder_bmmu_box_get_mem_handle(
@@ -1555,7 +1679,7 @@ static bool is_ref_error(struct vdec_mpeg12_hw_s *hw)
static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq)
{
- u32 reg, index, info, seqinfo, offset, pts, frame_size, tmp;
+ u32 reg, index, info, seqinfo, offset, pts, frame_size=0, tmp;
u64 pts_us64 = 0;
struct pic_info_t *new_pic, *disp_pic;
struct vdec_mpeg12_hw_s *hw =
@@ -1624,6 +1748,11 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq)
hw->dec_num++;
hw->dec_result = DEC_RESULT_DONE;
new_pic = &hw->pics[index];
+ if (vdec->mvfrm) {
+ new_pic->frame_size = vdec->mvfrm->frame_size;
+ new_pic->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+ }
tmp = READ_VREG(MREG_PIC_WIDTH);
if ((tmp > 1920) || (tmp == 0)) {
new_pic->width = 1920;
@@ -1734,6 +1863,11 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq)
if (disp_pic->pts_valid)
hw->lastpts64 = disp_pic->pts64;
+ if (input_frame_based(hw_to_vdec(hw)))
+ frame_size = new_pic->frame_size;
+
+ fill_frame_info(hw, info, frame_size, new_pic->pts);
+
if ((hw->first_i_frame_ready == 0) &&
((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) &&
((info & PICINFO_ERROR) == 0))
@@ -1760,7 +1894,7 @@ static irqreturn_t vmpeg12_isr(struct vdec_s *vdec, int irq)
info = READ_VREG(MREG_PIC_INFO);
offset = READ_VREG(MREG_FRAME_OFFSET);
- vdec_count_info(&gvs, info & PICINFO_ERROR, offset);
+ vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset);
WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
@@ -2047,16 +2181,16 @@ static int vmmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
vstatus->frame_rate = -1;
vstatus->error_count = READ_VREG(AV_SCRATCH_C);
vstatus->status = hw->stat;
- vstatus->bit_rate = gvs.bit_rate;
+ vstatus->bit_rate = hw->gvs.bit_rate;
vstatus->frame_dur = hw->frame_dur;
- vstatus->frame_data = gvs.frame_data;
- vstatus->total_data = gvs.total_data;
- vstatus->frame_count = gvs.frame_count;
- vstatus->error_frame_count = gvs.error_frame_count;
+ vstatus->frame_data = hw->gvs.frame_data;
+ vstatus->total_data = hw->gvs.total_data;
+ vstatus->frame_count = hw->gvs.frame_count;
+ vstatus->error_frame_count = hw->gvs.error_frame_count;
vstatus->drop_frame_count = hw->drop_frame_count;
- vstatus->total_data = gvs.total_data;
- vstatus->samp_cnt = gvs.samp_cnt;
- vstatus->offset = gvs.offset;
+ vstatus->total_data = hw->gvs.total_data;
+ vstatus->samp_cnt = hw->gvs.samp_cnt;
+ vstatus->offset = hw->gvs.offset;
vstatus->ratio_control = hw->ratio_control;
snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
"%s", DRIVER_NAME);
@@ -2752,6 +2886,8 @@ void (*callback)(struct vdec_s *, void *),
READ_PARSER_REG(PARSER_VIDEO_WP),
size);
+ if (vdec->mvfrm && hw->chunk)
+ vdec->mvfrm->frame_size = hw->chunk->size;
hw->input_empty = 0;
vdec_enable_input(vdec);
@@ -2786,6 +2922,8 @@ void (*callback)(struct vdec_s *, void *),
hw->stat |= STAT_MC_LOAD;
hw->last_vld_level = 0;
start_process_time(hw);
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
amvdec_start();
hw->stat |= STAT_VDEC_RUN;
hw->init_flag = 1;
@@ -2891,6 +3029,8 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev)
}
vdec_set_prepare_level(pdata, start_decode_buf_level);
+ vdec_set_vframe_comm(pdata, DRIVER_NAME);
+
if (pdata->parallel_dec == 1)
vdec_core_request(pdata, CORE_MASK_VDEC_1);
else {
@@ -2979,7 +3119,6 @@ static int ammvdec_mpeg12_remove(struct platform_device *pdev)
hw = NULL;
}
pr_info("ammvdec_mpeg12 removed.\n");
- memset(&gvs, 0x0, sizeof(gvs));
return 0;
}
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
index c098a5e..92cea0e 100644
--- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
+++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
@@ -200,6 +200,8 @@ struct pic_info_t {
u32 duration;
u32 repeat_cnt;
ulong v4l_ref_buf_addr;
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode;
};
struct vdec_mpeg4_hw_s {
@@ -774,6 +776,8 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
kfifo_put(&hw->newframe_q,
(const struct vframe_s *)vf);
} else {
+ struct vdec_info vinfo;
+
vf->mem_handle =
decoder_bmmu_box_get_mem_handle(
hw->mm_blk_handle, index);
@@ -784,6 +788,9 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
decoder_do_frame_check(vdec, vf);
hw->frame_num++;
+ vdec->dec_status(vdec, &vinfo);
+ vdec_fill_vdec_frame(vdec, NULL,
+ &vinfo, vf, pic->hw_decode_time);
if (without_display_mode == 0) {
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -949,6 +956,11 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq)
}
hw->dec_result = DEC_RESULT_DONE;
dec_pic = &hw->pic[index];
+ if (vdec->mvfrm) {
+ dec_pic->frame_size = vdec->mvfrm->frame_size;
+ dec_pic->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+ }
dec_pic->pts_valid = false;
dec_pic->pts = 0;
dec_pic->pts64 = 0;
@@ -2205,6 +2217,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
size = hw->chunk_size +
(hw->chunk_offset & (VDEC_FIFO_ALIGN - 1));
WRITE_VREG(VIFF_BIT_CNT, size * 8);
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = hw->chunk->size;
}
hw->input_empty = 0;
hw->last_vld_level = 0;
@@ -2213,6 +2227,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
/* wmb before ISR is handled */
wmb();
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
amvdec_start();
hw->stat |= STAT_VDEC_RUN;
hw->init_flag = 1;
@@ -2348,6 +2364,8 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev)
}
vdec_set_prepare_level(pdata, start_decode_buf_level);
+ vdec_set_vframe_comm(pdata, DRIVER_NAME);
+
if (pdata->parallel_dec == 1)
vdec_core_request(pdata, CORE_MASK_VDEC_1);
else {
diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c
index 644797a..07e039b 100644
--- a/drivers/frame_provider/decoder/utils/vdec.c
+++ b/drivers/frame_provider/decoder/utils/vdec.c
@@ -121,10 +121,8 @@ static int max_di_instance = 2;
//static int path_debug = 0;
-static struct vframe_qos_s *frame_info_buf_in = NULL;
-static struct vframe_qos_s *frame_info_buf_out = NULL;
-static int frame_qos_wr = 0;
-static int frame_qos_rd = 0;
+static int enable_mvdec_info = 1;
+
int decode_underflow = 0;
#define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1)
@@ -1060,6 +1058,12 @@ struct vdec_s *vdec_create(struct stream_port_s *port,
master->slave = vdec;
master->sched = 1;
}
+ if (enable_mvdec_info) {
+ vdec->mvfrm = (struct vdec_frames_s *)
+ vzalloc(sizeof(struct vdec_frames_s));
+ if (!vdec->mvfrm)
+ pr_err("vzalloc: vdec_frames_s failed\n");
+ }
}
pr_debug("vdec_create instance %p, total %d\n", vdec,
@@ -2049,6 +2053,8 @@ int vdec_destroy(struct vdec_s *vdec)
vdec_profile_flush(vdec);
#endif
ida_simple_remove(&vdec_core->ida, vdec->id);
+ if (vdec->mvfrm)
+ vfree(vdec->mvfrm);
vfree(vdec);
atomic_dec(&vdec_core->vdec_nr);
@@ -2068,6 +2074,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k)
const char *dev_name;
int id = PLATFORM_DEVID_AUTO;/*if have used my self*/
+ //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
dev_name = get_dev_name(vdec_single(vdec), vdec->format);
if (dev_name == NULL)
@@ -2364,25 +2371,6 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k)
vdec->sys_info->height);
/* vdec is now ready to be active */
vdec_set_status(vdec, VDEC_STATUS_DISCONNECTED);
- if (p->use_vfm_path) {
- frame_info_buf_in = (struct vframe_qos_s *)
- kmalloc(QOS_FRAME_NUM*sizeof(struct vframe_qos_s), GFP_KERNEL);
- if (!frame_info_buf_in)
- pr_err("kmalloc: frame_info_buf_in failed\n");
- else
- memset(frame_info_buf_in, 0,
- QOS_FRAME_NUM*sizeof(struct vframe_qos_s));
-
- frame_info_buf_out = (struct vframe_qos_s *)
- kmalloc(QOS_FRAME_NUM*sizeof(struct vframe_qos_s), GFP_KERNEL);
- if (!frame_info_buf_out)
- pr_err("kmalloc: frame_info_buf_out failed\n");
- else
- memset(frame_info_buf_out, 0,
- QOS_FRAME_NUM*sizeof(struct vframe_qos_s));
- frame_qos_wr = 0;
- frame_qos_rd = 0;
- }
return 0;
error:
@@ -2445,14 +2433,6 @@ void vdec_release(struct vdec_s *vdec)
platform_device_unregister(vdec->dev);
pr_debug("vdec_release instance %p, total %d\n", vdec,
atomic_read(&vdec_core->vdec_nr));
- if (vdec->use_vfm_path) {
- kfree(frame_info_buf_in);
- frame_info_buf_in = NULL;
- kfree(frame_info_buf_out);
- frame_info_buf_out = NULL;
- frame_qos_wr = 0;
- frame_qos_rd = 0;
- }
vdec_destroy(vdec);
mutex_lock(&vdec_mutex);
@@ -2750,7 +2730,7 @@ static irqreturn_t vdec_thread_isr(int irq, void *dev_id)
vdec->tfn_ns = local_clock();
isr2tfn = vdec->tfn_ns - vdec->isr_ns;
if (isr2tfn > 10000000)
- pr_err("!!!!!!! %s vdec_isr to %s took %uns !!!\n",
+ pr_err("!!!!!!! %s vdec_isr to %s took %u ns !!!\n",
vdec->vf_provider_name, __func__, isr2tfn);
}
if (c->dev_threaded_isr) {
@@ -4225,6 +4205,28 @@ static ssize_t clock_level_show(struct class *class,
return ret;
}
+static ssize_t enable_mvdec_info_show(struct class *cla,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", enable_mvdec_info);
+}
+
+static ssize_t enable_mvdec_info_store(struct class *cla,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int r;
+ int val;
+
+ r = kstrtoint(buf, 0, &val);
+ if (r < 0)
+ return -EINVAL;
+ enable_mvdec_info = val;
+
+ return count;
+}
+
+
static ssize_t store_poweron_clock_level(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
@@ -4273,6 +4275,7 @@ static ssize_t show_keep_vdec_mem(struct class *class,
return sprintf(buf, "%d\n", keep_vdec_mem);
}
+
#ifdef VDEC_DEBUG_SUPPORT
static ssize_t store_debug(struct class *class,
struct class_attribute *attr,
@@ -4878,6 +4881,8 @@ static struct class_attribute vdec_class_attrs[] = {
__ATTR_RO(amrisc_regs),
__ATTR_RO(dump_trace),
__ATTR_RO(clock_level),
+ __ATTR(enable_mvdec_info, S_IRUGO | S_IWUSR | S_IWGRP,
+ enable_mvdec_info_show, enable_mvdec_info_store),
__ATTR(poweron_clock_level, S_IRUGO | S_IWUSR | S_IWGRP,
show_poweron_clock_level, store_poweron_clock_level),
__ATTR(dump_risc_mem, S_IRUGO | S_IWUSR | S_IWGRP,
@@ -5105,104 +5110,109 @@ static int __init vdec_mem_setup(struct reserved_mem *rmem)
return 0;
}
-void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug)
+
+void vdec_set_vframe_comm(struct vdec_s *vdec, char *n)
{
- if (frame_info_buf_in == NULL) {
- pr_info("error,frame_info_buf_in is null\n");
- return;
- }
- if (frame_info_buf_out == NULL) {
- pr_info("error,frame_info_buf_out is null\n");
- return;
- }
- if (frame_qos_wr >= QOS_FRAME_NUM)
- frame_qos_wr = 0;
+ struct vdec_frames_s *mvfrm = vdec->mvfrm;
- if (frame_qos_wr >= QOS_FRAME_NUM ||
- frame_qos_wr < 0) {
- pr_info("error,index :%d is error\n", frame_qos_wr);
+ if (!mvfrm)
return;
- }
- if (frameinfo_flag == DISABLE_FRAME_INFO)
+
+ mvfrm->comm.vdec_id = vdec->id;
+
+ snprintf(mvfrm->comm.vdec_name, sizeof(mvfrm->comm.vdec_name)-1,
+ "%s", n);
+ mvfrm->comm.vdec_type = vdec->type;
+}
+EXPORT_SYMBOL(vdec_set_vframe_comm);
+
+void vdec_fill_vdec_frame(struct vdec_s *vdec, struct vframe_qos_s *vframe_qos,
+ struct vdec_info *vinfo,struct vframe_s *vf,
+ u32 hw_dec_time)
+{
+ u32 i;
+ struct vframe_counter_s *fifo_buf;
+ struct vdec_frames_s *mvfrm = vdec->mvfrm;
+
+ if (!mvfrm)
return;
+ fifo_buf = mvfrm->fifo_buf;
+
+ /* assume fps==60,mv->wr max value can support system running 828 days,
+ this is enough for us */
+ i = mvfrm->wr & (NUM_FRAME_VDEC-1); //find the slot num in fifo_buf
+ mvfrm->fifo_buf[i].decode_time_cost = hw_dec_time;
+ if (vframe_qos)
+ memcpy(&fifo_buf[i].qos, vframe_qos, sizeof(struct vframe_qos_s));
+ if (vinfo) {
+ memcpy(&fifo_buf[i].frame_width, &vinfo->frame_width,
+ ((char*)&vinfo->reserved[0] - (char*)&vinfo->frame_width));
+ }
+ if (vf) {
+ fifo_buf[i].vf_type = vf->type;
+ fifo_buf[i].signal_type = vf->signal_type;
+ fifo_buf[i].pts = vf->pts;
+ fifo_buf[i].pts_us64 = vf->pts_us64;
+ }
+ mvfrm->wr++;
+}
+EXPORT_SYMBOL(vdec_fill_vdec_frame);
+
+/* In this function,if we use copy_to_user, we may encounter sleep,
+which may block the vdec_fill_vdec_frame,this is not acceptable.
+So, we should use a tmp buffer(passed by caller) to get the content */
+u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf)
+{
+ u32 toread = 0;
+ u32 slot_rd;
+ struct vframe_counter_s *fifo_buf = NULL;
+ struct vdec_frames_s *mvfrm = NULL;
- if (frameinfo_flag == PRINT_FRAME_INFO) {
- pr_info("num %d size %d pts %d\n",
- vframe_qos->num,
- vframe_qos->size,
- vframe_qos->pts);
- pr_info("mv min_mv %d avg_mv %d max_mv %d\n",
- vframe_qos->min_mv,
- vframe_qos->avg_mv,
- vframe_qos->max_mv);
- pr_info("qp min_qp %d avg_qp %d max_qp %d\n",
- vframe_qos->min_qp,
- vframe_qos->avg_qp,
- vframe_qos->max_qp);
- pr_info("skip min_skip %d avg_skip %d max_skip %d\n",
- vframe_qos->min_skip,
- vframe_qos->avg_skip,
- vframe_qos->max_skip);
- }
- memcpy(&frame_info_buf_in[frame_qos_wr++],
- vframe_qos, sizeof(struct vframe_qos_s));
- if (frame_qos_wr >= QOS_FRAME_NUM)
- frame_qos_wr = 0;
-
- /*pr_info("frame_qos_wr:%d\n", frame_qos_wr);*/
-
-}
-EXPORT_SYMBOL(vdec_fill_frame_info);
-
-struct vframe_qos_s *vdec_get_qos_info(void)
-{
- int write_count = 0;
- int qos_wr = frame_qos_wr;
-
- if (frame_info_buf_in == NULL) {
- pr_info("error,frame_info_buf_in is null\n");
- return NULL;
- }
- if (frame_info_buf_out == NULL) {
- pr_info("error,frame_info_buf_out is null\n");
- return NULL;
+ /*
+ switch (version) {
+ case version_1:
+ f1();
+ case version_2:
+ f2();
+ default:
+ break;
}
+ */
+
+ if (!vdec)
+ return 0;
+ mvfrm = vdec->mvfrm;
+ if (!mvfrm)
+ return 0;
+ fifo_buf = &mvfrm->fifo_buf[0];
- memset(frame_info_buf_out, 0,
- QOS_FRAME_NUM*sizeof(struct vframe_qos_s));
- if (frame_qos_rd > qos_wr) {
- write_count = QOS_FRAME_NUM - frame_qos_rd;
- if (write_count > 0 && write_count <= QOS_FRAME_NUM) {
- memcpy(frame_info_buf_out, &frame_info_buf_in[0],
- write_count*sizeof(struct vframe_qos_s));
- if ((write_count + qos_wr) <= QOS_FRAME_NUM)
- memcpy(&frame_info_buf_out[write_count], frame_info_buf_in,
- qos_wr*sizeof(struct vframe_qos_s));
- else
- pr_info("get_qos_info:%d,out of range\n", __LINE__);
- } else
- pr_info("get_qos_info:%d,out of range\n", __LINE__);
- } else if (frame_qos_rd < qos_wr) {
- write_count = qos_wr - frame_qos_rd;
- if (write_count > 0 && write_count < QOS_FRAME_NUM)
- memcpy(frame_info_buf_out, &frame_info_buf_in[frame_qos_rd],
- (write_count)*sizeof(struct vframe_qos_s));
- else
- pr_info("get_qos_info:%d, out of range\n", __LINE__);
+ toread = mvfrm->wr - mvfrm->rd;
+ if (toread) {
+ if (toread >= NUM_FRAME_VDEC - QOS_FRAME_NUM) {
+ /* round the fifo_buf length happens, give QOS_FRAME_NUM for buffer */
+ mvfrm->rd = mvfrm->wr - (NUM_FRAME_VDEC - QOS_FRAME_NUM);
+ }
+
+ if (toread >= QOS_FRAME_NUM) {
+ toread = QOS_FRAME_NUM; //by default, we use this num
+ }
+
+ slot_rd = mvfrm->rd &( NUM_FRAME_VDEC-1); //In this case it equals to x%y
+ if (slot_rd + toread <= NUM_FRAME_VDEC) {
+ memcpy(tmpbuf, &fifo_buf[slot_rd], toread*sizeof(struct vframe_counter_s));
+ } else {
+ u32 exeed;
+ exeed = slot_rd + toread - NUM_FRAME_VDEC;
+ memcpy(tmpbuf, &fifo_buf[slot_rd], (NUM_FRAME_VDEC - slot_rd)*sizeof(struct vframe_counter_s));
+ memcpy(&tmpbuf[NUM_FRAME_VDEC-slot_rd], &fifo_buf[0], exeed*sizeof(struct vframe_counter_s));
+ }
+
+ mvfrm->rd += toread;
}
- /*
- pr_info("cnt:%d,size:%d,num:%d,rd:%d,wr:%d\n",
- wirte_count,
- frame_info_buf_out[0].size,
- frame_info_buf_out[0].num,
- frame_qos_rd,qos_wr);
- */
- frame_qos_rd = qos_wr;
- return frame_info_buf_out;
+ return toread;
}
-EXPORT_SYMBOL(vdec_get_qos_info);
-
+EXPORT_SYMBOL(vdec_get_frame_vdec);
RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup);
/*
diff --git a/drivers/frame_provider/decoder/utils/vdec.h b/drivers/frame_provider/decoder/utils/vdec.h
index 92a2244..06b565d 100644
--- a/drivers/frame_provider/decoder/utils/vdec.h
+++ b/drivers/frame_provider/decoder/utils/vdec.h
@@ -121,7 +121,13 @@ extern void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
unsigned int get_vdec_clk_config_settings(void);
void update_vdec_clk_config_settings(unsigned int config);
//unsigned int get_mmu_mode(void);//DEBUG_TMP
-extern void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug);
+//extern void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug);
+extern void vdec_fill_vdec_frame(struct vdec_s *vdec,
+ struct vframe_qos_s *vframe_qos,
+ struct vdec_info *vinfo,
+ struct vframe_s *vf, u32 hw_dec_time);
+extern void vdec_set_vframe_comm(struct vdec_s *vdec, char *n);
+
struct vdec_s;
enum vformat_t;
@@ -265,6 +271,7 @@ struct vdec_s {
int parallel_dec;
volatile u64 isr_ns;
volatile u64 tfn_ns;
+ struct vdec_frames_s *mvfrm;
};
/* common decoder vframe provider name to use default vfm path */
@@ -448,7 +455,7 @@ int vdec_get_status(struct vdec_s *vdec);
void vdec_set_timestamp(struct vdec_s *vdec, u64 timestamp);
-extern struct vframe_qos_s *vdec_get_qos_info(void);
+extern u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf);
int vdec_get_frame_num(struct vdec_s *vdec);
diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c
index 1089c75..bd1e51a 100644
--- a/drivers/frame_provider/decoder/vp9/vvp9.c
+++ b/drivers/frame_provider/decoder/vp9/vvp9.c
@@ -582,6 +582,8 @@ struct PIC_BUFFER_CONFIG_s {
int min_mv;
int avg_mv;
+ u32 hw_decode_time;
+ u32 frame_size2; // For frame base mode
bool vframe_bound;
} PIC_BUFFER_CONFIG;
@@ -7007,16 +7009,33 @@ static void update_vf_memhandle(struct VP9Decoder_s *pbi,
}
}
+static inline void pbi_update_gvs(struct VP9Decoder_s *pbi)
+{
+ if (pbi->gvs->frame_height != frame_height) {
+ pbi->gvs->frame_width = frame_width;
+ pbi->gvs->frame_height = frame_height;
+ }
+ if (pbi->gvs->frame_dur != pbi->frame_dur) {
+ pbi->gvs->frame_dur = pbi->frame_dur;
+ if (pbi->frame_dur != 0)
+ pbi->gvs->frame_rate = 96000 / pbi->frame_dur;
+ else
+ pbi->gvs->frame_rate = -1;
+ }
+ pbi->gvs->status = pbi->stat | pbi->fatal_error;
+}
+
static int prepare_display_buf(struct VP9Decoder_s *pbi,
struct PIC_BUFFER_CONFIG_s *pic_config)
{
struct vframe_s *vf = NULL;
+ struct vdec_s *pvdec = hw_to_vdec(pbi);
int stream_offset = pic_config->stream_offset;
unsigned short slice_type = pic_config->slice_type;
u32 pts_valid = 0, pts_us64_valid = 0;
u32 pts_save;
u64 pts_us64_save;
- u32 frame_size;
+ u32 frame_size = 0;
if (debug & VP9_DEBUG_BUFMGR)
pr_info("%s index = %d\r\n", __func__, pic_config->index);
@@ -7042,7 +7061,7 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi,
}
#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec_frame_based(hw_to_vdec(pbi))) {
+ if (vdec_frame_based(pvdec)) {
vf->pts = pic_config->pts;
vf->pts_us64 = pic_config->pts64;
vf->timestamp = pic_config->timestamp;
@@ -7260,16 +7279,19 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi,
&& (debug & VP9_DEBUG_NO_TRIGGER_FRAME) == 0
&& (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX))) {
inc_vf_ref(pbi, pic_config->index);
- decoder_do_frame_check(hw_to_vdec(pbi), vf);
+ decoder_do_frame_check(pvdec, vf);
kfifo_put(&pbi->display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
pbi->vf_pre_count++;
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+ pbi_update_gvs(pbi);
/*count info*/
- gvs->frame_dur = pbi->frame_dur;
- vdec_count_info(gvs, 0, stream_offset);
-#endif
- hw_to_vdec(pbi)->vdec_fps_detec(hw_to_vdec(pbi)->id);
+ vdec_count_info(pbi->gvs, 0, stream_offset);
+ pbi->gvs->bit_rate = bit_depth_luma;
+ pbi->gvs->frame_data = bit_depth_chroma;
+ pbi->gvs->samp_cnt = get_double_write_mode(pbi);
+ vdec_fill_vdec_frame(pvdec, &pbi->vframe_qos, pbi->gvs,
+ vf, pic_config->hw_decode_time);
+ pvdec->vdec_fps_detec(pvdec->id);
if (without_display_mode == 0) {
vf_notify_receiver(pbi->provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -7665,7 +7687,10 @@ static void fill_frame_info(struct VP9Decoder_s *pbi,
/*
#define SHOW_QOS_INFO
*/
- vframe_qos->size = framesize;
+ if (input_frame_based(hw_to_vdec(pbi)))
+ vframe_qos->size = frame->frame_size2;
+ else
+ vframe_qos->size = framesize;
vframe_qos->pts = pts;
#ifdef SHOW_QOS_INFO
vp9_print(pbi, 0, "slice:%d\n", frame->slice_type);
@@ -7698,9 +7723,6 @@ static void fill_frame_info(struct VP9Decoder_s *pbi,
vframe_qos->min_skip);
#endif
vframe_qos->num++;
-
- if (pbi->frameinfo_enable)
- vdec_fill_frame_info(vframe_qos, 1);
}
/* only when we decoded one field or one frame,
@@ -7708,9 +7730,15 @@ we can call this function to get qos info*/
static void get_picture_qos_info(struct VP9Decoder_s *pbi)
{
struct PIC_BUFFER_CONFIG_s *frame = &pbi->cur_buf->buf;
+ struct vdec_s *vdec = hw_to_vdec(pbi);
if (!frame)
return;
+ if (vdec->mvfrm) {
+ frame->frame_size2 = vdec->mvfrm->frame_size;
+ frame->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+ }
if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
unsigned char a[3];
@@ -8755,19 +8783,17 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
vstatus->error_count = 0;
vstatus->status = vp9->stat | vp9->fatal_error;
vstatus->frame_dur = vp9->frame_dur;
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- vstatus->bit_rate = gvs->bit_rate;
- vstatus->frame_data = gvs->frame_data;
- vstatus->total_data = gvs->total_data;
- vstatus->frame_count = gvs->frame_count;
- vstatus->error_frame_count = gvs->error_frame_count;
- vstatus->drop_frame_count = gvs->drop_frame_count;
- vstatus->total_data = gvs->total_data;
- vstatus->samp_cnt = gvs->samp_cnt;
- vstatus->offset = gvs->offset;
+ vstatus->bit_rate = vp9->gvs->bit_rate;
+ vstatus->frame_data = vp9->gvs->frame_data;
+ vstatus->total_data = vp9->gvs->total_data;
+ vstatus->frame_count = vp9->gvs->frame_count;
+ vstatus->error_frame_count = vp9->gvs->error_frame_count;
+ vstatus->drop_frame_count = vp9->gvs->drop_frame_count;
+ vstatus->total_data = vp9->gvs->total_data;
+ vstatus->samp_cnt = vp9->gvs->samp_cnt;
+ vstatus->offset = vp9->gvs->offset;
snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
"%s", DRIVER_NAME);
-#endif
return 0;
}
@@ -8935,6 +8961,7 @@ static int vvp9_local_init(struct VP9Decoder_s *pbi)
pr_info("the struct of vdec status malloc failed.\n");
return -1;
}
+ vdec_set_vframe_comm(hw_to_vdec(pbi), DRIVER_NAME);
#ifdef DEBUG_PTS
pbi->pts_missed = 0;
pbi->pts_hit = 0;
@@ -9965,6 +9992,8 @@ static void run_front(struct vdec_s *vdec)
WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
size = pbi->chunk->size +
(pbi->chunk->offset & (VDEC_FIFO_ALIGN - 1));
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = pbi->chunk->size;
}
WRITE_VREG(HEVC_DECODE_SIZE, size);
WRITE_VREG(HEVC_DECODE_COUNT, pbi->slice_idx);
@@ -10130,6 +10159,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n",
__func__, mask);
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
run_count[pbi->index]++;
pbi->vdec_cb_arg = arg;
pbi->vdec_cb = callback;
diff --git a/drivers/stream_input/amports/amstream.c b/drivers/stream_input/amports/amstream.c
index bc46356..70367da 100644
--- a/drivers/stream_input/amports/amstream.c
+++ b/drivers/stream_input/amports/amstream.c
@@ -1611,6 +1611,8 @@ static int amstream_open(struct inode *inode, struct file *file)
if (iminor(inode) >= amstream_port_num)
return -ENODEV;
+ //pr_err("%s, port name %s\n", __func__, port->name);
+ //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
mutex_lock(&amstream_mutex);
if (port->type & PORT_TYPE_VIDEO) {
@@ -2606,17 +2608,71 @@ static long amstream_do_ioctl_new(struct port_priv_s *priv,
r = -EINVAL;
break;
case AMSTREAM_IOC_GET_QOSINFO:
+ case AMSTREAM_IOC_GET_MVDECINFO:
{
- struct av_param_qosinfo_t __user *uarg = (void *)arg;
- struct vframe_qos_s *qos_info = vdec_get_qos_info();
- if (this->type & PORT_TYPE_VIDEO) {
- if (qos_info != NULL && copy_to_user((void *)uarg->vframe_qos,
- qos_info,
- QOS_FRAME_NUM*sizeof(struct vframe_qos_s))) {
- r = -EFAULT;
+ u32 slots = 0;
+ u32 struct_size = 0;
+ int vdec_id = 0;
+ struct vdec_s *vdec = NULL;
+ struct vframe_counter_s tmpbuf[QOS_FRAME_NUM] = {0};
+ struct av_param_mvdec_t __user *uarg = (void *)arg;
+
+ if (AMSTREAM_IOC_GET_MVDECINFO == cmd) {
+ if (get_user(vdec_id, &uarg->vdec_id) < 0
+ || get_user(struct_size, &uarg->struct_size) < 0) {
+ r = -EFAULT;
+ break;
+ }
+ if (struct_size != sizeof(struct av_param_mvdec_t)) {
+ pr_err("pass in size %u != expected size %u\n",
+ struct_size, sizeof(struct av_param_mvdec_t));
+ pr_err("App using old structue,we will support it.\n");
+ //Here will add the compatibility for old structure when
+ //current struecture be substituded by newer structure.
+ //msleep(1000); let app handle it.
break;
}
}
+ vdec = vdec_get_vdec_by_id(vdec_id);
+ if (!vdec) {
+ r = 0;
+ break;
+ }
+
+ slots = vdec_get_frame_vdec(vdec, tmpbuf);
+ if (AMSTREAM_IOC_GET_MVDECINFO == cmd)
+ put_user(slots, &uarg->slots);
+ if (slots) {
+ if (AMSTREAM_IOC_GET_MVDECINFO == cmd) {
+ if (copy_to_user((void *)&uarg->comm,
+ &vdec->mvfrm->comm,
+ sizeof(struct vframe_comm_s))) {
+ r = -EFAULT;
+ break;
+ }
+ if (copy_to_user((void *)&uarg->minfo[0],
+ tmpbuf,
+ slots*sizeof(struct vframe_counter_s))) {
+ r = -EFAULT;
+ kfree(tmpbuf);
+ break;
+ }
+ }else { //For compatibility, only copy the qos
+ struct av_param_qosinfo_t __user *uarg = (void *)arg;
+ int i;
+ for (i=0; i<slots; i++)
+ if (copy_to_user((void *)&uarg->vframe_qos[i],
+ &tmpbuf[i].qos,
+ sizeof(struct vframe_qos_s))) {
+ r = -EFAULT;
+ break;
+ }
+ }
+ } else {
+ /*Vdec didn't produce item,wait for 10 ms to avoid user application
+ infinitely calling*/
+ //msleep(10); let user app handle it.
+ }
}
break;
default:
@@ -3420,6 +3476,7 @@ static long amstream_do_ioctl(struct port_priv_s *priv,
case AMSTREAM_IOC_SET_PTR:
case AMSTREAM_IOC_SYSINFO:
case AMSTREAM_IOC_GET_QOSINFO:
+ case AMSTREAM_IOC_GET_MVDECINFO:
r = amstream_do_ioctl_new(priv, cmd, arg);
break;
default: