📄 decoder.c
字号:
u32pipe |= BIT_4ST; vpe_prob_dmc_start(); while ((ptMP4->CPSTS & BIT1) == 0) ; vpe_prob_dmc_end(); }//(13)preDMC(2S-3S) if (u32pipe & BIT_2ST) { u32pipe &= ~ BIT_2ST; u32pipe |= BIT_3ST; if (mb_dmc->mode <= MODE_INTRA_Q) { if (mb_dmc->mode <= MODE_INTER4V) u32cmd_mc |= MCCTL_DMCGO; else u32cmd_mc |= (MCCTL_DMCGO | MCCTL_INTRA); // fill CBP in this stage ptMP4->QCR0 = (mbb_dmc->quant << 18) | mbb_dmc->cbp; } } #if (OUTPUT_FMT < OUTPUT_FMT_YUV)//(27)waitDT(D-x)(Conf0) if (u32pipe & BIT_PRE_DT) { u32pipe &= ~ BIT_PRE_DT; vpe_prob_dt_start(); while((ptMP4->CPSTS & BIT14) == 0) ; vpe_prob_dt_end(); }//(21)preDT(4S)(x-D)(Conf0) if (u32pipe & BIT_4ST) { if ((mbb_img->x >= u32output_mb_start) && (mbb_img->x < u32output_mb_end) && (mbb_img->y >= u32output_mb_ystart) && (mbb_img->y < u32output_mb_yend)) {// if ((mbb_img->x >= u32output_mb_start)// && (mbb_img->x < u32output_mb_end)// && (mbb_img->y < (dec->output_height / PIXEL_Y))) { u32pipe |= BIT_PRE_DT; if (mbb_img->toggle) { ptMP4->MECADDR = INTER_Y_OFF_1; // YUV2RGB source addr, [10: 7] valid ptMP4->MCCADDR = BUFFER_RGB_OFF_1;// YUV2RGB dest. addr, [10: 7] valid } else { ptMP4->MECADDR = INTER_Y_OFF_0; // YUV2RGB source addr, [10: 7] valid ptMP4->MCCADDR = BUFFER_RGB_OFF_0;// YUV2RGB dest. addr, [10: 7] valid } u32cmd_mc |= MCCTL_DTGO; } } #endif//(10)waitVLD(1S-2S) if (u32pipe & BIT_1ST) { u32pipe &= ~BIT_1ST; u32pipe |= BIT_2ST; vpe_prob_vld_start(); while (((u32temp = ptMP4->VLDSTS) & BIT0) == 0) ; vpe_prob_vld_end(); if (u32temp & 0xF000) goto DECODER_PFRAME_RECHECK; } //(*)ChgQCOEFF_vld----------------------------(*)ChgQCOEFF_dmc // switch 3 buffer // setup Dezigzag-scan output address and dequant input address // VLD output to DZQ[31..16] DZQ[15..0] is input of DMC switch (i % 3) { case 0: ptMP4->QAR = ((QCOEFF_OFF_0 & 0xFFFF) << 16) | (QCOEFF_OFF_1 & 0xFFFF); break; case 1: ptMP4->QAR = ((QCOEFF_OFF_1 & 0xFFFF) << 16) | (QCOEFF_OFF_2 & 0xFFFF); break; default: ptMP4->QAR = ((QCOEFF_OFF_2 & 0xFFFF) << 16) | (QCOEFF_OFF_0 & 0xFFFF); break; }//(22)waitME_pxi(4S) if (u32pipe & BIT_4ST) { vpe_prob_me_start(); // check ME done while ((ptMP4->CPSTS & BIT0) == 0) ; vpe_prob_me_end(); }#if 1 if (u32pipe & BIT_3ST) { // toggle meiaddr & mciaddr when mode != MODE_STUFFING if (mbb_dmc->toggle) { // interpolation_output direct to INTER_Y_OFF_1 ptMP4->MEIADDR = INTER_Y_OFF_1; // dmc_input(& output) direct to INTER_Y_OFF_1 ptMP4->MCIADDR = INTER_Y_OFF_1; } else { // interpolation_output direct to INTER_Y_OFF_0 ptMP4->MEIADDR = INTER_Y_OFF_0; // dmc_input(& output) direct to INTER_Y_OFF_0 ptMP4->MCIADDR = INTER_Y_OFF_0; } }#endif//(11)waitDMA_LD_ST-(14)waitDMA_ref------------(28)waitDMA_img--(31)waitDMA_rgb(Conf0)// |---(29)waitDMA_yuv(Conf1) { vpe_prob_dma_start(); while((ptDma->Status & BIT0) == 0) ; vpe_prob_dma_end(); } if (u32pipe == 0) break; } i = 0; while (u32ErrorCount) { mb_vld = &dec->mbs[i]; if (mb_vld->mb_jump != 0) { error_concealment_p(dec, i, mb_vld->mb_jump + 1); u32ErrorCount --; i += dec->mbs[i].mb_jump; } else i ++; } for (; (ptMP4->VLDSTS & BIT10)==0; ) ; /// wait for autobuffer clean // stop auto-buffering ptMP4->VLDCTL = VLDCTL_ABFSTOP;}// temp use bank2 & bank3 (0x8000 ~ 0x9000)#define NVOP_MAX 0x1000static __inline voidnframe_dma(DECODER * dec, uint32_t img_sour, uint32_t img_dest, uint32_t u32length){ uint32_t * dma_cmd_n = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_N_OFF); volatile MDMA * ptDma = (MDMA *)((uint32_t)dec->pu32BaseAddr + DMA_OFF);// #define MDMA1 ((volatile MDMA *)(AHBBASE_DMA1)) // init dma parameter dma_cmd_n[CHN_NVOP_IN + 1] = mDmaLocMemAddr14b(REF_Y_OFF_0); // dont care block width dma_cmd_n[CHN_NVOP_IN + 3] = mDmaIntChainMask1b(TRUE) | mDmaEn1b(TRUE) | mDmaChainEn1b(TRUE) | mDmaDir1b(DMA_DIR_2LOCAL) | mDmaSType2b(DMA_DATA_SEQUENTAIL) | mDmaLType2b(DMA_DATA_SEQUENTAIL) | mDmaLen12b(NVOP_MAX/4); dma_cmd_n[CHN_NVOP_OUT + 1] = mDmaLocMemAddr14b(REF_Y_OFF_0); // dont care block width dma_cmd_n[CHN_NVOP_OUT + 3] = mDmaIntChainMask1b(FALSE) | mDmaEn1b(TRUE) | mDmaChainEn1b(FALSE) | mDmaDir1b(DMA_DIR_2SYS) | mDmaSType2b(DMA_DATA_SEQUENTAIL) | mDmaLType2b(DMA_DATA_SEQUENTAIL) | mDmaLen12b(NVOP_MAX/4); while (u32length) { // indicator mVpe_Indicator(0x93000000 | u32length); dma_cmd_n[CHN_NVOP_IN + 0] = mDmaSysMemAddr29b(img_sour); dma_cmd_n[CHN_NVOP_OUT + 0] = mDmaSysMemAddr29b(img_dest); if (u32length < NVOP_MAX) { dma_cmd_n[CHN_NVOP_IN + 3] = mDmaIntChainMask1b(TRUE) | mDmaEn1b(TRUE) | mDmaChainEn1b(TRUE) | mDmaDir1b(DMA_DIR_2LOCAL) | mDmaSType2b(DMA_DATA_SEQUENTAIL) | mDmaLType2b(DMA_DATA_SEQUENTAIL) | mDmaLen12b(u32length/4); dma_cmd_n[CHN_NVOP_OUT + 3] = mDmaIntChainMask1b(FALSE) | mDmaEn1b(TRUE) | mDmaChainEn1b(FALSE) | mDmaDir1b(DMA_DIR_2SYS) | mDmaSType2b(DMA_DATA_SEQUENTAIL) | mDmaLType2b(DMA_DATA_SEQUENTAIL) | mDmaLen12b(u32length/4); // update transfer length u32length = 0; } else { // update transfer length & image source & destination u32length -= NVOP_MAX; img_sour += NVOP_MAX; img_dest += NVOP_MAX; } ptDma->CCA = (DMA_CMD_N_OFF + CHN_NVOP_IN * 4) | DMA_LC_LOC; // dont care SMaddr // dont care LMaddr // dont care MDMA1->BlkWidth ptDma->Control = mDmaIntChainMask1b(TRUE) | mDmaEn1b(TRUE) | mDmaChainEn1b(TRUE) | mDmaDir1b(DONT_CARE) | mDmaSType2b(DONT_CARE) | mDmaLType2b(DONT_CARE) | mDmaLen12b(0); // wait for dma finish mFa526DrainWrBuf(); while((ptDma->Status & BIT0) == 0) ; }}voiddecoder_nframe(DECODER * dec){ uint32_t u32mb_size; u32mb_size = (dec->output_stride / PIXEL_Y) * dec->output_height; // y nframe_dma(dec, (uint32_t) dec->refn.y_phy, (uint32_t) dec->cur.y_phy, dec->mb_width * dec->mb_height * SIZE_Y); // u nframe_dma(dec, (uint32_t) dec->refn.u_phy, (uint32_t) dec->cur.u_phy, dec->mb_width * dec->mb_height * SIZE_U); // v nframe_dma(dec, (uint32_t) dec->refn.v_phy, (uint32_t) dec->cur.v_phy, dec->mb_width * dec->mb_height * SIZE_V); // display if (dec->output_base_phy != dec->output_base_ref_phy) nframe_dma(dec, (uint32_t) dec->output_base_ref_phy, (uint32_t) dec->output_base_phy, (dec->output_stride * dec->output_height * RGB_PIXEL_SIZE));}// swap two MACROBLOCK arrayvoid mb_swap(MACROBLOCK ** mb1, MACROBLOCK ** mb2){ MACROBLOCK *temp = *mb1; *mb1 = *mb2; *mb2 = temp;}int32_tdecoder_decode(void * ptDecHandle, FMP4_DEC_RESULT * ptResult){ DECODER * dec = (DECODER *)ptDecHandle; MP4_t * ptMP4 = (MP4_t *)((uint32_t)dec->pu32BaseAddr + MP4_OFF); Bitstream bs; uint32_t rounding = 0; uint32_t quant = 0; uint32_t fcode_forward = 0; uint32_t fcode_backward = 0; uint32_t intra_dc_threshold_bit = 0; uint32_t vop_type; uint32_t u32temp; uint32_t u32temp1;// uint32_t bs_phy_address; if (dec->pfnSemWait) dec->pfnSemWait (dec->pvSemaphore); BitstreamInit(&bs, dec->pu8BS_ptr_virt, dec->pu8BS_ptr_phy, dec->u32BS_buf_sz_remain); dec->u32BS_used_byte = 0; dec->frames++; u32temp = dec->width; u32temp1 = dec->height; if ((vop_type = BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold_bit)) == -1) return FARADAY_ERR_FAIL; if ((dec->width > dec->u32MaxWidth) || (dec->height > dec->u32MaxHeight)) return FARADAY_ERR_FAIL; if (dec->output_stride == 0) dec->output_stride = dec->width; if (dec->output_height == 0) dec->output_height = dec->height; if ((u32temp != dec->width) || (u32temp1 != dec->height)) { // reCalculate MB width & height dec->mb_width = (dec->width + 15) / 16; dec->mb_height = (dec->height + 15) / 16; dma_dec_commandq_init(dec); } BitstreamUpdatePos(&bs, NULL, DONT_CARE); { int pp, ii; if (vop_type && (dec->h263 == 0)) pp = NUMBITS_VP_RESYNC_MARKER+fcode_forward-1; else pp = NUMBITS_VP_RESYNC_MARKER; ii = 1<< (32-pp); ptMP4->RSMRK = ii;// bs_phy_address = (uint32_t)dec->pu8BS_ptr_phy + ((uint32_t) bs.tail - (uint32_t) bs.start); // Disable auto-buffering if closed abnormally last time ptMP4->VLDCTL = VLDCTL_ABFSTOP; ptMP4->ASADR = (uint32_t)bs.tail_phy; //bs_phy_address; ptMP4->VADR = RUN_LEVEL_OFF | bs.pos; ptMP4->VOPDM = (dec->mb_width << 20) | (dec->mb_height << 4); ptMP4->VOP0 = (fcode_forward << 20) | (intra_dc_threshold_bit << 16) | (quant << 8) | (vop_type); if (dec->h263 == 1) ptMP4->VOP1 = (3 << 28) | // start code length ((pp - 16) << 24) | // length of resync-marker ((dec->time_inc_bits + 2) << 16) | // length of vop_time_increment code (7 << 12) | // length of macroblock_number code (dec->reversible_vlc << 1) | // RVLC (dec->data_partitioned << 0); else ptMP4->VOP1 = (3 << 28) | // start code length ((pp - 16) << 24) | // length of resync-marker ((dec->time_inc_bits + 2) << 16) | // length of vop_time_increment code // length of macroblock_number code (log2bin(dec->mb_width * dec->mb_height - 1) << 12) | (dec->reversible_vlc << 1) | // RVLC (dec->data_partitioned << 0); } switch (vop_type) { case I_VOP: // data partition: yes or no decoder_iframe(dec, &bs, quant);// bs_phy_address = (uint32_t)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc) - bs_phy_address; BitstreamUpdatePos_phy (&bs, (uint32_t *)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc), ptMP4->VADR & 0x1f);// BitstreamUpdatePos(&bs,// (uint32_t) bs.tail + bs_phy_address,// ptMP4->VADR & 0x1f); break; case P_VOP: // data partition: yes or no decoder_pframe(dec, &bs, rounding, quant, fcode_forward);// bs_phy_address = (uint32_t)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc) - bs_phy_address;// BitstreamUpdatePos(&bs,// (uint32_t) bs.tail + bs_phy_address,// ptMP4->VADR & 0x1f); BitstreamUpdatePos_phy (&bs, (uint32_t *)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc), ptMP4->VADR & 0x1f); break; case N_VOP: // vop not coded decoder_nframe(dec); break; case B_VOP: default: return FARADAY_ERR_FAIL; } if (vop_type == I_VOP || vop_type == P_VOP) { image_swap_dec(&dec->cur, &dec->refn); } dec->output_base_ref_phy = dec->output_base_phy; u32temp = BitstreamPos(&bs) / 8; dec->u32BS_buf_sz_remain -= u32temp; dec->pu8BS_ptr_virt += u32temp; dec->pu8BS_ptr_phy += u32temp; if (dec->pfnSemSignal) dec->pfnSemSignal(dec->pvSemaphore); ptResult->u32VopWidth = dec->width; ptResult->u32VopHeight = dec->height; ptResult->u32UsedBytes = dec->u32BS_used_byte + u32temp; ptResult->pu8FrameBaseAddr_phy = dec->output_base_phy; #if (OUTPUT_FMT == OUTPUT_FMT_YUV) ptResult->pu8FrameBaseAddr_U_phy = dec->output_base_u_phy; ptResult->pu8FrameBaseAddr_V_phy = dec->output_base_v_phy; #endif return FARADAY_ERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -