decoder: add TR135 video parameter counter. [1/3]
authorwenlong.yuan <wenlong.yuan@amlogic.com>
Fri, 21 Aug 2020 07:13:12 +0000 (15:13 +0800)
committerHui Zhang <hui.zhang@amlogic.com>
Fri, 28 Aug 2020 13:31:19 +0000 (06:31 -0700)
PD#SWPL-31491

Problem:
need add detail video parameter counter for iptv and ott.

Solution:
add the video parameters for multi decoder,use vdec.c func
vdec_fill_vdec_frame to add video info and use amstream.c
ioctl index AMSTREAM_IOC_GET_MVDECINFO to get the video info.

Verify:
905X2-U212

Change-Id: I0572e0df4d561c47b870b4cec1371b0dad8755cb
Signed-off-by: wenlong.yuan <wenlong.yuan@amlogic.com>
drivers/frame_provider/decoder/avs2/vavs2.c
drivers/frame_provider/decoder/avs_multi/avs_multi.c
drivers/frame_provider/decoder/h264_multi/vmh264.c
drivers/frame_provider/decoder/h265/vh265.c
drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
drivers/frame_provider/decoder/utils/vdec.c
drivers/frame_provider/decoder/utils/vdec.h
drivers/frame_provider/decoder/vp9/vvp9.c
drivers/stream_input/amports/amstream.c

index 50df9896e19444e4aebfd5868d60932521102cf8..5504dd3b9b164ce17d4355dc909529c2f56e9a51 100644 (file)
@@ -4560,7 +4560,8 @@ static inline void dec_update_gvs(struct AVS2Decoder_s *dec)
        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;
+                       dec->gvs->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
+                                       96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
                else
                        dec->gvs->frame_rate = -1;
        }
@@ -4619,6 +4620,15 @@ static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
                        dec_update_gvs(dec);
                        /*count info*/
                        vdec_count_info(dec->gvs, 0, stream_offset);
+               if (stream_offset) {
+                       if (pic->slice_type == I_IMG) {
+                               dec->gvs->i_decoded_frames++;
+                       } else if (pic->slice_type == P_IMG) {
+                               dec->gvs->p_decoded_frames++;
+                       } else if (pic->slice_type == B_IMG) {
+                               dec->gvs->b_decoded_frames++;
+                       }
+               }
                        memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info));
                        tmp4x.bit_depth_luma = bit_depth_luma;
                        tmp4x.bit_depth_chroma = bit_depth_chroma;
@@ -6152,7 +6162,8 @@ int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        vstatus->frame_height = dec->frame_height;
 
        if (dec->frame_dur != 0)
-               vstatus->frame_rate = 96000 / dec->frame_dur;
+               vstatus->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
+                                   96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
        else
                vstatus->frame_rate = -1;
        vstatus->error_count = 0;
@@ -6164,6 +6175,15 @@ int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        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->i_decoded_frames = dec->gvs->i_decoded_frames;
+       vstatus->i_lost_frames =  dec->gvs->i_lost_frames;
+       vstatus->i_concealed_frames =  dec->gvs->i_concealed_frames;
+       vstatus->p_decoded_frames =  dec->gvs->p_decoded_frames;
+       vstatus->p_lost_frames =  dec->gvs->p_lost_frames;
+       vstatus->p_concealed_frames =  dec->gvs->p_concealed_frames;
+       vstatus->b_decoded_frames =  dec->gvs->b_decoded_frames;
+       vstatus->b_lost_frames =  dec->gvs->b_lost_frames;
+       vstatus->b_concealed_frames =  dec->gvs->b_concealed_frames;
        vstatus->total_data = dec->gvs->total_data;
        vstatus->samp_cnt = dec->gvs->samp_cnt;
        vstatus->offset = dec->gvs->offset;
index f395669ec27cd3691af5b2d6ca3649d99fbe7307..1f62c204b4e6b4d8f9de10cd07ea270633663007 100644 (file)
@@ -929,7 +929,8 @@ static inline void avs_update_gvs(struct vdec_avs_hw_s *hw)
        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;
+                       hw->gvs->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
+                                       96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
                else
                        hw->gvs->frame_rate = -1;
        }
@@ -1080,7 +1081,8 @@ static int vavs_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)
-               vstatus->frame_rate = 96000 / hw->frame_dur;
+               vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
+                               96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
        else
                vstatus->frame_rate = -1;
        vstatus->error_count = READ_VREG(AV_SCRATCH_C);
@@ -1092,6 +1094,15 @@ static int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        vstatus->frame_count = hw->gvs->frame_count;
        vstatus->error_frame_count = hw->gvs->error_frame_count;
        vstatus->drop_frame_count = hw->gvs->drop_frame_count;
+       vstatus->i_decoded_frames = hw->gvs->i_decoded_frames;
+       vstatus->i_lost_frames = hw->gvs->i_lost_frames;
+       vstatus->i_concealed_frames = hw->gvs->i_concealed_frames;
+       vstatus->p_decoded_frames = hw->gvs->p_decoded_frames;
+       vstatus->p_lost_frames = hw->gvs->p_lost_frames;
+       vstatus->p_concealed_frames = hw->gvs->p_concealed_frames;
+       vstatus->b_decoded_frames = hw->gvs->b_decoded_frames;
+       vstatus->b_lost_frames = hw->gvs->b_lost_frames;
+       vstatus->b_concealed_frames = hw->gvs->b_concealed_frames;
        vstatus->total_data = hw->gvs->total_data;
        vstatus->samp_cnt = hw->gvs->samp_cnt;
        vstatus->offset = hw->gvs->offset;
@@ -3642,6 +3653,15 @@ static irqreturn_t vmavs_isr_thread_fn(struct vdec_s *vdec, int irq)
        
                        /*count info*/
                        vdec_count_info(hw->gvs, 0, offset);
+                       if (offset) {
+                               if (picture_type == I_PICTURE) {
+                                       hw->gvs->i_decoded_frames++;
+                               } else if (picture_type == P_PICTURE) {
+                                       hw->gvs->p_decoded_frames++;
+                               } else if (picture_type == B_PICTURE) {
+                                       hw->gvs->b_decoded_frames++;
+                               }
+                       }
                        avs_update_gvs(hw);
                        vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0);
        
index 715a0c0cd572661082a4dda597700dda0760f089..58fe8000539fa8a2cb705fe39eaebb1614694c75 100644 (file)
@@ -2797,8 +2797,24 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
 
        if (frame->data_flag & ERROR_FLAG) {
                vdec_count_info(&hw->gvs, 1, 0);
-               if (!hw->send_error_frame_flag)
+               if (frame->slice_type == I_SLICE) {
+                       hw->gvs.i_concealed_frames++;
+               } else if (frame->slice_type == P_SLICE) {
+                       hw->gvs.p_concealed_frames++;
+               } else if (frame->slice_type == B_SLICE) {
+                       hw->gvs.b_concealed_frames++;
+               }
+               if (!hw->send_error_frame_flag) {
                        hw->gvs.drop_frame_count++;
+                       if (frame->slice_type == I_SLICE) {
+                               hw->gvs.i_lost_frames++;
+                       } else if (frame->slice_type == P_SLICE) {
+                               hw->gvs.p_lost_frames++;
+                       } else if (frame->slice_type == B_SLICE) {
+                               hw->gvs.b_lost_frames++;
+                       }
+               }
+
        }
 
        if ((frame->data_flag & NODISP_FLAG) ||
@@ -3009,6 +3025,10 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
                        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);
+
+                       dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
+                       "[%s:%d] i_decoded_frame = %d p_decoded_frame = %d b_decoded_frame = %d\n",
+                       __func__, __LINE__,vs.i_decoded_frames,vs.p_decoded_frames,vs.b_decoded_frames);
                }
 
                /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/
@@ -6491,6 +6511,13 @@ pic_done_proc:
                        hw->get_data_count = 0x7fffffff;
                        WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD);
                        decode_frame_count[DECODE_ID(hw)]++;
+                       if (p_H264_Dpb->mSlice.slice_type == I_SLICE) {
+                               hw->gvs.i_decoded_frames++;
+                       } else if (p_H264_Dpb->mSlice.slice_type == P_SLICE) {
+                               hw->gvs.p_decoded_frames++;
+                       } else if (p_H264_Dpb->mSlice.slice_type == B_SLICE) {
+                               hw->gvs.b_decoded_frames++;
+                       }
                        start_process_time(hw);
                        return IRQ_HANDLED;
                }
@@ -7165,7 +7192,8 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        vstatus->frame_height = hw->frame_height;
        if (hw->frame_dur != 0) {
                vstatus->frame_dur = hw->frame_dur;
-               vstatus->frame_rate = 96000 / hw->frame_dur;
+               vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
+                                   96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
        }
        else
                vstatus->frame_rate = -1;
@@ -7186,6 +7214,15 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        vstatus->error_frame_count = hw->gvs.error_frame_count;
        vstatus->drop_frame_count = hw->gvs.drop_frame_count;
        vstatus->frame_count = decode_frame_count[DECODE_ID(hw)];
