?? mp4venc.c
字號:
/**
* @file Mp4Venc.c
* @brief The implementation file for Faraday MPEG4 encoder API.
*
*/
#include "portab.h"
#include "ftmcp100.h"
#include "Mp4Venc.h"
#include "encoder.h"
#include "motion.h"
//#include "mem_align.h"
// added for debugging purpose
#ifdef DUMP_RECONSTRUCTED_RESULT
FILE *reconstructed_result_file;
#endif
#ifdef DUMP_ME_RESULT
FILE *me_result_file;
#endif
#ifdef DUMP_PMV_RESULT
FILE *pmv_result_file;
#endif
unsigned int pred_value_virt_sz=0;
void *Init_FTMCP100(FMP4_ENC_PARAM * ptParam)
{
// create the Codec object
#if 1//ivan
FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *) kmalloc(sizeof(FTMCP100_CODEC),GFP_ATOMIC);
#else
FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *) Faraday_malloc(sizeof(FTMCP100_CODEC),CACHE_LINE);
#endif
volatile MP4_t * ptMP4 = (MP4_t *)(((uint32_t)ptParam->pu32BaseAddr) + MP4_OFFSET);
uint32_t v;
pCodec->pCoreBaseAddr=ptParam->pu32BaseAddr;
// set the coprocessor clock, 0 => same as CPU clock
SET_CKR(CKR_RATIO)
SET_QAR(0)
SET_VLDCTL(1<<5) //stop autobuffer in case previous firmware program did not terminate normally
SET_MEIADDR(0)
SET_CMDADDR(0)
SET_MECADDR(0)
SET_MCCADDR(0)
SET_ACDCPAR(0)
SET_BADR(0)
SET_MCIADDR(0)
SET_VOADR(RUN_LEVEL)
// To set the bit 23~20 of VOP0 register to zero at hardware member's request
//READ_VOP0(v)
//SET_VOP0(v&0x0fffff)
// we put the rate control related parameters here for reference...
// we did not export these encoding setting to API...
pCodec->RC_AVERAGE_PERIOD = 100;
pCodec->DELAY_FACTOR = 16;
pCodec->ARG_RC_BUFFER=100;
pCodec->ME_command_queue0=(uint32_t *) (ME_COMMAND_QUEUE_ADDR + pCodec->pCoreBaseAddr);
pCodec->DMA_COMMAND_local=(uint32_t *) (DMA_COMMAND_LOCAL_ADDR + pCodec->pCoreBaseAddr);
pCodec->pfnDmaMalloc=(void *)ptParam->pfnDmaMalloc;
pCodec->pfnDmaFree=(void *)ptParam->pfnDmaFree;
if(ptParam->p16ACDC) {
pCodec->pred_value_virt = NULL;
pCodec->pred_value_phy=ptParam->p16ACDC;
}
else {
#if 1 //ivan
pred_value_virt_sz=((ptParam->u32FrameWidth+15)/16)*64;
pCodec->pred_value_virt = consistent_alloc(GFP_ATOMIC,pred_value_virt_sz,&pCodec->pred_value_phy);
#else
pCodec->pred_value_virt = (int16_t *)(*(DMA_MALLOC_PTR)pCodec->pfnDmaMalloc)(((ptParam->u32FrameWidth+15)/16)*64, 16, CACHE_LINE,&(pCodec->pred_value_phy));
#endif
}
#ifdef CORE_VERSION_1
#if 1 //ivan
DMA_COMMAND_system_virt_sz=44*sizeof(uint32_t);
pCodec->DMA_COMMAND_system_virt=consistent_alloc(GFP_ATOMIC,DMA_COMMAND_system_virt_sz,&(pCodec->DMA_COMMAND_system_phy));
#else
pCodec->DMA_COMMAND_system_virt=(uint32_t *)(*(DMA_MALLOC_PTR)pCodec->pfnDmaMalloc)(44*sizeof(uint32_t),16,CACHE_LINE,&(pCodec->DMA_COMMAND_system_phy));
#endif
#endif
return (void *)pCodec;
}
void *FMpeg4EncCreate(FMP4_ENC_PARAM * ptParam)
{
FTMCP100_CODEC *pCodec;
volatile MDMA *pmdma;
void *pEnc;
pCodec=(FTMCP100_CODEC *)Init_FTMCP100(ptParam);
pmdma = MDMA1;
// for debugging purpose
#ifdef DUMP_RECONSTRUCTED_RESULT
reconstructed_result_file = fopen("reconstructed_result_fpga.yuv","wb");
#endif
#ifdef DUMP_ME_RESULT
me_result_file = fopen("me_result_fpga.dat","w");
#endif
#ifdef DUMP_PMV_RESULT
pmv_result_file = fopen("pmv_result_fpga.dat","w");
#endif
pmdma->Status = 1;
#ifdef FPGA_PLATFORM
FA526_CleanInvalidateDCacheAll();
FA526_DrainWriteBuffer();
#endif
pEnc = encoder_create(ptParam,pCodec);
if(pEnc!=NULL)
{
// attach our FTMCP100 Codec object to encoder object
((Encoder *)pEnc)->pCodec=pCodec;
((Encoder *)pEnc)->mEncParam=*ptParam;
((Encoder *)pEnc)->reference->image.y = ptParam->pu8YFrameBaseAddr;
((Encoder *)pEnc)->reference->image.u = ptParam->pu8UFrameBaseAddr;
((Encoder *)pEnc)->reference->image.v = ptParam->pu8VFrameBaseAddr;
return pEnc;
}
return NULL;
}
void FMpeg4EncSetYUVAddr(void *enc_handle,unsigned char *yaddr,unsigned char *uaddr,unsigned char *vaddr)
{
((Encoder *)enc_handle)->mEncParam.pu8YFrameBaseAddr=yaddr;
((Encoder *)enc_handle)->mEncParam.pu8UFrameBaseAddr=uaddr;
((Encoder *)enc_handle)->mEncParam.pu8VFrameBaseAddr=vaddr;
((Encoder *)enc_handle)->reference->image.y = yaddr;
((Encoder *)enc_handle)->reference->image.u = uaddr;
((Encoder *)enc_handle)->reference->image.v = vaddr;
}
int FMpeg4EncOneFrame(void *enc_handle,int *key_frame)
{
int xerr,vld;
Faraday_ENC_FRAME xframe;
Encoder *enc=(Encoder *)enc_handle;
FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)enc->pCodec;
int flush_size;
DECLARE_MP4_PTR
SET_ASADR((uint32_t) (enc->mEncParam.pu8BitstreamAddr) | 1)
SET_VOADR(RUN_LEVEL)
SET_VLDCTL(1<<4 |1<<6) // enable auto-buffering and swap endian
xframe.bitstream = enc->mEncParam.pu8BitstreamAddr;
xframe.length = -1; // this is written by the routine
xframe.colorspace =Faraday_CSP_YV12; // defined in <faraday.h>
xframe.intra = -1; // let the codec decide between I-frame (1) and P-frame (0)
xframe.quant = ((Encoder *)enc_handle)->mEncParam.u32Quant; // is quant != 0, use a fixed quant (and ignore bitrate)
xframe.motion = PMV_EARLYSTOP16 | PMV_HALFPELREFINE16;
xframe.general = Faraday_HALFPEL | (((Encoder *)enc_handle)->mEncParam.bH263Quant ? Faraday_H263QUANT:Faraday_MPEGQUANT);
xframe.quant_intra_matrix = xframe.quant_inter_matrix = NULL;
xerr = encoder_encode((Encoder *) enc_handle, &xframe);
// Because during testing the real chip FIE8100, we found there is
// difference between real chip (FIE8100) and FPGA target for autobuffer mechanism. That is,
// whenever we enable the autobuffer mechanism, the bitstream buffer offset pointer can be
// reset to zero under FPAG target. But in real chip (FIE8100), because of gated-clock,the
// bitstream buffer offset pointer can not be reset to zero. So we figure out the following
// code to fix such problem.
READ_BALR(flush_size);
flush_size = 256 - flush_size;
flush_size >>= 1;
SET_BADR(0) // residue half-words in local memory
for (; flush_size > 0; flush_size--) {
SET_BALR(16)
}
READ_VLDSTS(vld);
for (;;)
{
READ_VLDSTS(vld);
if ((vld & 0x400) != 0)
break;
}
SET_VLDCTL(1<<5) // stop autobuffer
SET_VOADR(RUN_LEVEL)
*key_frame = xframe.intra;
enc->iBitstreamSize=xframe.length;
return (xerr==Faraday_ERR_OK)?1:0;
}
unsigned int FMpeg4EncGetBitsLength(void *enc_handle)
{
return ((Encoder *)enc_handle)->iBitstreamSize;
}
MACROBLOCK_INFO *FMpeg4EncGetMBInfo(void *enc_handle)
{
return (MACROBLOCK_INFO *) ((Encoder *)enc_handle)->current1->mbs;
}
int FMpeg4EncDestroy(void *enc_handle)
{
int retval;
Encoder *pEnc=(Encoder *) enc_handle;
#if 1 //ivan
if(pEnc->pCodec->pred_value_virt)
consistent_free(pEnc->pCodec->pred_value_virt,pred_value_virt_sz,pEnc->pCodec->pred_value_phy);
#ifdef CORE_VERSION_1
if(pEnc->pCodec->DMA_COMMAND_system_virt)
consistent_free(pEnc->pCodec->DMA_COMMAND_system_virt,DMA_COMMAND_system_virt_sz,pEnc->pCodec->DMA_COMMAND_system_phy);
#endif
#else
if(pEnc->pCodec->pred_value_virt)
(*(DMA_FREE_PTR)pEnc->pCodec->pfnDmaFree)(pEnc->pCodec->pred_value_virt, pEnc->pCodec->pred_value_phy);
#ifdef CORE_VERSION_1
(*(DMA_FREE_PTR)pEnc->pCodec->pfnDmaFree)(pEnc->pCodec->DMA_COMMAND_system_virt,pEnc->pCodec->DMA_COMMAND_system_phy);
#endif
#endif
// free Codec object
#if 1
kfree(pEnc->pCodec);
#else
Faraday_free(pEnc->pCodec);
#endif
retval=encoder_destroy(pEnc);
#ifdef DUMP_RECONSTRUCTED_RESULT
fclose(reconstructed_result_file);
#endif
#ifdef DUMP_ME_RESULT
fclose(me_result_file);
#endif
#ifdef DUMP_PMV_RESULT
fclose(pmv_result_file);
#endif
return (retval==Faraday_ERR_OK)?1:0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -