int sidebind_channel_id;
u32 profile_idc;
u32 level_idc;
+ int dec_again_cnt;
};
static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw);
static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw);
/*static int counter_max = 5;*/
static u32 run_ready_min_buf_num = 2;
-
+static int dirty_again_threshold = 100;
+static int error_proc_policy = 0x1;
#define PRINT_FLAG_ERROR 0x0
#define PRINT_FLAG_RUN_FLOW 0X0001
if (hw) {
mutex_lock(&hw->userdata_mutex);
- pr_info("%s: bInit: %d, ri: %d, wi: %d\n",
- __func__,
+ pr_info("mpeg2_reset_userdata_fifo: bInit: %d, ri: %d, wi: %d\n",
bInit,
hw->userdata_info.read_index,
hw->userdata_info.write_index);
debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
"%s, result=%d, status=%d\n", __func__,
hw->dec_result, vdec->next_status);
-
if (hw->dec_result == DEC_RESULT_DONE) {
+ if (vdec->input.swap_valid)
+ hw->dec_again_cnt = 0;
vdec_vframe_dirty(vdec, hw->chunk);
hw->chunk = NULL;
} else if (hw->dec_result == DEC_RESULT_AGAIN &&
#ifdef AGAIN_HAS_THRESHOLD
hw->next_again_flag = 1;
#endif
+ //hw->dec_again_cnt++;
} else if (hw->dec_result == DEC_RESULT_GET_DATA &&
vdec->next_status != VDEC_STATUS_DISCONNECTED) {
if (!vdec_has_more_input(vdec)) {
hw->buffer_not_ready = 0;
hw->start_process_time = 0;
hw->init_flag = 0;
+ hw->dec_again_cnt = 0;
hw->error_frame_skip_level = error_frame_skip_level;
if (dec_control)
return sum;
}
+static int check_dirty_data(struct vdec_s *vdec)
+{
+ struct vdec_mpeg12_hw_s *hw =
+ (struct vdec_mpeg12_hw_s *)(vdec->private);
+ u32 wp, rp, level;
+
+ rp = STBUF_READ(&vdec->vbuf, get_rp);
+ wp = STBUF_READ(&vdec->vbuf, get_wp);
+
+ if (wp > rp)
+ level = wp - rp;
+ else
+ level = wp + vdec->input.size - rp ;
+
+ if (hw->next_again_flag &&
+ hw->pre_parser_wr_ptr !=
+ STBUF_READ(&vdec->vbuf, get_wp))
+ hw->dec_again_cnt++;
+ if ((level > (vdec->input.size * 2 / 3) ) &&
+ (hw->dec_again_cnt > dirty_again_threshold)) {
+ debug_print(DECODE_ID(hw), 0, "mpeg12 data skipped %x, level %x\n", ((level / 2) >> 20) << 20, level);
+ if (vdec->input.swap_valid) {
+ vdec_stream_skip_data(vdec, ((level / 2) >> 20) << 20);
+ hw->dec_again_cnt = 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
static void run(struct vdec_s *vdec, unsigned long mask,
void (*callback)(struct vdec_s *, void *),
void *arg)
hw->vdec_cb_arg = arg;
hw->vdec_cb = callback;
+ if ((vdec_stream_based(vdec)) &&
+ (error_proc_policy & 0x1) &&
+ check_dirty_data(vdec)) {
+ hw->dec_result = DEC_RESULT_AGAIN;
+ if (!vdec->input.swap_valid) {
+ debug_print(DECODE_ID(hw), 0, "mpeg12 start dirty data skipped\n");
+ vdec_prepare_input(vdec, &hw->chunk);
+ hw->dec_result = DEC_RESULT_DONE;
+ }
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+
#ifdef AGAIN_HAS_THRESHOLD
if (vdec_stream_based(vdec)) {
hw->pre_parser_wr_ptr =
module_param(udebug_flag, uint, 0664);
MODULE_PARM_DESC(udebug_flag, "\n ammvdec_mpeg12 udebug_flag\n");
+module_param(dirty_again_threshold, int, 0664);
+MODULE_PARM_DESC(dirty_again_threshold, "\n ammvdec_mpeg12 dirty_again_threshold\n");
+
#ifdef AGAIN_HAS_THRESHOLD
module_param(again_threshold, uint, 0664);
module_param(without_display_mode, uint, 0664);
MODULE_PARM_DESC(without_display_mode, "\n ammvdec_mpeg12 without_display_mode\n");
+module_param(error_proc_policy, uint, 0664);
+MODULE_PARM_DESC(error_proc_policy, "\n ammvdec_mpeg12 error_proc_policy\n");
module_init(ammvdec_mpeg12_driver_init_module);
module_exit(ammvdec_mpeg12_driver_remove_module);
}
}
+void vdec_stream_skip_data(struct vdec_s *vdec, int skip_size)
+{
+ u32 rp_set;
+ struct vdec_input_s *input = &vdec->input;
+ u32 rp = 0, wp = 0, level;
+
+ rp = STBUF_READ(&vdec->vbuf, get_rp);
+ wp = STBUF_READ(&vdec->vbuf, get_wp);
+ pr_err("aaaa wp %x, rp %x\n", wp, rp);
+ pr_err("1VLD_MEM_VIFIFO_RP %x\n", rp);
+
+ if (wp > rp)
+ level = wp - rp;
+ else
+ level = wp + vdec->input.size - rp ;
+
+ if (level <= skip_size) {
+ pr_err("skip size is error, buffer level = 0x%x, skip size = 0x%x\n", level, skip_size);
+ return;
+ }
+
+ if (wp >= rp) {
+ pr_err("case 1\n");
+ rp_set = rp + skip_size;
+ }
+ else if ((rp + skip_size) < (input->start + input->size)) {
+ pr_err("case 2\n");
+ rp_set = rp + skip_size;
+ } else {
+ pr_err("case 3\n");
+ rp_set = rp + skip_size - input->size;
+ input->stream_cookie++;
+ }
+
+ if (vdec->format == VFORMAT_H264)
+ SET_VREG_MASK(POWER_CTL_VLD,
+ (1 << 9));
+
+ WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
+
+ /* restore read side */
+ WRITE_VREG(VLD_MEM_SWAP_ADDR,
+ input->swap_page_phys);
+ WRITE_VREG(VLD_MEM_SWAP_CTL, 1);
+
+ while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7))
+ ;
+ WRITE_VREG(VLD_MEM_SWAP_CTL, 0);
+
+ WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR,
+ rp_set);
+ WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1);
+ WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
+ STBUF_WRITE(&vdec->vbuf, set_rp,
+ rp_set);
+ WRITE_VREG(VLD_MEM_SWAP_ADDR,
+ input->swap_page_phys);
+ WRITE_VREG(VLD_MEM_SWAP_CTL, 3);
+ while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7))
+ ;
+ WRITE_VREG(VLD_MEM_SWAP_CTL, 0);
+ pr_err("2VLD_MEM_VIFIFO_RP %x\n", READ_VREG(VLD_MEM_VIFIFO_RP));
+
+}
+EXPORT_SYMBOL(vdec_stream_skip_data);
+
+
+
/*
*get next frame from input chain
*/