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

📄 encoder.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
#include "encoder.h"
#include "global.h"
#include "enc_image.h"
#include "motion.h"
#include "ratecontrol.h"
#include "bitstream.h"
#include "mbfunctions.h"
#include "quant_matrix.h"

// added for dumping reconstructed image result
#ifdef DUMP_RECONSTRUCTED_RESULT
void dump_reconstructed_image_to_file(uint8_t * const buf,uint32_t width,uint32_t height,int dump_y,FILE *f)
{   // since the reconstructed image for MPEG4 encoder's hardware is 2D, so we transfrom it to 1D
	uint32_t i,j;
	uint32_t mb_x,mb_y,mb_size; // mb_x and mb_y is macroblock's number
	uint32_t mb_width,mb_height;
	uint8_t *mb_start;
	
	if(dump_y) { mb_width=16; mb_height=16; }
	else { mb_width=8; mb_height=8; }
	
	mb_size=mb_width*mb_height;
	
	for (j = 0; j < height; j++) {
		for (i = 0; i < width; i++) {
		  mb_x=i/mb_width;
		  mb_y=j/mb_height;
		  mb_start=buf+(mb_y*(width/mb_width)+mb_x)*mb_size;
          fwrite(mb_start+(j%mb_height)*mb_width+(i%mb_width),sizeof(uint8_t),1,f);
		}
	}
}
#endif

/*
__align(16) int16_t default_acdc_values[64] = {
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0,
	1024, 0, 0, 0, 0, 0, 0, 0};
*/

#define FRAMERATE_INCR		1001
#define SMALL_EPS 1e-10

/*****************************************************************************
 * Local function prototypes
 ****************************************************************************/
static int FrameCodeP(Encoder * pEnc,Bitstream * bs,uint32_t * pBits,bool vol_header);
static int FrameCodePNotCoded(Encoder * pEnc,Bitstream * bs,uint32_t * pBits,bool vol_header);
static int FrameCodeI(Encoder * pEnc,Bitstream * bs,uint32_t * pBits);
/*****************************************************************************
 * Local data
 ****************************************************************************/

static void __inline
image_null(IMAGE * image)
{
	image->y = image->u = image->v = NULL;
	image->y_virt = image->u_virt = image->v_virt = NULL;
}

static uint32_t __inline
log2bin(uint32_t value)
{
	int n = 0;

	while (value) {
		value >>= 1;
		n++;
	}
	return n;
}

/*****************************************************************************
 * Encoder creation
 *
 * This function creates an Encoder instance, it allocates all necessary
 * image buffers (reference, current) and initialize the internal Faraday
 * encoder paremeters according to the Faraday_ENC_PARAM input parameter.
 *
 * The code seems to be very long but is very basic, mainly memory allocation
 * and cleaning code.
 *
 * Returned values :
 *    - Faraday_ERR_OK     - no errors
 *    - Faraday_ERR_MEMORY - the libc could not allocate memory, the function
 *                        cleans the structure before exiting.
 *                        pParam->handle is also set to NULL.
 *
 ****************************************************************************/

void __inline MOVE_DEFAULT_PREDICTOR(MBParam * const pParam,uint32_t y,FTMCP100_CODEC *pCodec)
{
    if (pParam->resyn==0)
	{
		if (y)
			pCodec->acdc_status = 5; // Diagonal and Left
		else
			pCodec->acdc_status = 7; // Diagonal and Top and Left
	}
	else
	{
		pCodec->acdc_status = 7; // Diagonal and Top and Left
	}
}

void *encoder_create(FMP4_ENC_PARAM * ptParam,FTMCP100_CODEC *pCodec)
{
	volatile MDMA *pmdma = MDMA1;
	Encoder *pEnc;
	int i;
	int fincr,fbase;
	
    if ((ptParam->fFrameRate - (int)ptParam->fFrameRate) < SMALL_EPS)
      {  fincr = 1;  fbase = (int)ptParam->fFrameRate; }
    else
      {  fincr = FRAMERATE_INCR;  fbase = (int)(FRAMERATE_INCR * ptParam->fFrameRate); }

	#if defined(CORE_VERSION_2)
	  // we group the DMA commands type
	  // group ID 0 : normal operation
	  // group ID 1 : disable this DMA command
      // group ID 2 : sync to MC done
      // group ID 3 : sync to VLC done
      pmdma->GRPC =(uint32_t) 0x000000f8;
      pmdma->GRPS =(uint32_t) 0x000000e0;
      
	  /*  initial DMA command chain	*/
	  pCodec->DMA_COMMAND_local[14] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[14+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[18] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[18+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[22] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[22+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0;


      pCodec->DMA_COMMAND_local[26] = (uint32_t) 0;
	  //pCodec->DMA_COMMAND_local[27] = (uint32_t) 0x4B01040; // make it group ID 1, disable this command
	  pCodec->DMA_COMMAND_local[30] = (uint32_t) 0;
	  //pCodec->DMA_COMMAND_local[31] = (uint32_t) 0x4B01010; // make it group ID 1, disable this command
	  pCodec->DMA_COMMAND_local[34] = (uint32_t) 0;
	  //pCodec->DMA_COMMAND_local[35] = (uint32_t) 0x4B01010; // make it group ID 1, disable this command
	  
	  pCodec->DMA_COMMAND_local[26+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0;
	  //pCodec->DMA_COMMAND_local[27+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0x4B01040; // make it group ID 1, disable this command
	  pCodec->DMA_COMMAND_local[30+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0;
	  //pCodec->DMA_COMMAND_local[31+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0x4B01010; // make it group ID 1, disable this command
	  pCodec->DMA_COMMAND_local[34+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0;
	  //pCodec->DMA_COMMAND_local[35+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0x4B01010; // make it group ID 1, disable this command
      // load predictor
      pCodec->DMA_COMMAND_local[38] = (uint32_t) (8+1-4) << 24 | 4 << 20;
	  //pCodec->DMA_COMMAND_local[39] = (uint32_t) 0x840010;
	  pCodec->DMA_COMMAND_local[38+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) (8+1-4) << 24 | 4 << 20;
	  //pCodec->DMA_COMMAND_local[39+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0x840010;	  
      
      //  store predictor
      pCodec->DMA_COMMAND_local[41] = TRANSLATE_LOCAL_MEMORY_BASE_ADDRESS(LOCAL_PREDICTOR8);
      pCodec->DMA_COMMAND_local[41+DMA_COMMAND_QUEUE_STRIDE] = TRANSLATE_LOCAL_MEMORY_BASE_ADDRESS(LOCAL_PREDICTOR8);
	
	  pCodec->DMA_COMMAND_local[42] = (uint32_t) (8+1-4) << 24 | 4 << 20;
	  pCodec->DMA_COMMAND_local[42+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) (8+1-4) << 24 | 4 << 20;

	  pCodec->DMA_COMMAND_local[43] = (uint32_t) 0x942010;  // sync to MC done
      pCodec->DMA_COMMAND_local[43+DMA_COMMAND_QUEUE_STRIDE] = (uint32_t) 0x942010; // sync to MC done

    #elif defined(CORE_VERSION_1)
	  /*  initial DMA command chain	*/
	  pCodec->DMA_COMMAND_local[14] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[18] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[22] = (uint32_t) 0;
      //	load predictor
	  pCodec->DMA_COMMAND_local[26] = (uint32_t) (8+1-4) << 24 | 4 << 20;
	  pCodec->DMA_COMMAND_local[27] = (uint32_t) 0x840010;						//  chain disenable
      //	end load predictor

	  pCodec->DMA_COMMAND_local[30] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[31] = (uint32_t) 0x4B00040;						//  chain enable

	  pCodec->DMA_COMMAND_local[34] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[35] = (uint32_t) 0x4B00010;						//  chain enable

	  pCodec->DMA_COMMAND_local[38] = (uint32_t) 0;
	  pCodec->DMA_COMMAND_local[39] = (uint32_t) 0x4B00010;						//  chain disenable

      //  store predictor
	  pCodec->DMA_COMMAND_local[41] = LOCAL_PREDICTOR8;
	
	  pCodec->DMA_COMMAND_local[42] = (uint32_t) (8+1-4) << 24 | 4 << 20;
	  pCodec->DMA_COMMAND_local[43] = (uint32_t) 0x940010; // Disable Transfer Done flag mask
                                                   // Enable DMA start transferring
                                                   // Disable chain transfer
                                                   // From 2D Local memory to sequential System memory
                                                   // transfer 0x10(16) words = 64 bytes
      //  end store predictor
    #endif

	//if (pParam->fincr <= 0 || pParam->fbase <= 0) {
    //pParam->fincr = 1;
	//	pParam->fbase = 25;
	//}
	if (fincr <= 0 || fbase <= 0) {
		fincr = 1;
		fbase = 25;
	}

	//
	// Simplify the "fincr/fbase" fraction
	// (neccessary, since windows supplies us with huge numbers)
	//
	 
	i = fincr; //i = pParam->fincr;
	while (i > 1) {
		if (fincr % i == 0 && fbase % i == 0) {
			fincr /= i;
			fbase /= i;
			i = fincr;
			continue;
		}
		i--;
	}

    if (fbase > 65535) {
		float div = (float) fbase / 65535;
		fbase = (int) (fbase / div);
		fincr = (int) (fincr / div);
	}
#if 0 //ivan
	pEnc = (Encoder *) Faraday_malloc(sizeof(Encoder), (uint8_t) CACHE_LINE);
#else
    pEnc = (Encoder *)kmalloc(sizeof(Encoder),GFP_KERNEL|GFP_ATOMIC);
#endif
	
	if (pEnc == NULL) 
	  return NULL;

	// Zero the Encoder Structure
	memset(pEnc, 0, sizeof(Encoder));
	
	pEnc->mbParam.h263 = ptParam->bShortHeader;	
	pEnc->mbParam.resyn = ptParam->bResyncMarker;
	pEnc->mbParam.enable_4mv = ptParam->bEnable4MV;
	
	if (ptParam->bEnable4MV) {	//if (pParam->enable_4mv) {	
      MotionEstimation = MotionEstimation_4MV;
      MotionEstimation_blocklast = MotionEstimation_blocklast_4MV;
      MotionEstimation_block0 = MotionEstimation_block0_4MV;
	} else {
      MotionEstimation = MotionEstimation_1MV;
      MotionEstimation_blocklast = MotionEstimation_blocklast_1MV;
      MotionEstimation_block0 = MotionEstimation_block0_1MV;
	}
	
	pEnc->mbParam.temporal_ref = 0;

	/* Fill members of Encoder structure */

    pEnc->mbParam.width = ptParam->u32FrameWidth;
	pEnc->mbParam.height = ptParam->u32FrameHeight;

	pEnc->mbParam.mb_width = (pEnc->mbParam.width + 15) / 16;
	pEnc->mbParam.mb_height = (pEnc->mbParam.height + 15) / 16;

	pEnc->mbParam.fbase = fbase;
	pEnc->mbParam.fincr = fincr;

	pEnc->mbParam.m_quant_type = H263_QUANT;

	/* Fill rate control parameters */

	pEnc->bitrate = ptParam->u32BitRate*1000;

	pEnc->iFrameNum = 0;
	pEnc->iMaxKeyInterval = ptParam->u32IPInterval;

	/* try to allocate frame memory */
#if 0
	pEnc->current = Faraday_malloc(sizeof(FRAMEINFO), CACHE_LINE);
	pEnc->reference = Faraday_malloc(sizeof(FRAMEINFO), CACHE_LINE);
#else
	pEnc->current1 = kmalloc(sizeof(FRAMEINFO),GFP_KERNEL|GFP_ATOMIC);
	pEnc->reference = kmalloc(sizeof(FRAMEINFO),GFP_KERNEL|GFP_ATOMIC);
#endif

	if (pEnc->current1 == NULL || pEnc->reference == NULL)
		goto Faraday_err_memory1;
	

    if(ptParam->pu8ReConFrameCur) // if it is not NULL, use user-provided buffer
      enc_image_adjust(&(pEnc->current1->reconstruct), pEnc->mbParam.mb_width, pEnc->mbParam.mb_height,ptParam->pu8ReConFrameCur);
    else {

⌨️ 快捷键说明

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