116 files changed, 25845 insertions, 36303 deletions
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index c098a5e..aa73613 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 { @@ -305,6 +307,7 @@ struct vdec_mpeg4_hw_s { bool v4l_params_parsed; u32 buf_num; u32 dynamic_buf_num_margin; + u32 i_only; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); @@ -611,7 +614,20 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, { struct vframe_s *vf = NULL; struct vdec_s *vdec = hw_to_vdec(hw); + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + ulong nv_order = VIDTYPE_VIU_NV21; int index = pic->index; + bool pb_skip = false; + + /* swap uv */ + if (hw->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } + + if (hw->i_only) + pb_skip = 1; if (pic->pic_info & INTERLACE_FLAG) { if (kfifo_get(&hw->newframe_q, &vf) == 0) { @@ -642,7 +658,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ? VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM; #ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; #endif set_frame_info(hw, vf, pic->index); @@ -651,7 +667,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, "field0: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) + if (((hw->first_i_frame_ready == 0) || pb_skip) && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; @@ -694,7 +710,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ? VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; #ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; #endif set_frame_info(hw, vf, pic->index); @@ -702,8 +718,8 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, "filed1: pts %d, pts64 %lld, w %d, h %d, dur: %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) && - (pic->pic_type != I_PICTURE)) { + if (((hw->first_i_frame_ready == 0) || pb_skip) + && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; kfifo_put(&hw->newframe_q, @@ -755,7 +771,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, pic->duration; #ifdef NV21 vf->type = VIDTYPE_PROGRESSIVE | - VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21; + VIDTYPE_VIU_FIELD | nv_order; #else vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; @@ -767,13 +783,15 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, "prog: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) && - (pic->pic_type != I_PICTURE)) { + if (((hw->first_i_frame_ready == 0) || pb_skip) + && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; 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 +802,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 +970,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; @@ -978,9 +1004,6 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; } if (hw->vmpeg4_amstream_dec_info.rate == 0) { @@ -1518,13 +1541,8 @@ static int vmpeg4_canvas_init(struct vdec_mpeg4_hw_s *hw) decbuf_size = ALIGN(align_w * align_h * 3/2, SZ_64K); } else { /*1080p*/ - if (h > w) { - canvas_width = 1088; - canvas_height = 1920; - } else { - canvas_width = 1920; - canvas_height = 1088; - } + canvas_width = 1920; + canvas_height = 1088; decbuf_y_size = 0x200000; decbuf_size = 0x300000; } @@ -1770,8 +1788,6 @@ static void check_timer_func(unsigned long arg) } if (((debug_enable & PRINT_FLAG_TIMEOUT_STATUS) == 0) && - (vdec_frame_based(vdec) || - ((u32)READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x100)) && (timeout_val > 0) && (hw->start_process_time > 0) && ((1000 * (jiffies - hw->start_process_time) / HZ) @@ -2205,6 +2221,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 +2231,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; @@ -2250,6 +2270,23 @@ static void reset(struct vdec_s *vdec) hw->ctx_valid = 0; } +static int vmpeg4_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct vdec_mpeg4_hw_s *hw = + (struct vdec_mpeg4_hw_s *)vdec->private; + if (!hw) + return 0; + + if (trickmode == TRICKMODE_I) { + hw->i_only = 0x3; + trickmode_i = 1; + } else if (trickmode == TRICKMODE_NONE) { + hw->i_only = 0x0; + trickmode_i = 0; + } + return 0; +} + static int ammvdec_mpeg4_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; @@ -2274,6 +2311,7 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = dec_status; /* pdata->set_trickmode = set_trickmode; */ + pdata->set_trickmode = vmpeg4_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; @@ -2348,6 +2386,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 { |