?? encoder.c
字號:
#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 + -