📄 decoder.c
字号:
refy); } } refx = (x * PIXEL_U * 2 + uv_dx) / 2; // unit: 1 pixel refy = (y * PIXEL_U * 2 + uv_dy) / 2; // unit: 1 pixel transfer8x8_copy_ben(dec, mbpos * SIZE_U, dec->cur.u_virt, dec->refn.u_virt, refx, refy); transfer8x8_copy_ben(dec, mbpos * SIZE_U, dec->cur.v_virt, dec->refn.v_virt, refx, refy); mbpos ++; x ++; if (x == dec->mb_width) { x = 0; y ++; } }}static __inline uint32_tFindRsmkOrVopS(Bitstream * const bs, volatile MP4_t * ptMP4){ uint32_t u32temp; while (1) { // MPEG4 search re-sync marker before decoding u32temp = ptMP4->VLDCTL & ~0x000F; ptMP4->VLDCTL = u32temp | mVLDCTL_CMD4b(2); ptMP4->MCCTL |= MCCTL_DECGO; mFa526DrainWrBuf(); while (((u32temp = ptMP4->VLDSTS) & BIT0) == 0) ; if ((u32temp & 0xF000) == 0xE000) { // timeout for (; (ptMP4->VLDSTS & BIT10)==0; ) ; /// wait for autobuffer clean BitstreamUpdatePos_phy(bs, (uint32_t *)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc), ptMP4->VADR & 0x1f);// BitstreamUpdatePos(bs,// (uint32_t *)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc),// ptMP4->VADR & 0x1f); if ((BitstreamPos(bs) >> 3) >= bs->length) { // nothing found u32temp = BIT2; break; } } else break; } return u32temp;}static __inline voiddma_chain_init_i(DECODER * dec){ uint32_t * dma_cmd_tgl0 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_0); uint32_t * dma_cmd_tgl1 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_1); // for the 1st time dma trigger, use tgl_1 dma chain, // fill these 2 register to avoid the dma register unknow dma_cmd_tgl1[CHNI_STORE_PREDITOR] = dma_cmd_tgl1[CHNI_LOAD_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy) | mDmaSysInc3b(DMA_INCS_128); // tgl 0 dma_cmd_tgl0[CHNI_IMG_U] = mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U dma_cmd_tgl0[CHNI_IMG_V] = mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U // tgl 1 dma_cmd_tgl1[CHNI_IMG_U] = mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy+ 64) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U dma_cmd_tgl1[CHNI_IMG_V] = mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy+ 64) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U}static __inline voiddma_chain_init_p(DECODER * dec){ uint32_t * dma_cmd_tgl0 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_0); uint32_t * dma_cmd_tgl1 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_1); // for the 1st time dma trigger, use tgl_1 dma chain, // fill these 2 register to avoid the dma register unknow dma_cmd_tgl1[CHNP_STORE_PREDITOR] = dma_cmd_tgl1[CHNP_LOAD_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy) | mDmaSysInc3b(DMA_INCS_128); // tgl 0 dma_cmd_tgl0[CHNP_IMG_U] = mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy + 64) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U dma_cmd_tgl0[CHNP_IMG_V] = mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy + 64) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U // tgl 1 dma_cmd_tgl1[CHNP_IMG_U] = mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U dma_cmd_tgl1[CHNP_IMG_V] = mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U}#define BIT_0ST BIT0#define BIT_1ST BIT1#define BIT_2ST BIT2#define BIT_3ST BIT3#define BIT_4ST BIT4#define BIT_5ST BIT5#define BIT_DMA_RGB_GO BIT8#define BIT_PRE_DT BIT9// Conf0: configure output as RGB or CbYCrY// Conf1: configure output as YUV420/* <- mb_vld -><- mb_dmc -><- mb_img -><- mb_rgb -><-00st stage -><- 1st stage -><- 2nd stage -><- 3nd stage -><- 4nd stage ->----------------------------cycle start ----------------------------------------------- (3)goMC_vld------(9)goMC_dmc-----(16)goMC_dt (4)goDMA_LD-----(10)goDMA_ST-----(17)goDMA_img--(23)goDMA_ RGB(R-x)(Conf0) |---(18)goDMA_yuv(Conf1)~~change to next mb~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (11)preMoveImg(1S-2S) (12)preMoveYuv(1S-2S)(Conf1) (19)preMoveRGB(3S-R)(D)(Conf0) (19')(Conf1)(3S-x) (5)wait VLD(0S-1S)(1)preVLD(x-0S) (6)preStoreACDC(2)preLoadACDC (7)waitDMA_LD----(13)waitDMA_ST---(20)waitDMA_img---(24)waitDMA_RGB(Conf0) |---(21)waitDMA_yuv(Conf1) (22)waitDT(D-x)(Conf0) (14)prDT(2S)(x-D)(Conf0) (15)wait DMC(2S-3S) (8)preDMC(1S)----------------------------cycle end --------------------------------------------------*/#define I_FRAME_PIPE 4voiddecoder_iframe(DECODER * dec, Bitstream * bs, int quant){ volatile MP4_t * ptMP4 = (MP4_t *)((uint32_t)dec->pu32BaseAddr + MP4_OFF); volatile MDMA * ptDma = (MDMA *)((uint32_t)dec->pu32BaseAddr + DMA_OFF); uint32_t * dma_cmd_tgl0 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_0); uint32_t * dma_cmd_tgl1 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_1); int32_t bound = 0; int32_t i; uint32_t u32temp; uint32_t u32cmd_mc; uint32_t u32pipe = 0; uint32_t u32cmd_mc_reload; uint32_t mb_cnt_in_vp = 0; // MB count in video packet// uint32_t * pu32table = &Table_Output[4]; uint32_t * pu32table = &((uint32_t *)((uint32_t) dec->pu32BaseAddr + TABLE_OUTPUT_OFF))[4]; uint32_t u32grpc; MACROBLOCK *mb_vld; MACROBLOCK *mb_dmc; MACROBLOCK *mb_img; MACROBLOCK *mb_rgb; MACROBLOCK *mb_last; MACROBLOCK_b mbb[I_FRAME_PIPE]; MACROBLOCK_b *mbb_vld = &mbb[I_FRAME_PIPE - 1]; MACROBLOCK_b *mbb_dmc=0; MACROBLOCK_b *mbb_img=0; MACROBLOCK_b *mbb_rgb=0; uint32_t u32output_mb_end=0; uint32_t u32output_mb_start = 0; uint32_t u32output_mb_yend=0; uint32_t u32output_mb_ystart = 0; if (dec->output_base_phy == NULL) // goDT & moveRGB never start u32output_mb_start = 0xFFFFFFFF; else { // width if (dec->width >= dec->output_stride) { u32temp = dec->mb_width - (dec->output_stride / PIXEL_Y); // width diff between screan and VOP u32output_mb_start = u32temp / 2; u32output_mb_end = (dec->output_stride / PIXEL_Y) + u32output_mb_start; } else u32output_mb_end = dec->width / PIXEL_Y; // height if (dec->height >= dec->output_height) { u32temp = dec->mb_height - (dec->height / PIXEL_Y); // height diff between screan and VOP u32output_mb_ystart = u32temp / 2; u32output_mb_yend = (dec->height / PIXEL_Y) + u32output_mb_ystart; } else u32output_mb_yend = dec->height / PIXEL_Y; } /////////////////////////////////////////////////////////////////////////// // Enable auto-buffering ptMP4->VLDCTL = VLDCTL_ABFSTART; u32cmd_mc_reload = MCCTL_INTRA; if (dec->quant_type == MPEG4_QUANT) u32cmd_mc_reload = MCCTL_MP4Q | MCCTL_INTRA; if (dec->h263 == 1) u32cmd_mc_reload |= MCCTL_SVH; u32cmd_mc = u32cmd_mc_reload; dma_chain_init_i(dec); ptDma->GRPS = 0; // the last command in the chain never skipped. u32grpc = (2 << (ID_CHN_1MV*2)) // 1mv dma: disable |(2 << (ID_CHN_4MV*2)) // 4mv dma: disable |(2 << (ID_CHN_IMG*2)) // IMG dma: disable #if (OUTPUT_FMT == OUTPUT_FMT_YUV) |(2 << (ID_CHN_YUV*2)) // YUV dma: disable. #else |(2 << (ID_CHN_RGB*2)) // RGB dma: disable. #endif |(3 << (ID_CHN_ACDC*2)); // St_ACDC dma: sync to VLD_done // Ld_ACDC dma: sync to VLD_done mb_vld = mb_dmc = mb_img = mb_rgb = mb_last = &dec->mbs[0]; mb_vld->mb_jump = 0; mbb_vld->mbpos = -1; mbb_vld->x = -1; mbb_vld->y = 0; mbb_vld->toggle = 1; i = -1; while (1) {//(3)goMC_vld-------(9)goMC_dmc--(16)goMC_dt if (u32cmd_mc & (MCCTL_DECGO | MCCTL_DMCGO | MCCTL_DTGO)) { // swap 2 buffer // setup Dezigzag-scan output address and dequant input address // VLD output to DZQ[31..16] DZQ[15..0] is input of DMC if (i & BIT0) ptMP4->QAR = ((QCOEFF_OFF_1 & 0xFFFF) << 16) | (QCOEFF_OFF_2 & 0xFFFF); else ptMP4->QAR = ((QCOEFF_OFF_2 & 0xFFFF) << 16) | (QCOEFF_OFF_1 & 0xFFFF); ptMP4->MCCTL = u32cmd_mc; }//(4)goDMA_LD-----(10)goDMA_ST-----(17)goDMA_img--(23)goDMA_ RGB(R-x)(Conf0)// |-----(18)goDMA_yuv(Conf1) { u32pipe &= ~BIT_DMA_RGB_GO; ptDma->GRPC = u32grpc; if (mbb_vld->toggle == 0) ptDma->CCA = (DMA_CMD_OFF_0 + CHNI_IMG_Y * 4) | DMA_LC_LOC; else ptDma->CCA = (DMA_CMD_OFF_1 + CHNI_IMG_Y * 4) | DMA_LC_LOC; // dont care SMaddr // dont care LMaddr // dont care BlkWidth ptDma->Control = mDmaIntChainMask1b(TRUE) | mDmaEn1b(TRUE) | mDmaChainEn1b(TRUE) | mDmaDir1b(DONT_CARE) | mDmaSType2b(DONT_CARE) | mDmaLType2b(DONT_CARE) | mDmaLen12b(0) | mDmaID4b(0); } u32grpc = (2 << (ID_CHN_1MV*2)) // 1mv dma: disable |(2 << (ID_CHN_4MV*2)) // 4mv dma: disable |(2 << (ID_CHN_IMG*2)) // IMG dma: disable #if (OUTPUT_FMT == OUTPUT_FMT_YUV) |(2 << (ID_CHN_YUV*2)) // YUV dma: disable. #else |(2 << (ID_CHN_RGB*2)) // RGB dma: disable. #endif |(3 << (ID_CHN_ACDC*2)); // St_ACDC dma: sync to VLD_done // Ld_ACDC dma: sync to VLD_done//~~change to next mb~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /////////////////////////////////////////////////////////////////////////// // update mb pointer i ++; mbb_rgb = mbb_img; mbb_img = mbb_dmc; mbb_dmc = mbb_vld; mbb_vld = &mbb[i%I_FRAME_PIPE]; mbb_vld->toggle = i & BIT0; mb_last = mb_rgb; mb_rgb = mb_img; mb_img = mb_dmc; mb_dmc = mb_vld;//(11)preMoveImg(1S-2S)//(12)preMoveYuv(1S-2S)(Conf1) if (u32pipe & BIT_1ST) { u32pipe &= ~BIT_1ST; u32pipe |= BIT_2ST; u32grpc &= ~(uint32_t)(3 << (ID_CHN_IMG * 2)); // exec IMG dma // update address of destination // dont forget to update the next one after the one mb-jumpping(dma ping-pong chain) // mb_rgb is the next one after mb_img if ((mb_img->mb_jump != 0) || (mb_rgb->mb_jump != 0)) { if (mbb_vld->toggle == 0) { // y dma_cmd_tgl0[CHNI_IMG_Y] = mDmaSysMemAddr29b((uint32_t) dec->cur.y_phy + (uint32_t)mbb_img->x * 2 * SIZE_U + (uint32_t)mbb_img->y * dec->mb_width * SIZE_Y) |mDmaSysInc3b(DMA_INCS_256); // 2 * SIZE_U // u dma_cmd_tgl0[CHNI_IMG_U] = mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy + (uint32_t)mbb_img->mbpos * SIZE_U) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U // v dma_cmd_tgl0[CHNI_IMG_V] = mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy + (uint32_t)mbb_img->mbpos * SIZE_V) |mDmaSysInc3b(DMA_INCS_128); // SIZE_V } else { // y dma_cmd_tgl1[CHNI_IMG_Y] = mDmaSysMemAddr29b((uint32_t) dec->cur.y_phy + (uint32_t)mbb_img->x * 2 * SIZE_U + (uint32_t)mbb_img->y * dec->mb_width * SIZE_Y) |mDmaSysInc3b(DMA_INCS_256); // 2 * SIZE_U // u dma_cmd_tgl1[CHNI_IMG_U] = mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy + (uint32_t)mbb_img->mbpos * SIZE_U) |mDmaSysInc3b(DMA_INCS_128); // SIZE_U // v dma_cmd_tgl1[CHNI_IMG_V] = mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy + (uint32_t)mbb_img->mbpos * SIZE_V) |mDmaSysInc3b(DMA_INCS_128); // SIZE_V } } else if ((mbb_img->x == 0) || (mbb_img->x == 1)) { u32temp = mDmaSysMemAddr29b((uint32_t) dec->cur.y_phy + (uint32_t) mbb_img->mbpos * SIZE_Y - (uint32_t) mbb_img->x * 2 * SIZE_U) |mDmaSysInc3b(DMA_INCS_256); // 2 * SIZE_U if (mbb_vld->toggle == 0) dma_cmd_tgl0[CHNI_IMG_Y] = u32temp; else dma_cmd_tgl1[CHNI_IMG_Y] = u32temp; } #if (OUTPUT_FMT == OUTPUT_FMT_YUV) 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)) { u32grpc &= ~(uint32_t)(3 << (ID_CHN_YUV * 2)); // exec YUV dma if (((mb_img->mb_jump != 0) || (mb_rgb->mb_jump != 0)) || (mbb_img->x == u32output_mb_start) || (mbb_img->x == (u32output_mb_start + 1))) { if (mbb_vld->toggle == 0) { // y output dma_cmd_tgl0[CHNI_YUV_Y] = mDmaSysMemAddr29b((uint32_t) dec->output_base_phy + ((mbb_img->x - u32output_mb_start) + (mbb_img->y - u32output_mb_ystart) * dec->output_stride) * PIXEL_Y) |mDmaSysInc3b(DMA_INCS_32); // 2 * PIXEL_Y // u output dma_cmd_tgl0[CHNI_YUV_U] = mDmaSysMemAddr29b((uint32_t) dec->output_base_u_phy + ((mbb_img->x - u32output_mb_start)+ (mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_U) |mDmaSysInc3b(DMA_INCS_16); // 2 * PIXEL_U // v output dma_cmd_tgl0[CHNI_YUV_V] = mDmaSysMemAddr29b((uint32_t) dec->output_base_v_phy + ((mbb_img->x - u32output_mb_start) + (mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_V) |mDmaSysInc3b(DMA_INCS_16); // 2 * PIXEL_V } else { // y output dma_cmd_tgl1[CHNI_YUV_Y] = mDmaSysMemAddr29b((uint32_t) dec->output_base_phy + ((mbb_img->x - u32output_mb_start)+ (mbb_img->y - u32output_mb_ystart) * dec->output_stride) * PIXEL_Y) |mDmaSysInc3b(DMA_INCS_32); // 2 * PIXEL_Y // u output dma_cmd_tgl1[CHNI_YUV_U] = mDmaSysMemAddr29b((uint32_t) dec->output_base_u_phy + ((mbb_img->x - u32output_mb_start)+ (mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_U ) |mDmaSysInc3b(DMA_INCS_16); // 2 * PIXEL_U // v output dma_cmd_tgl1[CHNI_YUV_V] = mDmaSysMemAddr29b((uint32_t) dec->output_base_v_phy + ((mbb_img->x - u32output_mb_start)+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -