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

📄 decoder.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
			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 + -