+       vstatus->i_decoded_frames = hw->gvs.i_decoded_frames;
+       vstatus->i_lost_frames = hw->gvs.i_lost_frames;
+       vstatus->i_concealed_frames = hw->gvs.i_concealed_frames;
+       vstatus->p_decoded_frames = hw->gvs.p_decoded_frames;
+       vstatus->p_lost_frames = hw->gvs.p_lost_frames;
+       vstatus->p_concealed_frames = hw->gvs.p_concealed_frames;
+       vstatus->b_decoded_frames = hw->gvs.b_decoded_frames;
+       vstatus->b_lost_frames = hw->gvs.b_lost_frames;
+       vstatus->b_concealed_frames = hw->gvs.b_concealed_frames;
        snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
                "%s-%02d", DRIVER_NAME, hw->id);
 
@@ -8801,6 +8838,13 @@ result_done:
                                }
                        }
                decode_frame_count[DECODE_ID(hw)]++;
+               if (hw->dpb.mSlice.slice_type == I_SLICE) {
+                       hw->gvs.i_decoded_frames++;
+               } else if (hw->dpb.mSlice.slice_type == P_SLICE) {
+                       hw->gvs.p_decoded_frames++;
+               } else if (hw->dpb.mSlice.slice_type == B_SLICE) {
+                       hw->gvs.b_decoded_frames++;
+               }
                amvdec_stop();
                if (!vdec_is_support_4k()) {
                        if (clk_adj_frame_count < VDEC_CLOCK_ADJUST_FRAME) {
index 0d5ea48b2cd38d91a60a1fb35929478cbf33daa7..2dfde743adc618982983a845b317c891b8e84808 100644 (file)
@@ -6080,8 +6080,22 @@ static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic)
                                 * the drop count
                                 */
                                hevc->gvs->drop_frame_count++;
+                               if (pic_display->slice_type == I_SLICE) {
+                                       hevc->gvs->i_lost_frames++;
+                               } else if (pic_display->slice_type == P_SLICE) {
+                                       hevc->gvs->p_lost_frames++;
+                               } else if (pic_display->slice_type == B_SLICE) {
+                                       hevc->gvs->b_lost_frames++;
+                               }
                                /* error frame count also need increase */
                                hevc->gvs->error_frame_count++;
+                               if (pic_display->slice_type == I_SLICE) {
+                                       hevc->gvs->i_concealed_frames++;
+                               } else if (pic_display->slice_type == P_SLICE) {
+                                       hevc->gvs->p_concealed_frames++;
+                               } else if (pic_display->slice_type == B_SLICE) {
+                                       hevc->gvs->b_concealed_frames++;
+                               }
                        } else {
                                if (hevc->i_only & 0x1
                                        && pic_display->slice_type != 2) {
@@ -6388,8 +6402,22 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc,
                                         * the drop count
                                         */
                                        hevc->gvs->drop_frame_count++;
+                                       if (pic_display->slice_type == I_SLICE) {
+                                               hevc->gvs->i_lost_frames++;
+                                       }else if (pic_display->slice_type == P_SLICE) {
+                                               hevc->gvs->p_lost_frames++;
+                                       } else if (pic_display->slice_type == B_SLICE) {
+                                               hevc->gvs->b_lost_frames++;
+                                       }
                                        /* error frame count also need increase */
                                        hevc->gvs->error_frame_count++;
+                                       if (pic_display->slice_type == I_SLICE) {
+                                               hevc->gvs->i_concealed_frames++;
+                                       } else if (pic_display->slice_type == P_SLICE) {
+                                               hevc->gvs->p_concealed_frames++;
+                                       } else if (pic_display->slice_type == B_SLICE) {
+                                               hevc->gvs->b_concealed_frames++;
+                                       }
                                } else {
                                        if (hevc->i_only & 0x1
                                                && pic_display->
@@ -7571,9 +7599,33 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
                                /*count info*/
                                vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark,
                                        hevc->cur_pic->stream_offset);
-                               if (hevc->PB_skip_mode == 2)
-                                       hevc->gvs->drop_frame_count++;
+                               if (hevc->cur_pic->slice_type == I_SLICE) {
+                                       hevc->gvs->i_decoded_frames++;
+                               } else if (hevc->cur_pic->slice_type == P_SLICE) {
+                                       hevc->gvs->p_decoded_frames++;
+                               } else if (hevc->cur_pic->slice_type == B_SLICE) {
+                                       hevc->gvs->b_decoded_frames++;
+                               }
+                       if (hevc->cur_pic->error_mark) {
+                               if (hevc->cur_pic->slice_type == I_SLICE) {
+                                       hevc->gvs->i_concealed_frames++;
+                               } else if (hevc->cur_pic->slice_type == P_SLICE) {
+                                       hevc->gvs->p_concealed_frames++;
+                               } else if (hevc->cur_pic->slice_type == B_SLICE) {
+                                       hevc->gvs->b_concealed_frames++;
+                               }
+                       }
+                       if (hevc->PB_skip_mode == 2) {
+                               hevc->gvs->drop_frame_count++;
+                               if (rpm_param->p.slice_type == I_SLICE) {
+                                       hevc->gvs->i_lost_frames++;
+                               } else if (rpm_param->p.slice_type == P_SLICE) {
+                                       hevc->gvs->p_lost_frames++;
+                               } else if (rpm_param->p.slice_type == B_SLICE) {
+                                       hevc->gvs->b_lost_frames++;
+                               }
                        }
+               }
 
                        if (is_skip_decoding(hevc,
                                hevc->cur_pic)) {
@@ -7603,8 +7655,32 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
                /*count info*/
                vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark,
                        hevc->cur_pic->stream_offset);
-               if (hevc->PB_skip_mode == 2)
+               if (hevc->cur_pic->slice_type == I_SLICE) {
+                       hevc->gvs->i_decoded_frames++;
+               } else if (hevc->cur_pic->slice_type == P_SLICE) {
+                       hevc->gvs->p_decoded_frames++;
+               } else if (hevc->cur_pic->slice_type == B_SLICE) {
+                       hevc->gvs->b_decoded_frames++;
+               }
+               if (hevc->cur_pic->error_mark) {
+                       if (hevc->cur_pic->slice_type == I_SLICE) {
+                               hevc->gvs->i_concealed_frames++;
+                       } else if (hevc->cur_pic->slice_type == P_SLICE) {
+                               hevc->gvs->p_concealed_frames++;
+                       } else if (hevc->cur_pic->slice_type == B_SLICE) {
+                               hevc->gvs->b_concealed_frames++;
+                       }
+               }
+               if (hevc->PB_skip_mode == 2) {
                        hevc->gvs->drop_frame_count++;
+                       if (rpm_param->p.slice_type == I_SLICE) {
+                               hevc->gvs->i_lost_frames++;
+                       } else if (rpm_param->p.slice_type == P_SLICE) {
+                               hevc->gvs->p_lost_frames++;
+                       } else if (rpm_param->p.slice_type == B_SLICE) {
+                               hevc->gvs->b_lost_frames++;
+                       }
+               }
                return 2;
        }
 #ifdef MCRCC_ENABLE
@@ -8842,7 +8918,8 @@ static inline void hevc_update_gvs(struct hevc_state_s *hevc)
        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;
+                       hevc->gvs->frame_rate = ((96000 * 10 / hevc->frame_dur) % 10) < 5 ?
+                                       96000 / hevc->frame_dur : (96000 / hevc->frame_dur +1);
                else
                        hevc->gvs->frame_rate = -1;
        }
@@ -9394,6 +9471,13 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
 #endif
                /*count info*/
                vdec_count_info(hevc->gvs, 0, stream_offset);
+               if (hevc->cur_pic->slice_type == I_SLICE) {
+                       hevc->gvs->i_decoded_frames++;
+               } else if (hevc->cur_pic->slice_type == P_SLICE) {
+                       hevc->gvs->p_decoded_frames++;
+               } else if (hevc->cur_pic->slice_type == B_SLICE) {
+                       hevc->gvs->b_decoded_frames++;
+               }
                hevc_update_gvs(hevc);
                memcpy(&tmp4x, hevc->gvs, sizeof(struct vdec_info));
                tmp4x.bit_depth_luma = hevc->bit_depth_luma;
@@ -10853,6 +10937,13 @@ force_output:
        } else {
                /* skip, search next start code */
                hevc->gvs->drop_frame_count++;
+               if (hevc->cur_pic->slice_type == I_SLICE) {
+                       hevc->gvs->i_lost_frames++;
+               } else if (hevc->cur_pic->slice_type == P_SLICE) {
+                       hevc->gvs->i_lost_frames++;
+               } else if (hevc->cur_pic->slice_type == B_SLICE) {
+                       hevc->gvs->i_lost_frames++;
+               }
                WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2));
                        hevc->skip_flag = 1;
                WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
@@ -11306,7 +11397,8 @@ int vh265_dec_status(struct vdec_info *vstatus)
        vstatus->frame_height =
                (hevc->frame_height << hevc->interlace_flag);
        if (hevc->frame_dur != 0)
-               vstatus->frame_rate = 96000 / hevc->frame_dur;
+               vstatus->frame_rate = ((96000 * 10 / hevc->frame_dur) % 10) < 5 ?
+                               96000 / hevc->frame_dur : (96000 / hevc->frame_dur +1);
        else
                vstatus->frame_rate = -1;
        vstatus->error_count = hevc->gvs->error_frame_count;
@@ -11320,6 +11412,15 @@ int vh265_dec_status(struct vdec_info *vstatus)
                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->i_decoded_frames = hevc->gvs->i_decoded_frames;
+               vstatus->i_lost_frames = hevc->gvs->i_lost_frames;
+               vstatus->i_concealed_frames = hevc->gvs->i_concealed_frames;
+               vstatus->p_decoded_frames = hevc->gvs->p_decoded_frames;
+               vstatus->p_lost_frames = hevc->gvs->p_lost_frames;
+               vstatus->p_concealed_frames = hevc->gvs->p_concealed_frames;
+               vstatus->b_decoded_frames = hevc->gvs->b_decoded_frames;
+               vstatus->b_lost_frames = hevc->gvs->b_lost_frames;
+               vstatus->b_concealed_frames = hevc->gvs->b_concealed_frames;
                vstatus->samp_cnt = hevc->gvs->samp_cnt;
                vstatus->offset = hevc->gvs->offset;
        }
index 061dedbff71db39dd14920780aece905c0892c67..03c420a25f755fa5a3cbad5adcbd80d7facfdef4 100644 (file)
@@ -1518,7 +1518,8 @@ static inline void hw_update_gvs(struct vdec_mpeg12_hw_s *hw)
        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;
+                       hw->gvs.frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
+                                       96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
                else
                        hw->gvs.frame_rate = -1;
        }
@@ -1642,12 +1643,27 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw,
                        ((PICINFO_TYPE_MASK & pic->buffer_info) !=
                         PICINFO_TYPE_I))) {
                        hw->drop_frame_count++;
+                       if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
+                               hw->gvs.i_lost_frames++;
+                       } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
+                               hw->gvs.p_lost_frames++;
+                       } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
+                               hw->gvs.b_lost_frames++;
+                       }
                        /* Though we drop it, it is still an error frame, count it.
                         * Becase we've counted the error frame in vdec_count_info
                         * function, avoid count it twice.
                         */
-                       if (!(info & PICINFO_ERROR))
-                               hw->gvs.error_frame_count++;
+               if (!(info & PICINFO_ERROR)) {
+                       hw->gvs.error_frame_count++;
+                       if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
+                               hw->gvs.i_concealed_frames++;
+                       } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
+                               hw->gvs.p_concealed_frames++;
+                       } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
+                               hw->gvs.b_concealed_frames++;
+                       }
+               }
                        hw->vfbuf_use[index]--;
                        kfifo_put(&hw->newframe_q,
                                (const struct vframe_s *)vf);
@@ -2060,6 +2076,24 @@ static irqreturn_t vmpeg12_isr(struct vdec_s *vdec, int irq)
        offset = READ_VREG(MREG_FRAME_OFFSET);
 
        vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset);
+       if (info &PICINFO_ERROR) {
+               if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
+                       hw->gvs.i_concealed_frames++;
+               } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
+                       hw->gvs.p_concealed_frames++;
+               } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
+                       hw->gvs.b_concealed_frames++;
+               }
+       }
+       if (offset) {
+               if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
+                       hw->gvs.i_decoded_frames++;
+               } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
+                       hw->gvs.p_decoded_frames++;
+               } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
+                       hw->gvs.b_decoded_frames++;
+               }
+       }
 
        WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
 
@@ -2419,7 +2453,8 @@ static int vmmpeg12_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)
-               vstatus->frame_rate = 96000 / hw->frame_dur;
+               vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
+                                   96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
        else
                vstatus->frame_rate = -1;
        vstatus->error_count = READ_VREG(AV_SCRATCH_C);
@@ -2431,6 +2466,15 @@ static int vmmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        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->i_decoded_frames = hw->gvs.i_decoded_frames;
+       vstatus->i_lost_frames = hw->gvs.i_lost_frames;
+       vstatus->i_concealed_frames = hw->gvs.i_concealed_frames;
+       vstatus->p_decoded_frames = hw->gvs.p_decoded_frames;
+       vstatus->p_lost_frames = hw->gvs.p_lost_frames;
+       vstatus->p_concealed_frames = hw->gvs.p_concealed_frames;
+       vstatus->b_decoded_frames = hw->gvs.b_decoded_frames;
+       vstatus->b_lost_frames = hw->gvs.b_lost_frames;
+       vstatus->b_concealed_frames = hw->gvs.b_concealed_frames;
        vstatus->total_data = hw->gvs.total_data;
        vstatus->samp_cnt = hw->gvs.samp_cnt;
        vstatus->offset = hw->gvs.offset;
index a30d2503a93a124f7a7901638a8a5c5e45fdadbb..ec568a1470d0260c2d1587ac274e9015d80dd72c 100644 (file)
@@ -319,6 +319,15 @@ struct vdec_mpeg4_hw_s {
        int sidebind_type;
        int sidebind_channel_id;
        unsigned int res_ch_flag;
+       unsigned int i_decoded_frames;
+       unsigned int i_lost_frames;
+       unsigned int i_concealed_frames;
+       unsigned int p_decoded_frames;
+       unsigned int p_lost_frames;
+       unsigned int p_concealed_frames;
+       unsigned int b_decoded_frames;
+       unsigned int b_lost_frames;
+       unsigned int b_concealed_frames;
 };
 static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw);
 static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw);
