⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_dec_isr.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* all decode done */
        if (g_video_dec_info_ptr->video_end == KAL_FALSE)
        {
            video_dbg_trace(MP4_DEC_HISR_LAST_ONE, video_get_current_time());

            ASSERT(g_video_dec_info_ptr->video_dec_callback != NULL);
            g_video_dec_info_ptr->video_end = KAL_TRUE;
#if defined(__VIDEO_EDITOR__)
            if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
            {
                ASSERT(0);
            }
            else
#endif /*__VIDEO_EDITOR__*/
            {
                /* all decode done */
                video_dec_complete();
            }
        }
        return;
    }
    else if (g_video_dec_info_ptr->hdr_parse_frames_no == g_video_dec_info_ptr->total_frames_in_file)
    {
        /* all parse done */
        return;
    }

    video_dbg_trace(MP4_DEC_HISR_ENTRY, video_get_current_time());
    /* get next frame for parsing */
    result = video_dec_get_next_frame(&frame_addr, &frame_length, &prev_frame_duration);

    if (result != MEDIA_STATUS_OK)
    {
         /* Exception cases: Task can't prepare the enough buffer */
        g_video_dec_info_ptr->skip_frames++;

        Buffer_WRITE(BUFFER_MP4_FRAME_DURATION, prev_frame_duration);
        g_video_dec_info_ptr->hdr_parse_frames_no++;
        g_video_dec_info_ptr->lost_frames++;
        return;
    }
    else
    {
        /* Skip frame only increment in previous HISR, shoule be clear to 0 before next time comes here */
        if (g_video_dec_info_ptr->skip_frames)
            EXT_ASSERT(0, g_video_dec_info_ptr->skip_frames, 0, 0);
    }

    if (prev_frame_duration == 0)
    {
        VIDEO_ASSERT(0);

        mpeg4_dec_isr_error_report_hdlr();
        return;
    }

    /* parse next frame */
    result = mpeg4_decode_main((kal_uint8 *)frame_addr, frame_length, prev_frame_duration);

    if (result != MEDIA_STATUS_OK)
    {
        /* This frame is non-coded */
        VIDEO_ASSERT(0);
        g_video_dec_info_ptr->is_non_coded = KAL_TRUE;
    }

    video_dbg_trace(MP4_DEC_HISR_END, video_get_current_time());
}


/* Decode lisr process function. Check interrupt status and do corresponding handling
 * @param None   
 * @return None                                                        
 */
static void mpeg4_dec_lisr_process(void)
{
    kal_uint32 status;
    kal_uint32 lost_display;
    
    video_dbg_trace(MP4_DEC_LISR_ENTRY, video_get_current_time());

#if ( defined(MT6219) || defined(MT6226) || defined(MT6227) || defined(MT6226M) )
    IRQMask(IRQ_MPEG4_CODE);
#else  /*MT6228, MT6229, MT6230*/
    IRQMask(IRQ_MPEG4_DEC_CODE);
#endif /*MT6228, MT6229, MT6230*/

    /* check state */
    if (g_video_dec_info_ptr->dec_state != VIDEO_DEC_STATE_NORMAL)
    {
        VIDEO_ASSERT(0);

        g_video_dec_info_ptr->isr_error_event_happen = KAL_TRUE;
        g_video_dec_status.VIDEO_STATUS = VIDEO_DEC_FUNC_STATE_ERROR;
        visual_active_hisr(VISUAL_MPEG4_DEC_HISR_ID);
        return;
    }

    //Jensen's tricky
    if ((g_video_dec_info_ptr->dec_frames_no == g_video_dec_info_ptr->total_frames_in_file)
            || (g_video_dec_info_ptr->dec_frames_no == g_video_dec_info_ptr->stop_frame_no))
    {
        VIDEO_ASSERT(0);
        return;
    }

    /* check re-entry */
    if(g_video_dec_isr_param.b_check_reentry !=  KAL_FALSE)
    {
        VIDEO_ASSERT(0);

        g_video_dec_info_ptr->isr_error_event_happen = KAL_TRUE;
        g_video_dec_status.VIDEO_STATUS = VIDEO_DEC_FATAL_ERROR;
        visual_active_hisr(VISUAL_MPEG4_DEC_HISR_ID);
        g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
        return;
    }

    g_video_dec_isr_param.b_check_reentry = KAL_TRUE;

    /* skip frame != 0 means task can't prepare enough buffer, should stop decode and activate recover mechanism */
    if ((g_video_dec_info_ptr->skip_frames == 0) && (g_video_dec_info_ptr->prepare_recover==KAL_FALSE))
    {
        /* Previous HISR has parsed frame successfully, decode it ! */
#if ( defined(MT6219) || defined(MT6226) || defined(MT6227) || defined(MT6226M) )
        status = DRV_Reg32(MP4_IRQ_STS);
#else /* !(MT6219, MT6226, MT6227, MT6226M) */
        status = DRV_Reg32(MP4_DEC_IRQ_STS);
#endif /* (MT6219, MT6226, MT6227, MT6226M) */

        /* Skip check isr status happens when the previous decoded frame is on-coded. 
             so dose not really write register to decode it */
        if (g_video_dec_info_ptr->skip_check_isr_status == KAL_FALSE)
        {
        #if ( defined(MT6219) || defined(MT6226) || defined(MT6227) || defined(MT6226M) )
            if (status & MP4_IRQ_STS_DEC)
            {
                /* decode done */
                 g_video_dec_isr_param.speed_recover_count = 0;
                 
                DRV_WriteReg32(MP4_IRQ_ACK, MP4_IRQ_STS_DEC);

                DRV_WriteReg32(MP4_VLC_COMD, MP4_VLC_COMD_STOP);

                if (g_video_dec_info_ptr->play_speed > 100)
                {
                    g_video_dec_info_ptr->decode_error_frame_count_in_high_speed = 0;
                }
                video_dec_display();
            }
            else if ((status == 0)
                         && (((g_video_dec_info_ptr->play_speed % 100) != 0)
                                 || (g_video_dec_info_ptr->play_speed <= 100)) 
                         && (g_video_dec_isr_param.speed_recover_count < 3))
            {
                /* Audio support time stretch in this case. error recover for this case */
                VIDEO_ASSERT(0);
                video_dbg_trace(MP4_MAY_ISR_ERROR, video_get_current_time());
                
                g_video_dec_isr_param.speed_recover_count++;
                g_video_dec_isr_param.b_check_exception = KAL_TRUE;
                video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
                GPTI_StartItem(g_video_dec_isr_param.gpt_exception_protect_handle, 2, /*20ms*/
                               mpeg4_exception_handler, NULL);
                g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
                IRQ_Register_LISR(IRQ_MPEG4_CODE, mpeg4_dec_recover_LISR, "MPEG4");
                IRQSensitivity(IRQ_MPEG4_CODE, LEVEL_SENSITIVE);
                IRQUnmask(IRQ_MPEG4_CODE);
                return;
            }
            else
            {
                /* not decode done, something error */
                video_dbg_trace(MP4_MAY_ISR_ERROR, video_get_current_time());

                if (g_video_dec_info_ptr->play_speed > 100)
                {
                    g_video_dec_info_ptr->decode_error_frame_count_in_high_speed++;
                    if (g_video_dec_info_ptr->decode_error_frame_count_in_high_speed
                            <= (g_video_dec_info_ptr->play_speed / 100))
                    {
                        /*Tricky for high speed*/
                        /* In this case, audio mute. No AV sync issue. So just set one more frame time to decode this frame */
                        /* It may decode done in next AV sync interrupt handler */
                        video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
                        g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
                        VIDEO_ASSERT(0);
                        return;
                    }
                    else
                    {
                        /* High speed, but decode too long (more than N frames). So reset it */
                        mpeg4_dec_reset();
                        VIDEO_ASSERT(0);
                    }
                }
                else
                {
                    /* Normal/Slow speed can not decode more than one frame time */
                    mpeg4_dec_reset();
                    VIDEO_ASSERT(0);
                }

                DRV_WriteReg32(MP4_IRQ_ACK, status);
                
                /* Use the current ref frame as the next ref frame, since the rec frame data is not correct*/
                Buffer_WRITE(BUFFER_MP4_REC_ADDR, DRV_Reg32(MP4_REC_ADDR));
                Buffer_WRITE(BUFFER_MP4_REF_ADDR, DRV_Reg32(MP4_REF_ADDR));

                video_dec_prev_display();
                
            }
        #else /* !(MT6219, MT6226, MT6227, MT6226M) */

            if (status & MP4_DEC_IRQ_STS_DEC)
            {
                /* decode done */
                
                g_video_dec_isr_param.speed_recover_count = 0;

                DRV_WriteReg32(MP4_DEC_IRQ_ACK, MP4_DEC_IRQ_STS_DEC);
                DRV_WriteReg32(MP4_VLC_DMA_COMD, MP4_VLC_DMA_COMD_STOP);

                if (g_video_dec_info_ptr->play_speed > 100)
                {
                    g_video_dec_info_ptr->decode_error_frame_count_in_high_speed = 0;
                }
                
                video_dec_display();
            }
            else if (status & MP4_DEC_IRQ_STS_DMA)
            {
                if (g_video_dec_isr_param.check_vlc_addr == KAL_TRUE)
                {
                    /* frame length is larger than 0xffff */
                    VIDEO_ASSERT(0);

                    /* Reload VLC DMA */
                    DRV_WriteReg32(MP4_CORE_VLC_LIMIT, 0xffff);
                    DRV_WriteReg32(MP4_CORE_VLC_ADDR, (g_video_dec_isr_param.vlc_addr + 0xffff));
                    g_video_dec_isr_param.vlc_addr = (g_video_dec_isr_param.vlc_addr + 0xffff);
                    DRV_WriteReg32(MP4_VLC_DMA_COMD, MP4_VLC_DMA_COMD_RELOAD);

                    /* Start error check mechanism */
                    g_video_dec_isr_param.b_check_exception = KAL_TRUE;
                    video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
                    GPTI_StartItem(g_video_dec_isr_param.gpt_exception_protect_handle, 3, /*20~30ms*/
                                   mpeg4_exception_handler, NULL);
                    g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
                    IRQ_Register_LISR(IRQ_MPEG4_DEC_CODE, mpeg4_dec_recover_LISR, "MPEG4");
                    IRQSensitivity(IRQ_MPEG4_DEC_CODE, LEVEL_SENSITIVE);
                    IRQUnmask(IRQ_MPEG4_DEC_CODE);
                    return;
                }
                else
                {
                    EXT_ASSERT(0, g_video_dec_info_ptr->dec_frames_no, g_video_dec_info_ptr->total_frames_in_file, 
                    	            g_video_dec_info_ptr->hdr_parse_frames_no);
                }
            }
            else if ((status == 0)
                         && (((g_video_dec_info_ptr->play_speed % 100) != 0)
                                 || (g_video_dec_info_ptr->play_speed <= 100)) 
                         && (g_video_dec_isr_param.speed_recover_count < 3))
            {
                /* Audio support time stretch in this case. error recover for this case */
                VIDEO_ASSERT(0);
                video_dbg_trace(MP4_MAY_ISR_ERROR, video_get_current_time());
                
                g_video_dec_isr_param.speed_recover_count++;
                g_video_dec_isr_param.b_check_exception = KAL_TRUE;
                video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
                GPTI_StartItem(g_video_dec_isr_param.gpt_exception_protect_handle, 2, /*20ms*/
                               mpeg4_exception_handler, NULL);
                g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
                IRQ_Register_LISR(IRQ_MPEG4_DEC_CODE, mpeg4_dec_recover_LISR, "MPEG4");
                IRQSensitivity(IRQ_MPEG4_DEC_CODE, LEVEL_SENSITIVE);
                IRQUnmask(IRQ_MPEG4_DEC_CODE);
                return;
            }
            else
            {
                video_dbg_trace(MP4_MAY_ISR_ERROR, video_get_current_time());

                if (g_video_dec_info_ptr->play_speed > 100)
                {
                    /* Audio mute in this case */
                    g_video_dec_info_ptr->decode_error_frame_count_in_high_speed++;
                    if (g_video_dec_info_ptr->decode_error_frame_count_in_high_speed
                            <= (g_video_dec_info_ptr->play_speed / 100))
                    {
                        /* Tricky for high speed */
                        /* In this case, audio mute. No AV sync issue. So just set one more frame time to decode this frame */
                        /* It may decode done in next AV sync interrupt handler */
                        video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
                        g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
                        VIDEO_ASSERT(0);
                        return;
                    }
                    else
                    {
                        /* High speed, but decode too long (more than N frames). So reset it */
                        mpeg4_dec_reset();
                        mpeg4_core_reset();
                        VIDEO_ASSERT(0);
                    }
                }
                else
                {
                    /* Normal/Slow speed can not decode more than one frame time */
                    mpeg4_dec_reset();
                    mpeg4_core_reset();
                    VIDEO_ASSERT(0);
                }

                DRV_WriteReg32(MP4_DEC_IRQ_ACK, status);

                {
                    /* Use the current ref frame as the next ref frame, since the rec frame data is not correct*/
                    MPEG4_FRAME_BUFFER_ADDR frame_buffer_addr;

                    mpeg4_dec_sort_frame_buffer(DRV_Reg32(MP4_DEC_REC_ADDR), &frame_buffer_addr);
                    Buffer_WRITE(BUFFER_MP4_REC_ADDR, frame_buffer_addr.rec_addr);
                    Buffer_WRITE(BUFFER_MP4_REF_ADDR, frame_buffer_addr.ref_addr);
                    Buffer_WRITE(BUFFER_MP4_DEBLOCK_ADDR, frame_buffer_addr.deblock_addr);
                }
                
                video_dec_prev_display();
            }
        #endif       /* (MT6219, MT6226, MT6227, MT6226M) */

        }
        else /* !if (g_video_dec_info_ptr->skip_check_isr_status == KAL_FALSE) */
        {
             /* Skip check isr status happens when the previous decoded frame is on-coded. 
             so dose not really write register to decode it */
        #if ( defined(MT6219) || defined(MT6226) || defined(MT6227) || defined(MT6226M) )
            DRV_WriteReg32(MP4_IRQ_ACK, status);
        #else  /* !(MT6219, MT6226, MT6227, MT6226M) */
            DRV_WriteReg32(MP4_DEC_IRQ_ACK, status);
        #endif /* (MT6219, MT6226, MT6227, MT6226M) */
        
            g_video_dec_info_ptr->skip_check_isr_status = KAL_FALSE;
            video_dec_display();
        }

        g_video_dec_info_ptr->dec_frames_no++;

        if(g_video_dec_info_ptr->pre_frame_duration==0)
        	VIDEO_ASSERT(0);

        /* update play time, upper layer may use this as play time */
        g_video_dec_info_ptr->play_time += g_video_dec_info_ptr->pre_frame_duration;

        /* set next frame time */
        video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
        g_video_dec_info_ptr->pre_frame_duration = video_dec_get_curr_frame_duration();

        /* decode next frame when needed */
        if (g_video_dec_info_ptr->dec_frames_no < g_video_dec_info_ptr->total_frames_in_file)
        {
            if ((g_video_dec_info_ptr->stop_frame_no != g_video_dec_info_ptr->total_frames_in_file)
                    && (g_video_dec_info_ptr->dec_frames_no == g_video_dec_info_ptr->stop_frame_no))
            {
                g_video_dec_info_ptr->isr_error_event_happen = KAL_TRUE;
                g_video_dec_status.VIDEO_STATUS = VIDEO_DEC_FATAL_ERROR;
            }
            else
            {
                mpeg4_decode_write_register();
            }
        }
    }
    else /*if (g_video_dec_info_ptr->skip_frames == 0)*/
    {
        /* Exception cases: Task can't prepare the enough buffer */
        if (g_video_dec_info_ptr->play_speed >= 200)
        {
            lost_display = g_video_dec_info_ptr->disp_lost_frames;
            video_dec_display();
            if(lost_display!=g_video_dec_info_ptr->disp_lost_frames)  
            {
                // fail display
                g_video_dec_info_ptr->prepare_recover = KAL_TRUE;
                video_dec_set_frametime(video_dec_get_curr_frame_duration(), KAL_FALSE);
                g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
                return;
            }
        }
        
        g_video_dec_info_ptr->dec_frames_no++;
        g_video_dec_info_ptr->prepare_recover = KAL_FALSE;
        g_video_dec_info_ptr->recover_start = KAL_TRUE;
        g_video_dec_info_ptr->recover_start_frame = g_video_dec_info_ptr->dec_frames_no;
        video_dec_disable_irq();
        video_dec_start_refresh();
        // Rey's A2V
        //video_dec_stop_av();
    }

    visual_active_hisr(VISUAL_MPEG4_DEC_HISR_ID);
    g_video_dec_isr_param.b_check_reentry = KAL_FALSE;
    video_dbg_trace(MP4_DEC_LISR_END, video_get_current_time());
}


/* Decode error recover LISR  function. Act in MPEG4 LISR context
 *  It is used when decode can not be done in normal AV sync LISR 
 * @param None   
 * @return None                                                        
 */
static void mpeg4_dec_recover_LISR(void) /*Mpeg4 ISR*/
{
#ifdef __VIDEO_EDITOR__

    if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
    {
        ASSERT(0);
    }
    else
#endif /*__VIDEO_EDITOR__*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -