📄 decoder.c
字号:
#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 + -