@@ -714,6 +723,13 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
                if (((hw->first_i_frame_ready == 0) || pb_skip)
                         && (pic->pic_type != I_PICTURE)) {
                        hw->drop_frame_count++;
+                       if (pic->pic_type == I_PICTURE) {
+                               hw->i_lost_frames++;
+                       } else if (pic->pic_type == P_PICTURE) {
+                               hw->p_lost_frames++;
+                       } else if (pic->pic_type == B_PICTURE) {
+                               hw->b_lost_frames++;
+                       }
                        hw->vfbuf_use[index]--;
                        kfifo_put(&hw->newframe_q,
                                (const struct vframe_s *)vf);
@@ -727,6 +743,13 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
                        ATRACE_COUNTER(MODULE_NAME, vf->pts);
                        vdec->vdec_fps_detec(vdec->id);
                        hw->frame_num++;
+                       if (pic->pic_type == I_PICTURE) {
+                               hw->i_decoded_frames++;
+                       } else if (pic->pic_type == P_PICTURE) {
+                               hw->p_decoded_frames++;
+                       } else if (pic->pic_type == B_PICTURE) {
+                               hw->b_decoded_frames++;
+                       }
                        if (without_display_mode == 0) {
                                vf_notify_receiver(vdec->vf_provider_name,
                                        VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -770,6 +793,13 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
                if (((hw->first_i_frame_ready == 0) || pb_skip)
                        && (pic->pic_type != I_PICTURE)) {
                        hw->drop_frame_count++;
+                       if (pic->pic_type == I_PICTURE) {
+                               hw->i_lost_frames++;
+                       } else if (pic->pic_type == P_PICTURE) {
+                               hw->p_lost_frames++;
+                       } else if (pic->pic_type == B_PICTURE) {
+                               hw->b_lost_frames++;
+                       }
                        hw->vfbuf_use[index]--;
                        kfifo_put(&hw->newframe_q,
                                (const struct vframe_s *)vf);
@@ -783,6 +813,13 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
                        vdec->vdec_fps_detec(vdec->id);
                        decoder_do_frame_check(vdec, vf);
                        hw->frame_num++;
+                       if (pic->pic_type == I_PICTURE) {
+                               hw->i_decoded_frames++;
+                       } else if (pic->pic_type == P_PICTURE) {
+                               hw->p_decoded_frames++;
+                       } else if (pic->pic_type == B_PICTURE) {
+                               hw->b_decoded_frames++;
+                       }
                        if (without_display_mode == 0) {
                                vf_notify_receiver(vdec->vf_provider_name,
                                        VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -840,6 +877,13 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
                if (((hw->first_i_frame_ready == 0) || pb_skip)
                        && (pic->pic_type != I_PICTURE)) {
                        hw->drop_frame_count++;
+                       if (pic->pic_type == I_PICTURE) {
+                               hw->i_lost_frames++;
+                       } else if (pic->pic_type == P_PICTURE) {
+                               hw->p_lost_frames++;
+                       } else if (pic->pic_type == B_PICTURE) {
+                               hw->b_lost_frames++;
+                       }
                        hw->vfbuf_use[index]--;
                        kfifo_put(&hw->newframe_q,
                                (const struct vframe_s *)vf);
@@ -855,7 +899,13 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
                        vdec->vdec_fps_detec(vdec->id);
                        decoder_do_frame_check(vdec, vf);
                        hw->frame_num++;
-
+                       if (pic->pic_type == I_PICTURE) {
+                               hw->i_decoded_frames++;
+                       } else if (pic->pic_type == P_PICTURE) {
+                               hw->p_decoded_frames++;
+                       } else if (pic->pic_type == B_PICTURE) {
+                               hw->b_decoded_frames++;
+                       }
                        vdec->dec_status(vdec, &vinfo);
                        vdec_fill_vdec_frame(vdec, NULL,
                                &vinfo, vf, pic->hw_decode_time);
@@ -1617,13 +1667,25 @@ 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 (0 != hw->vmpeg4_amstream_dec_info.rate)
-               vstatus->frame_rate = DURATION_UNIT /
-                               hw->vmpeg4_amstream_dec_info.rate;
+               vstatus->frame_rate = ((DURATION_UNIT * 10 / hw->vmpeg4_amstream_dec_info.rate) % 10) < 5 ?
+               DURATION_UNIT / hw->vmpeg4_amstream_dec_info.rate : (DURATION_UNIT / hw->vmpeg4_amstream_dec_info.rate +1);
        else
-               vstatus->frame_rate = DURATION_UNIT;
+               vstatus->frame_rate = -1;
        vstatus->error_count = READ_VREG(MP4_ERR_COUNT);
        vstatus->status = hw->stat;
        vstatus->frame_dur = hw->frame_dur;
+       vstatus->error_frame_count = READ_VREG(MP4_ERR_COUNT);
+       vstatus->drop_frame_count = hw->drop_frame_count;
+       vstatus->frame_count =hw->frame_num;
+       vstatus->i_decoded_frames = hw->i_decoded_frames;
+       vstatus->i_lost_frames = hw->i_lost_frames;
+       vstatus->i_concealed_frames = hw->i_concealed_frames;
+       vstatus->p_decoded_frames = hw->p_decoded_frames;
+       vstatus->p_lost_frames = hw->p_lost_frames;
+       vstatus->p_concealed_frames = hw->p_concealed_frames;
+       vstatus->b_decoded_frames = hw->b_decoded_frames;
+       vstatus->b_lost_frames = hw->b_lost_frames;
+       vstatus->b_concealed_frames = hw->b_concealed_frames;
        snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
                        "%s", DRIVER_NAME);
 
index 0eb146efbfeb04b3e1fa8482499e562f906eec0f..3a85cbb8fac4cff55797d5f1547454e562694595 100644 (file)
@@ -5144,6 +5144,10 @@ void vdec_fill_vdec_frame(struct vdec_s *vdec, struct vframe_qos_s *vframe_qos,
        if (vinfo) {
                memcpy(&fifo_buf[i].frame_width, &vinfo->frame_width,
                        ((char*)&vinfo->reserved[0] - (char*)&vinfo->frame_width));
+               /*copy for ipb report*/
+               memcpy(&fifo_buf[i].i_decoded_frames, &vinfo->i_decoded_frames,
+                       ((char*)&vinfo->endipb_line[0] - (char*)&vinfo->i_decoded_frames));
+               fifo_buf[i].av_resynch_counter = timestamp_avsync_counter_get();
        }
        if (vf) {
                fifo_buf[i].vf_type = vf->type;
index 54c5903e29fb8c6c43e1988b8d8594191cf71e26..a7bf13e197264b3ee044d71c85ab8587939f43fb 100644 (file)
@@ -470,4 +470,5 @@ int show_stream_buffer_status(char *buf,
 
 bool is_support_no_parser(void);
 
+extern u32 timestamp_avsync_counter_get(void);
 #endif                         /* VDEC_H */
index 9933e944999c00f67617d862d1ad96745bcbd070..5717d608f073f4c35b94ade0d5604af67725d4a2 100644 (file)
@@ -7137,7 +7137,8 @@ static inline void pbi_update_gvs(struct VP9Decoder_s *pbi)
        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;
+                       pbi->gvs->frame_rate = ((96000 * 10 / pbi->frame_dur) % 10) < 5 ?
+                                       96000 / pbi->frame_dur : (96000 / pbi->frame_dur +1);
                else
                        pbi->gvs->frame_rate = -1;
        }
@@ -7450,6 +7451,15 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi,
                        pbi_update_gvs(pbi);
                        /*count info*/
                        vdec_count_info(pbi->gvs, 0, stream_offset);
+                       if (stream_offset) {
+                               if (slice_type == KEY_FRAME) {
+                                       pbi->gvs->i_decoded_frames++;
+                               } else if (slice_type == INTER_FRAME) {
+                                       pbi->gvs->p_decoded_frames++;
+                               } else if (slice_type == FRAME_TYPES) {
+                                       pbi->gvs->b_decoded_frames++;
+                               }
+                       }
                        memcpy(&tmp4x, pbi->gvs, sizeof(struct vdec_info));
                        tmp4x.bit_depth_luma = pbi->vp9_param.p.bit_depth;
                        tmp4x.bit_depth_chroma = pbi->vp9_param.p.bit_depth;
@@ -9011,7 +9021,8 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        vstatus->frame_width = frame_width;
        vstatus->frame_height = frame_height;
        if (vp9->frame_dur != 0)
-               vstatus->frame_rate = 96000 / vp9->frame_dur;
+               vstatus->frame_rate = ((96000 * 10 / vp9->frame_dur) % 10) < 5 ?
+                               96000 / vp9->frame_dur : (96000 / vp9->frame_dur +1);
        else
                vstatus->frame_rate = -1;
        vstatus->error_count = 0;
@@ -9023,6 +9034,15 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
        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->i_decoded_frames = vp9->gvs->i_decoded_frames;
+       vstatus->i_lost_frames = vp9->gvs->i_lost_frames;
+       vstatus->i_concealed_frames = vp9->gvs->i_concealed_frames;
+       vstatus->p_decoded_frames = vp9->gvs->p_decoded_frames;
+       vstatus->p_lost_frames = vp9->gvs->p_lost_frames;
+       vstatus->p_concealed_frames = vp9->gvs->p_concealed_frames;
+       vstatus->b_decoded_frames = vp9->gvs->b_decoded_frames;
+       vstatus->b_lost_frames = vp9->gvs->b_lost_frames;
+       vstatus->b_concealed_frames = vp9->gvs->b_concealed_frames;
        vstatus->total_data = vp9->gvs->total_data;
        vstatus->samp_cnt = vp9->gvs->samp_cnt;
        vstatus->offset = vp9->gvs->offset;
index d40d8a60f228fc0b49a934d64726f3ad2f318af7..6b42a548d75f12c4726c39ec773273512d85e45e 100644 (file)
@@ -2619,28 +2619,20 @@ static long amstream_do_ioctl_new(struct port_priv_s *priv,
                        u32 struct_size = 0;
                        int vdec_id = 0;
                        struct vdec_s *vdec = NULL;
-                       struct vframe_counter_s tmpbuf[QOS_FRAME_NUM] = {0};
+                       struct vframe_counter_s *tmpbuf = kmalloc(QOS_FRAME_NUM *
+                                               sizeof(struct vframe_counter_s),GFP_KERNEL);
                        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, (u32)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;
-                               }
+                       if (!tmpbuf) {
+                               r = -EFAULT;
+                               pr_err("kmalloc vframe_counter_s failed!\n");
+                               break;
                        }
+
                        vdec = vdec_get_vdec_by_id(vdec_id);
                        if (!vdec) {
                                r = 0;
+                               kfree(tmpbuf);
                                break;
                        }
 
@@ -2649,19 +2641,43 @@ static long amstream_do_ioctl_new(struct port_priv_s *priv,
                                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))) {
+                                       if (get_user(vdec_id, &uarg->vdec_id) < 0 ||
+                                       get_user(struct_size, &uarg->struct_size) < 0) {
                                                r = -EFAULT;
+                                               kfree(tmpbuf);
                                                break;
                                        }
-                                       if (copy_to_user((void *)&uarg->minfo[0],
-                                                               tmpbuf,
-                                                               slots*sizeof(struct vframe_counter_s))) {
+                                       if (copy_to_user((void *)&uarg->comm,
+                                                               &vdec->mvfrm->comm,
+                                                               sizeof(struct vframe_comm_s))) {
                                                r = -EFAULT;
                                                kfree(tmpbuf);
                                                break;
                                        }
+                                       if (struct_size == sizeof(struct av_param_mvdec_t_old)) {//old struct
+                                               struct av_param_mvdec_t_old  __user *uarg_old = (void *)arg;
+                                               int m;
+                                               for (m=0; m<slots; m++)
+                                                       if (copy_to_user((void *)&uarg_old->minfo[m],
+                                                                               &tmpbuf[m],
+                                                                               sizeof(struct vframe_counter_s_old))) {
+                                                               r = -EFAULT;
+                                                               kfree(tmpbuf);
+                                                               break;
+                                                       }
+                                       } else if (struct_size == sizeof(struct av_param_mvdec_t)) {//new struct
+                                               if (copy_to_user((void *)&uarg->minfo[0],
+                                                                       tmpbuf,
+                                                                       slots*sizeof(struct vframe_counter_s))) {
+                                                       r = -EFAULT;
+                                                       kfree(tmpbuf);
+                                                       break;
+                                               }
+                                       } else {
+                                               pr_err("pass in size %u,old struct size %u,current struct size %u\n",
+                                               struct_size, (u32)sizeof(struct av_param_mvdec_t_old),(u32)sizeof(struct av_param_mvdec_t));
+                                               pr_err("App use another picture size,we haven't support it.\n");
+                                       }
                                }else { //For compatibility, only copy the qos
                                        struct av_param_qosinfo_t  __user *uarg = (void *)arg;
                                        int i;
@@ -2670,6 +2686,7 @@ static long amstream_do_ioctl_new(struct port_priv_s *priv,
                                                                        &tmpbuf[i].qos,
                                                                        sizeof(struct vframe_qos_s))) {
                                                        r = -EFAULT;
+                                                       kfree(tmpbuf);
                                                        break;
                                                }
                                }
@@ -2678,6 +2695,7 @@ static long amstream_do_ioctl_new(struct port_priv_s *priv,
                              infinitely calling*/
                                //msleep(10); let user app handle it.
                        }
+                       kfree(tmpbuf);
                }
                break;
        case AMSTREAM_IOC_GET_AVINFO: