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

📄 mp4venc.c

📁 基于Linux的ffmepg decoder
💻 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 + -