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

📄 decoder.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
#define LOCAL_MEM_GLOBAL#include "../fmpeg4_driver/fmpeg4.h"#include "define.h"#include "mp4vdec.h"#include "portab.h"#include "dma.h"#include "dma_b.h"#include "mp4.h"#include "vpe_m.h"#include "dma_m.h"#include "me.h"#include "decoder.h"#include "bitstream/bitstream.h"#include "image/image.h"//#include "utils/mem_align.h"#include "local_mem.h"#include "prediction/mbprediction.h"#include "utils/mem_transfer1.h"#ifndef TEST_BY_PATTERN_FILEextern uint32_t yuv0_y[];extern uint32_t yuv0_u[];extern uint32_t yuv0_v[];extern uint32_t output0[];#endif#if 0#define DC_MARKER		0x6B001#define MOTION_MARKER	0x1F001#define SCALEBITS		17#define FIX(X)			((1L << SCALEBITS) / (X) + 1)#define VM18P    		3#define VM18Q    		4const uint16_t div_array[48] = {    1,     1,     1, 43691, 32768, 26215, 21846, 18725, 16384, 14564,13108, 11916, 10923, 10083,  9363,  8739,  8192,  7711,  7282,  6899, 6554,  6242,  5958,  5699,  5462,  5243,  5042,  4855,  4682,  4520, 4370,  4229,  4096,  3972,  3856,  3745,  3641,  3543,  3450,  3361, 3277,  3197,  3121,  3048,  2979,  2913,  2850,  2789};const uint32_t multipliers[32] = {	0, FIX(2), FIX(4), FIX(6),	FIX(8), FIX(10), FIX(12), FIX(14),	FIX(16), FIX(18), FIX(20), FIX(22),	FIX(24), FIX(26), FIX(28), FIX(30),	FIX(32), FIX(34), FIX(36), FIX(38),	FIX(40), FIX(42), FIX(44), FIX(46),	FIX(48), FIX(50), FIX(52), FIX(54),	FIX(56), FIX(58), FIX(60), FIX(62)};extern int old_time_incre;#endifextern voidtest_y_mb(DECODER * dec, int x, int y);static uint32_t __inlinelog2bin(uint32_t value){/* Changed by Chenm001 */	int n = 0;	while (value) {		value >>= 1;		n++;	}	return n;}static __inline voidmpeg_init(uint32_t * base){	MP4_t * ptMP4 = (MP4_t *)((uint32_t)base  + MP4_OFF);	ptMP4->CKR = 0;	ptMP4->QAR = 0;	ptMP4->MEIADDR = 0;//	ptMP4->CMDADDR = 0;	ptMP4->MECADDR = 0;	ptMP4->MCCADDR = 0;//	ptMP4->ACDCPAR = 0;	ptMP4->VADR = 0;	ptMP4->BITDATA = 0;	ptMP4->BITLEN = 0;	ptMP4->MCIADDR = 0;	ptMP4->VLDSTS = 0;	ptMP4->SCODE = VOP_START_CODE;	ptMP4->TOADR = TABLE_OUTPUT_OFF;	ptMP4->HOFFSET = 0;	ptMP4->ACDCPAR = PREDICTOR0_OFF;//	ptMP4->CMDADDR = (uint32_t)base + ME_CMD_Q_OFF;	ptMP4->CMDADDR = ME_CMD_Q_OFF;	ptMP4->PMVADDR = PMV_BUFFER_OFF;#if (OUTPUT_FMT <	OUTPUT_FMT_YUV)	ptMP4->DTOFMT = OUTPUT_FMT;#endif	me_dec_commandq_init(base);}int32_tdecoder_create(FMP4_DEC_PARAM * ptParam, void ** pptDecHandle){	DECODER *dec;	uint32_t max_mb_width;	uint32_t max_mb_height;	if(ptParam->u32API_version != API_VERSION)		return FARADAY_ERR_API;	//dec = malloc_align(sizeof(DECODER), ptParam->u32CacheAlign, ptParam->u32CacheAlign);	dec = kmalloc(sizeof(DECODER),GFP_KERNEL|GFP_ATOMIC);	if (dec == NULL) {		return FARADAY_ERR_MEMORY;	}	*pptDecHandle = dec;	dec->pu32BaseAddr = ptParam->pu32BaseAddr;	dec->pvSemaphore = ptParam->pvSemaphore;	dec->u32MaxWidth = ptParam->u32MaxWidth;	dec->u32MaxHeight = ptParam->u32MaxHeight;	dec->u32BS_buf_sz = ptParam->u32BSBufSize;	dec->output_base_phy = ptParam->pu8FrameBaseAddr_phy;	#if (OUTPUT_FMT == OUTPUT_FMT_YUV)	dec->output_base_u_phy = ptParam->pu8FrameBaseAddr_U_phy;	dec->output_base_v_phy = ptParam->pu8FrameBaseAddr_V_phy;	#endif	dec->output_stride = ptParam->u32FrameWidth;	dec->output_height= ptParam->u32FrameHeight;	dec->u32CacheAlign = ptParam->u32CacheAlign;	dec->pfnDmaMalloc = ptParam->pfnDmaMalloc;	dec->pfnDmaFree = ptParam->pfnDmaFree;	dec->pfnSemWait = ptParam->pfnSemWait;	dec->pfnSemSignal = ptParam->pfnSemSignal;	dec->pfnRequestBS = ptParam->pfnRequestBS;	// Memory for encoded mp4 stream//	dec->pu8BS_start = malloc_align(ptParam->u32BSBufSize, ptParam->u32CacheAlign, ptParam->u32CacheAlign);#if 1 //ivan    dec->pu8BS_start_virt=(unsigned char *)fmpeg4_mempool_alloc(dec->u32BS_buf_sz,(unsigned int *)&dec->pu8BS_start_phy);#else	dec->pu8BS_start_virt = dec->pfnDmaMalloc(							dec->u32BS_buf_sz,							dec->u32CacheAlign,							dec->u32CacheAlign,							(void **)&dec->pu8BS_start_phy);#endif	if (dec->pu8BS_start_virt == NULL) {		//free_align(dec);		kfree(dec);		return FARADAY_ERR_MEMORY;	}	dec->pu8BS_ptr_virt = dec->pu8BS_start_virt;	dec->pu8BS_ptr_phy = dec->pu8BS_start_phy;	dec->u32BS_buf_sz_remain = 0;	dec->bBS_end_of_data = FALSE;	max_mb_width = (dec->u32MaxWidth + 15) / 16;	max_mb_height = (dec->u32MaxHeight + 15) / 16;//	old_time_incre = -1;	// initial AC/DC prediction buffer	// 1 MB includes 4 blocks(Y2, Y3, U, V), 16 bytes for each block#if 1    dec->pu16ACDC_ptr_virt=(unsigned short *)fmpeg4_mempool_alloc(max_mb_width*4*16,(unsigned int *)&dec->pu16ACDC_ptr_phy);#else	dec->pu16ACDC_ptr_virt = dec->pfnDmaMalloc(								max_mb_width * 4 * 16,								dec->u32CacheAlign,								dec->u32CacheAlign,								(void **)&dec->pu16ACDC_ptr_phy);#endif	if (dec->pu16ACDC_ptr_virt == NULL) {		//free_align(dec);		kfree(dec);#if 1        fmpeg4_mempool_free((unsigned int)dec->pu8BS_start_virt,dec->u32BS_buf_sz);#else		dec->pfnDmaFree(dec->pu8BS_start_virt, dec->pu8BS_ptr_phy);#endif		return FARADAY_ERR_MEMORY;	}	dec->data_partitioned=0;	dec->h263 = 0;	dec->reversible_vlc = 0;	dec->interlacing = 0;	dec->time_inc_bits = 0;#if 0	dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;	dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;#endif	dec->low_delay = 0;	if (image_create(&dec->cur, max_mb_width, max_mb_height, dec)) {		//free_align(dec);		kfree(dec);#if 1        fmpeg4_mempool_free((unsigned int)dec->pu8BS_start_virt,dec->u32BS_buf_sz);        fmpeg4_mempool_free((unsigned int)dec->pu16ACDC_ptr_virt,max_mb_width*4*16);#else		dec->pfnDmaFree(dec->pu8BS_start_virt, dec->pu8BS_ptr_phy);		dec->pfnDmaFree(dec->pu16ACDC_ptr_virt, dec->pu16ACDC_ptr_phy);#endif		return FARADAY_ERR_MEMORY;	}	if (image_create(&dec->refn, max_mb_width, max_mb_height, dec)) {		//free_align(dec);		kfree(dec);#if 1        fmpeg4_mempool_free((unsigned int)dec->pu8BS_start_virt,dec->u32BS_buf_sz);        fmpeg4_mempool_free((unsigned int)dec->pu16ACDC_ptr_virt,max_mb_width*4*16);#else		dec->pfnDmaFree(dec->pu8BS_start_virt, dec->pu8BS_ptr_phy);		dec->pfnDmaFree(dec->pu16ACDC_ptr_virt, dec->pu16ACDC_ptr_phy);#endif		image_destroy(&dec->cur, max_mb_width, dec);		return FARADAY_ERR_MEMORY;	}	dec->output_base_ref_phy = NULL;	//dec->mbs = malloc_align(sizeof(MACROBLOCK) * max_mb_width * max_mb_height,dec->u32CacheAlign, dec->u32CacheAlign);	dec->mbs = kmalloc(sizeof(MACROBLOCK) * max_mb_width * max_mb_height, GFP_ATOMIC|GFP_KERNEL);		if (dec->mbs == NULL) {		//free_align(dec);		kfree(dec);#if 1        fmpeg4_mempool_free((unsigned int)dec->pu8BS_start_virt,dec->u32BS_buf_sz);        fmpeg4_mempool_free((unsigned int)dec->pu16ACDC_ptr_virt,max_mb_width*4*16);#else		dec->pfnDmaFree(dec->pu8BS_start_virt, dec->pu8BS_ptr_phy);		dec->pfnDmaFree(dec->pu16ACDC_ptr_virt, dec->pu16ACDC_ptr_phy);#endif		image_destroy(&dec->cur, max_mb_width, dec);		image_destroy(&dec->refn, max_mb_width, dec);		return FARADAY_ERR_MEMORY;	}	dec->frames = -1;	dec->time = dec->time_base = dec->last_time_base = 0;	// for auto set used	dec->width = 0;	dec->height = 0;	mpeg_init(dec->pu32BaseAddr);	return FARADAY_ERR_OK;}voiddecoder_destroy(void * ptDecHandle){	DECODER * dec = (DECODER *)ptDecHandle;	uint32_t max_mb_width = (dec ->u32MaxWidth + 15) / 16;#if 1    fmpeg4_mempool_free((unsigned int)dec->pu8BS_start_virt,dec->u32BS_buf_sz);    fmpeg4_mempool_free((unsigned int)dec->pu16ACDC_ptr_virt,max_mb_width*4*16);#else	dec->pfnDmaFree(dec->pu16ACDC_ptr_virt, dec->pu16ACDC_ptr_phy);	dec->pfnDmaFree(dec->pu8BS_start_virt, dec->pu8BS_start_phy);#endif	image_destroy(&dec->cur, max_mb_width, dec);	image_destroy(&dec->refn, max_mb_width, dec);	//free_align(dec->mbs);	kfree(dec->mbs);	//free_align(dec);	kfree(dec);}#define SIGN(X) (((X)>0)?1:-1)#define ABS(X) (((X)>0)?(X):-(X))static __inline uint32_tpredict_acdc_P(const MACROBLOCK * pMBs,			const MACROBLOCK_b * mbb,			const int32_t mb_width,			const int32_t bound){	uint32_t u32temp;	const int32_t mbpos = mbb->mbpos;		if (mbb->toggle)		u32temp = MCCTL_REMAP | MCCTL_DECGO;	else		u32temp = MCCTL_DECGO;	// left macroblock valid ?	// No need to check bound here, hardware will check it	if ((mbb->x == 0) ||		(pMBs[mbpos - 1].mode != MODE_INTRA &&		 pMBs[mbpos - 1].mode != MODE_INTRA_Q))		u32temp |= MCCTL_ACDC_L;	// diag macroblock valid ?	if ((mbb->x == 0) || (mbpos < (bound + mb_width + 1)) ||		(pMBs[mbpos - 1 - mb_width].mode != MODE_INTRA &&		 pMBs[mbpos - 1 - mb_width].mode != MODE_INTRA_Q))		u32temp |= MCCTL_ACDC_D;	// top macroblock valid ?	if ((mbpos < (bound + mb_width))  ||		(pMBs[mbpos - mb_width].mode != MODE_INTRA &&		 pMBs[mbpos - mb_width].mode != MODE_INTRA_Q))		u32temp |= MCCTL_ACDC_T;	return u32temp;}static __inline uint32_tpredict_acdc_I(const MACROBLOCK_b * mbb,			const int32_t mb_width,			const int32_t bound){	uint32_t u32temp;	if (mbb->toggle)		u32temp = MCCTL_REMAP | MCCTL_DECGO;	else		u32temp = MCCTL_DECGO;	// left macroblock valid ?	// No need to check bound here, hardware will check it	if (mbb->x == 0)		u32temp |= (MCCTL_ACDC_L | MCCTL_ACDC_D);	// diag macroblock valid ?	if (mbb->mbpos < (bound + mb_width + 1)) {		u32temp |= MCCTL_ACDC_D;		// top macroblock valid ?		if ((mbb->mbpos < (bound + mb_width)))			u32temp |= MCCTL_ACDC_T;	}	return u32temp;}void error_concealment_p(DECODER *dec,					uint32_t mbpos,					const int32_t error_count){	int32_t x, y;	int32_t i, uv_dx, uv_dy;	union VECTOR1 pmv[4];	int refx;	int refy;	MACROBLOCK * mb;	int j, k;	x = mbpos % dec->mb_width;	y = mbpos / dec->mb_width;	for (i = 0; i < error_count; i ++) {		mb = & dec->mbs[mbpos];		pmv[0] = get_pmv_average(dec->mbs, dec->mb_width, x, y, 0);		mb->mvs[0] = pmv[0];		pmv[1] = get_pmv_average(dec->mbs, dec->mb_width, x, y, 1);		mb->mvs[1] = pmv[1];		pmv[2] = get_pmv_average(dec->mbs, dec->mb_width, x, y, 2);		mb->mvs[2] = pmv[2];		pmv[3] = get_pmv_average(dec->mbs, dec->mb_width, x, y, 3);		mb->mvs[3] = pmv[3];/*		pmv[0].x = 0;		pmv[0].y = 0;		pmv[1].x = 0;		pmv[1].y = 0;		pmv[2].x = 0;		pmv[2].y = 0;		pmv[3].x = 0;		pmv[3].y = 0;*/		uv_dx = (int32_t)pmv[0].vec.s16x;		uv_dy = (int32_t)pmv[0].vec.s16y;		uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;		uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;		for (j = 0; j < 2; j ++) {			for (k = 0; k < 2; k ++) {				refx = ((2 * x + k) * PIXEL_U * 2 + pmv[2 * j + k].vec.s16x) / 2; 		// unit: 1 pixel				refy = ((2 * y + j) * PIXEL_U * 2 + pmv[2 * j + k].vec.s16y) / 2; 	// unit: 1 pixel				transfer8x8_copy_ben(dec,								((x + k) + (2 * y + j) * dec->mb_width * 2) * SIZE_U,								dec->cur.y_virt,								dec->refn.y_virt,								refx,

⌨️ 快捷键说明

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