📄 decoder.c
字号:
(mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_V) |mDmaSysInc3b(DMA_INCS_16); // 2 * PIXEL_V } } } #endif }//(19)preMoveRGB(3S-R)(D)(Conf0)//(19')(Conf1)(3S-x) if (u32pipe & BIT_3ST) { u32pipe &= ~BIT_3ST; #if (OUTPUT_FMT < OUTPUT_FMT_YUV) u32pipe |= BIT_DMA_RGB_GO; // update address of destination // dont forget the next one after the one mb-jumpping // mb_last is the next one after mb_rgb if ((mb_rgb->mb_jump != 0) || (mb_last->mb_jump != 0) || (mbb_rgb->x == u32output_mb_start) || (mbb_rgb->x == (u32output_mb_start + 1))) { if ((mbb_rgb->x >= u32output_mb_start) && (mbb_rgb->x < u32output_mb_end) && (mbb_rgb->y >= u32output_mb_ystart) && (mbb_rgb->y < u32output_mb_yend)) { if (mbb_vld->toggle == 0) dma_cmd_tgl0[CHNI_RGB] = mDmaSysMemAddr29b((uint32_t) dec->output_base_phy + (mbb_rgb->x - u32output_mb_start) * PIXEL_Y * RGB_PIXEL_SIZE + (mbb_rgb->y - u32output_mb_ystart) * dec->output_stride * PIXEL_Y * RGB_PIXEL_SIZE) | mDmaSysInc3b(RGB_DMA_INC); //PIXEL_Y * 2; else dma_cmd_tgl1[CHNI_RGB] = mDmaSysMemAddr29b((uint32_t) dec->output_base_phy + (mbb_rgb->x - u32output_mb_start) * PIXEL_Y * RGB_PIXEL_SIZE + (mbb_rgb->y - u32output_mb_ystart) * dec->output_stride * PIXEL_Y * RGB_PIXEL_SIZE) | mDmaSysInc3b(RGB_DMA_INC); //PIXEL_Y * 2; } } u32grpc &= ~(uint32_t)(3 << (ID_CHN_RGB * 2)); // exec RGB dma if ((u32pipe & BIT_PRE_DT) == 0) u32grpc |= 1 << (ID_CHN_RGB*2); // RGB dma: skip but inscr. #endif }//(6)wait VLD(0S-1S) if (u32pipe & BIT_0ST) { u32pipe &= ~ BIT_0ST; u32pipe |= BIT_1ST; vpe_prob_vld_start(); mFa526DrainWrBuf(); while (((u32temp = ptMP4->VLDSTS) & BIT0) == 0) ; vpe_prob_vld_end(); // check error code if (u32temp & 0xF000) { mVpe_Indicator(0x92000000 | (u32temp & 0xF000)); mVpe_FAIL(); //waitDMC & waitDT while ((ptMP4->CPSTS & (BIT14 | BIT1)) != (BIT14 | BIT1)) ; u32temp = FindRsmkOrVopS(bs, ptMP4); break; } // Resync marker detected if (u32temp & BIT1) { if (bRead_video_packet_header(dec, NULL, NULL, &bound) == -1) { mVpe_FAIL(); break; } if (bound != mbb_dmc->mbpos) { // correct 'dmc'ed(img) jump to correct next-'dmc'ed(dmc) mb_img->mb_jump = bound - mbb_dmc->mbpos; // correct 'vld'ed(dmc) information mb_dmc = &dec->mbs[bound]; mb_dmc->mb_jump = 0; mbb_dmc->x = bound % dec->mb_width; mbb_dmc->y = (int32_t)(bound / dec->mb_width); mbb_dmc->mbpos = bound; // correct store acdc pointer // dont care about 'load preditor', it will not be used until next line is reached if (mbb_vld->toggle == 0) { dma_cmd_tgl0[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * mbb_vld->x) | mDmaSysInc3b(DMA_INCS_128); dma_cmd_tgl1[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * (mbb_vld->x + 1)) | mDmaSysInc3b(DMA_INCS_128); } else { dma_cmd_tgl1[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * mbb_vld->x) | mDmaSysInc3b(DMA_INCS_128); dma_cmd_tgl0[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * (mbb_vld->x + 1)) | mDmaSysInc3b(DMA_INCS_128); } } mb_cnt_in_vp = (u32temp >> 16) - 1; //pu32table = &Table_Output[4]; pu32table = &((uint32_t *)((uint32_t) dec->pu32BaseAddr + TABLE_OUTPUT_OFF))[4]; } mbb_dmc->cbp = (*pu32table >> 23) & 0x3F; mbb_dmc->quant = (ptMP4->VOP0 >> 8) & 0xFF; if (dec->data_partitioned) pu32table += 4; } mbb_vld->mbpos = mbb_dmc->mbpos + 1; mbb_vld->x = mbb_dmc->x + 1; mbb_vld->y = mbb_dmc->y; if (mbb_vld->x == dec->mb_width) { mbb_vld->x = 0; mbb_vld->y ++; } // indicator mVpe_Indicator(0x91000000 | (mbb_vld->y << 12) | mbb_vld->x);//(1)preVLD(x-0S) if (mbb_vld->y < dec->mb_height) { u32pipe |= BIT_0ST; // init mb_vld mb_vld = &dec->mbs[mbb_vld->mbpos]; mb_vld->mb_jump = 0; // get acdcPredict command parameter u32cmd_mc = predict_acdc_I(mbb_vld, (int32_t)dec->mb_width, bound); u32cmd_mc |= u32cmd_mc_reload; } else u32cmd_mc = u32cmd_mc_reload;//(7)preStoreACDC//(2)preLoadACDC if ((mb_img->mb_jump != 0) || (mb_dmc->mb_jump != 0) ||(mbb_vld->x == 0)) { if (mbb_vld->toggle == 0) { dma_cmd_tgl0[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy) | mDmaSysInc3b(DMA_INCS_128); dma_cmd_tgl0[CHNI_LOAD_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64) | mDmaSysInc3b(DMA_INCS_128); }else { dma_cmd_tgl1[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy) | mDmaSysInc3b(DMA_INCS_128); dma_cmd_tgl1[CHNI_LOAD_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64) | mDmaSysInc3b(DMA_INCS_128); } } else if (mbb_vld->x == 1) { if (mbb_vld->toggle == 0) dma_cmd_tgl0[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64) | mDmaSysInc3b(DMA_INCS_128); else dma_cmd_tgl1[CHNI_STORE_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64) | mDmaSysInc3b(DMA_INCS_128); } if (mbb_vld->x == (dec->mb_width - 1)) { if (mbb_vld->toggle == 0) dma_cmd_tgl0[CHNI_LOAD_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy) | mDmaSysInc3b(DMA_INCS_128); else dma_cmd_tgl1[CHNI_LOAD_PREDITOR] = mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy) | mDmaSysInc3b(DMA_INCS_128); }//(7)waitDMA_load--(13)waitDMA_store----------------(20)waitDMA_img-(24)waitDMA_RGB(Conf0)// |-------(21)waitDMA_yuv(Conf1) vpe_prob_dma_start(); mFa526DrainWrBuf(); while((ptDma->Status & BIT0) == 0) ; vpe_prob_dma_end();//(22)waitDT(D-x)(Conf0) #if (OUTPUT_FMT < OUTPUT_FMT_YUV) if (u32pipe & BIT_PRE_DT) { u32pipe &= ~BIT_PRE_DT; vpe_prob_dt_start(); mFa526DrainWrBuf(); while((ptMP4->CPSTS & BIT14) == 0) ; vpe_prob_dt_end(); }//(14)prDT(2S-D)(Conf0) if (u32pipe & BIT_2ST) { 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)) { 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//(15) wait DMC(2S-3S) if (u32pipe & BIT_2ST) { u32pipe &= ~BIT_2ST; u32pipe |= BIT_3ST; vpe_prob_dmc_start(); mFa526DrainWrBuf(); while ((ptMP4->CPSTS & BIT1) == 0) ; vpe_prob_dmc_end(); }//(8)preDMC(1S) if (u32pipe & BIT_1ST) { if (mbb_dmc->toggle) // dmc_input(& output) direct to INTER_Y_OFF_1 ptMP4->MCIADDR = INTER_Y_OFF_1; else // dmc_input(& output) direct to INTER_Y_OFF_0 ptMP4->MCIADDR = INTER_Y_OFF_0; u32cmd_mc |= MCCTL_DMCGO; // fill CBP in this stage ptMP4->QCR0 = (mbb_dmc->quant << 18) | mbb_dmc->cbp; } if (u32pipe == 0) break; } for (; (ptMP4->VLDSTS & BIT10)==0; ) ; /// wait for autobuffer clean // stop auto-buffering ptMP4->VLDCTL = VLDCTL_ABFSTOP;}//R: BIT_DMA_RGB_GO/* <- mb_vld -><- mb_ref -><- mb_dmc -><- mb_img -><- mb_rgb -><- 0st -><- 1st stage -><- 2nd stage -><- 3nd stage -><- 4nd stage -><- 5nd stage ->----------------------------cycle start -------------------------------------------------- (3)goMC_vld-----------------(15)goMC_dmc--(23)goMC_dt (4)goDMA_LD_ST-(12)goDMA_ref---------------(24)goDMA_img-(30)goDMA_rgb(R-x)(Conf0) |----(25)goDMA_yuv(Conf1) (16)prePXI(3S) (5)goME_pmv----------------(17)goME_pxi************************************************************************** change to next mb * (18)preMoveImg(3S) (19)preMoveYuv(3S)(Conf1) (26)preMoveRGB(4S-R)(D)(Conf0) (26')Conf1(4S-x) (6)waitME_PMV(0S) (7)storeMV(0S) (8)preMoveRef(0S-1S)(1)preVLD(x-0S) (9)preStoreACDC(2)preLoadACDC (20)waitDMC(3S-4S) (13)preDMC(2S-3S) (27)waitDT(D-x)(Conf0) (21)preDT(4S)(x-D)(Conf0) (10)waitVLD(1S-2S) (22)waitME_pxi(4S) (11)waitDMA_LD_ST-(14)waitDMA_ref------------(28)waitDMA_img--(31)waitDMA_rgb(Conf0) |-----(29)waitDMA_yuv(Conf1)----------------------------cycle end --------------------------------------------------*/#define P_FRAME_PIPE 5voiddecoder_pframe(DECODER * dec, Bitstream * bs, int rounding, int quant, int fcode){ 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); uint32_t u32temp; uint32_t u32pipe = 0; uint32_t u32cmd_mc = 0; uint32_t u32cmd_mc_reload = 0; uint32_t u32cmd_me = 0; uint32_t mb_cnt_in_vp = 0; // MB count in video packet uint32_t mbpos_in_vp = 0; // MB pos in video packet// uint32_t * pu32table = &Table_Output[4];// table pointer in video packet uint32_t * pu32table = &((uint32_t *)((uint32_t) dec->pu32BaseAddr + TABLE_OUTPUT_OFF))[4]; int32_t i; int32_t bound = 0; uint32_t u32ErrorCount = 0; uint32_t u32grpc; MACROBLOCK_b mbb[P_FRAME_PIPE]; MACROBLOCK_b *mbb_vld = &mbb[P_FRAME_PIPE - 1]; MACROBLOCK_b *mbb_ref=0; MACROBLOCK_b *mbb_dmc=0; MACROBLOCK_b *mbb_img=0; MACROBLOCK_b *mbb_rgb=0; MACROBLOCK *mb_vld; MACROBLOCK *mb_ref; MACROBLOCK *mb_dmc; MACROBLOCK *mb_img; MACROBLOCK *mb_rgb; MACROBLOCK *mb_last; 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; // reset PMV counter ptMP4->MECTL = MECTL_VOPSTART; // init mc & me command if (dec->quant_type == MPEG4_QUANT) u32cmd_mc_reload = MCCTL_MP4Q; if (dec->h263 == 1) u32cmd_mc_reload |= MCCTL_SVH; dma_chain_init_p(dec); ptDma->GRPS = 0; // the last command in the chain never skipped. u32grpc = (2 << (ID_CHN_1MV*2)) // disable 1mv |(2 << (ID_CHN_4MV*2)) // disable 4mv |(2 << (ID_CHN_IMG*2)) // disable IMG #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)); // LdSt_ACDC sync to VLD_done // load & store non-meaning mb_vld = mb_ref = 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-----------------(15)goMC_dmc--(23)goMC_dt if (u32cmd_mc & (MCCTL_DECGO | MCCTL_DMCGO | MCCTL_DTGO)) ptMP4->MCCTL = u32cmd_mc;//(4)goDMA_LD_ST-(12)goDMA_ref---------------(24)goDMA_img-(30)goDMA_rgb(Conf0)// |--(25)goDMA_yuv(Conf1) { u32pipe &= ~BIT_DMA_RGB_GO; ptDma->GRPC = u32grpc; if (mb_ref->mode == MODE_INTER4V) { if (mbb_vld->toggle == 0) ptDma->CCA = (DMA_CMD_OFF_0 + CHNP_REF_4MV_Y0 * 4) | DMA_LC_LOC; else ptDma->CCA = (DMA_CMD_OFF_1 + CHNP_REF_4MV_Y0 * 4) | DMA_LC_LOC; } else { if (mbb_vld->toggle == 0) ptDma->CCA = (DMA_CMD_OFF_0 + CHNP_REF_1MV_Y * 4) | DMA_LC_LOC; else ptDma->CCA = (DMA_CMD_OFF_1 + CHNP_REF_1MV_Y * 4) | DMA_LC_LOC; } // dont care SMaddr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -