author | apollo.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) |
commit | cc41710a669925611987cf923431128c04bc5f9c (patch) | |
tree | 148c3f069ba380fdc6d359701b0aa963f292eed2 | |
parent | 0fbadf023b5f11c49b07a1723fdc5253ce9e7c3b (diff) | |
download | media_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>
-rw-r--r-- | drivers/frame_provider/decoder/avs2/avs2_global.h | 3 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/avs2/vavs2.c | 73 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/avs_multi/avs_multi.c | 28 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264/vh264.c | 36 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/h264_dpb.c | 5 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/h264_dpb.h | 2 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/vmh264.c | 33 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h265/vh265.c | 148 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c | 167 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c | 18 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec.c | 250 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec.h | 11 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/vp9/vvp9.c | 77 | ||||
-rw-r--r-- | drivers/stream_input/amports/amstream.c | 71 |
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: |