有一个需要进行硬件编码的项目,因为板子给的SDK中并没有给出详细的使用方法,给自己的使用中带来了很多的麻烦。经过了很长一段时间的尝试,终于完成了对于NXP这套硬件编码SDK的使用方式。

相关依赖文件:
NX_Queue.cpp

//------------------------------------------------------------------------------
//
//  Copyright (C) 2010 Nexell co., Ltd All Rights Reserved
//
//  Module     : Queue Module
//  File       :
//  Description:
//  Author     : RayPark
//  History    :
//------------------------------------------------------------------------------
#include <assert.h>
#include <string.h>//   string
#include <pthread.h>#include "NX_Queue.h"#define DbgMsg(fmt,...)        printf(fmt)//
//  Description : Initialize queue structure
//  Return      : 0 = no error, -1 = error
//
int NX_InitQueue( NX_QUEUE *pQueue, unsigned int maxNumElement )
{//  Initialize Queuememset( pQueue, 0, sizeof(NX_QUEUE) );if( maxNumElement > NX_MAX_QUEUE_ELEMENT ){return -1;}if( 0 != pthread_mutex_init( &pQueue->hMutex, NULL ) ){return -1;}pQueue->maxElement = maxNumElement;pQueue->bEnabled = 1;return 0;
}int NX_PushQueue( NX_QUEUE *pQueue, void *pElement )
{assert( NULL != pQueue );pthread_mutex_lock( &pQueue->hMutex );//  Check Buffer Fullif( pQueue->curElements >= pQueue->maxElement || !pQueue->bEnabled ){pthread_mutex_unlock( &pQueue->hMutex );return -1;}else{pQueue->pElements[pQueue->tail] = pElement;pQueue->tail = (pQueue->tail+1)%pQueue->maxElement;pQueue->curElements ++;}pthread_mutex_unlock( &pQueue->hMutex );return 0;
}int NX_PopQueue( NX_QUEUE *pQueue, void **pElement )
{assert( NULL != pQueue );pthread_mutex_lock( &pQueue->hMutex );//  Check Buffer Fullif( pQueue->curElements == 0 || !pQueue->bEnabled ){pthread_mutex_unlock( &pQueue->hMutex );return -1;}else{*pElement = pQueue->pElements[pQueue->head];pQueue->head = (pQueue->head + 1)%pQueue->maxElement;pQueue->curElements --;}pthread_mutex_unlock( &pQueue->hMutex );return 0;
}int NX_GetNextQueuInfo( NX_QUEUE *pQueue, void **pElement )
{assert( NULL != pQueue );pthread_mutex_lock( &pQueue->hMutex );//  Check Buffer Fullif( pQueue->curElements == 0 || !pQueue->bEnabled ){pthread_mutex_unlock( &pQueue->hMutex );return -1;}else{*pElement = pQueue->pElements[pQueue->head];}pthread_mutex_unlock( &pQueue->hMutex );return 0;
}unsigned int NX_GetQueueCnt( NX_QUEUE *pQueue )
{assert( NULL != pQueue );return pQueue->curElements;
}void NX_DeinitQueue( NX_QUEUE *pQueue )
{assert( NULL != pQueue );pthread_mutex_lock( &pQueue->hMutex );pQueue->bEnabled = 0;pthread_mutex_unlock( &pQueue->hMutex );pthread_mutex_destroy( &pQueue->hMutex );memset( pQueue, 0, sizeof(NX_QUEUE) );
}

Queue.h

//------------------------------------------------------------------------------
//
//  Copyright (C) 2010 Nexell co., Ltd All Rights Reserved
//
//  Module      : Queue Module
//  File        :
//  Description : Thread safe Queue moudle
//  Author      : Seong-O Park (ray@nexell.co.kr)
//  History     :
//------------------------------------------------------------------------------
#ifndef __NX_Queue_h__
#define __NX_Queue_h__#include <pthread.h>#define NX_MAX_QUEUE_ELEMENT    128typedef struct NX_QUEUE{unsigned int head;unsigned int tail;unsigned int maxElement;unsigned int curElements;int bEnabled;void *pElements[NX_MAX_QUEUE_ELEMENT];pthread_mutex_t    hMutex;
}NX_QUEUE;int NX_InitQueue( NX_QUEUE *pQueue, unsigned int maxNumElement );
int NX_PushQueue( NX_QUEUE *pQueue, void *pElement );
int NX_PopQueue( NX_QUEUE *pQueue, void **pElement );
int NX_GetNextQueuInfo( NX_QUEUE *pQueue, void **pElement );
unsigned int NX_GetQueueCnt( NX_QUEUE *pQueue );
void NX_DeinitQueue( NX_QUEUE *pQueue );#endif//   __NX_OMXQueue_h__

Util.cpp

#include <stdio.h>
#include <sys/time.h>#include "Util.h"uint64_t NX_GetTickCount( void )
{uint64_t ret;struct timeval    tv;struct timezone    zv;gettimeofday( &tv, &zv );ret = ((uint64_t)tv.tv_sec)*1000 + tv.tv_usec/1000;return ret;
}void dumpdata( void *data, int32_t len, const char *msg )
{int32_t i=0;uint8_t *byte = (uint8_t *)data;printf("Dump Data : %s", msg);for( i=0 ; i<len ; i ++ ){if( i!=0 && i%16 == 0 )  printf("\n\t");printf("%.2x", byte[i] );if( i%4 == 3 ) printf(" ");}printf("\n");
}

Util.h

#ifndef __UTIL_h__
#define __UTIL_h__#include <stdint.h>uint64_t NX_GetTickCount( void );
void dumpdata( void *data, int32_t len, const char *msg );//  Encoder Application Data
typedef struct CODEC_APP_DATA {//  Input Optionschar *inFileName;         //  Input File Nameint32_t    width;               //  Input YUV Image Widthint32_t  height;              //  Input YUV Image Heightint32_t fpsNum;              //  Input Image Fps Numberint32_t fpsDen;              //  Input Image Fps Density//    Output Optionschar *outFileName;           //  Output File Namechar *outLogFileName;      //  Output Log File Namechar *outImgName;          //  Output Reconstructed Image File Nameint32_t kbitrate;          //  Kilo Bitrateint32_t gop;               //  GoPint32_t codec;              //  0:H.264, 1:Mp4v, 2:H.263, 3:JPEG (def:H.264)int32_t qp;                    //  Fixed Qpint32_t vbv;int32_t maxQp;int32_t RCAlgorithm;int32_t angle;//   Preview Optionsint32_t dspX;               //  Display X Axis Offsetint32_t dspY;             //  Display Y Axis Offsetint32_t  dspWidth;            //  Display Widthint32_t dspHeight;            //  Dispplay Height
} CODEC_APP_DATA;#endif// __UTIL_h__

DEMO文件
VpuEncTest.cpp

#include <stdio.h>
#include <string.h>
#include <unistd.h>//   getopt & optarg
#include <stdlib.h>//   atoi
#include <sys/time.h>//   gettimeofday
#include <math.h>#include <nx_fourcc.h>
#include <nx_vip.h>//   VIP
#include <nx_dsp.h>//   Display
#include <nx_video_api.h>//   Video En/Decoder#include "NX_Queue.h"
#include "Util.h"#define   MAX_SEQ_BUF_SIZE        (4*1024)
#define MAX_ENC_BUFFER          8
#define ENABLE_NV12             1//#define TEST_CHG_PARA//
//  Display Position
//
static int32_t giX = 0, giY = 0, giWidth = 1024, giHeight = 600;      //  Drone Board.static float GetPSNR (uint8_t *pbyOrg, uint8_t *pbyRecon, int32_t iWidth, int32_t iHeight, int32_t iStride)
{int32_t  i, j;float    fPSNR_L = 0;for (i = 0; i < iHeight ; i++) {for (j = 0; j < iWidth ; j++) {fPSNR_L += (*(pbyOrg + j) - *(pbyRecon + j)) * (*(pbyOrg + j) - *(pbyRecon + j));}pbyOrg   += iStride;pbyRecon += iWidth;}// LfPSNR_L = (float) fPSNR_L / (float) (iWidth * iHeight);fPSNR_L = (fPSNR_L)? 10 * (float) log10 ((float) (255 * 255) / fPSNR_L): (float) 99.99;return fPSNR_L;
}//
//  pSrc : Y + U(Cb) + V(Cr) (IYUV format)
//
static int32_t LoadImage( uint8_t *pSrc, int32_t w, int32_t h, NX_VID_MEMORY_INFO *pImg )
{int32_t i, j;uint8_t *pDst, *pCb, *pCr;//  Copy LupDst = (uint8_t*)pImg->luVirAddr;for( i=0 ; i<h ; i++ ){memcpy(pDst, pSrc, w);pDst += pImg->luStride;pSrc += w;}pCb = pSrc;pCr = pSrc + w*h/4;switch( pImg->fourCC ){case FOURCC_NV12:{ printf("NV12\n");uint8_t *pCbCr;pDst = (uint8_t*)pImg->cbVirAddr;for( i=0 ; i<h/2 ; i++ ){pCbCr = pDst + pImg->cbStride*i;for( j=0 ; j<w/2 ; j++ ){*pCbCr++ = *pCb++;*pCbCr++ = *pCr++;}}break;}case FOURCC_NV21:{uint8_t *pCrCb;pDst = (uint8_t*)pImg->cbVirAddr;for( i=0 ; i<h/2 ; i++ ){pCrCb = pDst + pImg->cbStride*i;for( j=0 ; j<w/2 ; j++ ){*pCrCb++ = *pCr++;*pCrCb++ = *pCb++;}}break;}case FOURCC_MVS0:case FOURCC_YV12:case FOURCC_IYUV:{printf("YUV\n");// CbpDst = (uint8_t*)pImg->cbVirAddr;for( i=0 ; i<h/2 ; i++ ){memcpy(pDst, pCb, w/2);pDst += pImg->cbStride;pCb += w/2;}//  CrpDst = (uint8_t*)pImg->crVirAddr;for( i=0 ; i<h/2 ; i++ ){memcpy(pDst, pCr, w/2);pDst += pImg->crStride;pCr += w/2;}break;}}return 0;
}#ifdef TEST_CHG_PARA
static void TestChangeParameter( ENC_APP_DATA *pAppData, NX_VID_ENC_HANDLE hEnc, int32_t frameCnt )
{NX_VID_ENC_CHG_PARAM stChgParam = {0,};if (frameCnt == 0){printf(" <<< Test Change Parameter >>> \n");}else if (frameCnt == 200){stChgParam.chgFlg = VID_CHG_GOP;stChgParam.gopSize = pAppData->gop >> 1;printf("Change From 200Frm : GOP Size is half (%d -> %d) \n", pAppData->gop, stChgParam.gopSize );NX_VidEncChangeParameter( hEnc, &stChgParam );}else if (frameCnt == 400){stChgParam.chgFlg = VID_CHG_BITRATE | VID_CHG_GOP | VID_CHG_VBV;stChgParam.bitrate = ( pAppData->kbitrate >> 1 ) * 1024;stChgParam.gopSize = pAppData->gop;stChgParam.rcVbvSize = 0;printf("Change From 400Frm : BPS is half (%d -> %d) \n", pAppData->kbitrate, stChgParam.bitrate );NX_VidEncChangeParameter( hEnc, &stChgParam );}else if (frameCnt == 600){stChgParam.chgFlg = VID_CHG_FRAMERATE | VID_CHG_BITRATE | VID_CHG_VBV;stChgParam.bitrate = pAppData->kbitrate * 1024;stChgParam.fpsNum = pAppData->fpsNum >> 1;stChgParam.fpsDen = pAppData->fpsDen;stChgParam.rcVbvSize = 0;printf("Change From 600Frm : FPS is half (%d, %d) \n", pAppData->fpsNum, stChgParam.fpsNum );NX_VidEncChangeParameter( hEnc, &stChgParam );}else if (frameCnt == 800){stChgParam.chgFlg = VID_CHG_BITRATE | VID_CHG_GOP | VID_CHG_FRAMERATE | VID_CHG_VBV;stChgParam.bitrate = ( pAppData->kbitrate << 2 ) * 1024;stChgParam.gopSize = pAppData->gop >> 2;stChgParam.fpsNum = pAppData->fpsNum;stChgParam.fpsDen = pAppData->fpsDen;stChgParam.rcVbvSize = 0;printf("Change From 800Frm : BPS is quadruple & gop is quarter (%d -> %d, %d -> %d) \n", pAppData->kbitrate, stChgParam.bitrate, pAppData->gop, stChgParam.gopSize );NX_VidEncChangeParameter( hEnc, &stChgParam );}
}
#endif#if 0
//  Camera Encoder Main
static int32_t VpuCamEncMain( CODEC_APP_DATA *pAppData )
{int32_t i;int32_t cropX=0, cropY=0, cropW, cropH;  //  Clipper Output Informationint32_t frameCnt = 0;FILE *fdOut = NULL;//  VIPVIP_HANDLE hVip;VIP_INFO vipInfo;// MemoryNX_VID_MEMORY_HANDLE hMem[MAX_ENC_BUFFER];//  DisplayDISPLAY_HANDLE hDsp;NX_QUEUE memQueue;DISPLAY_INFO dspInfo;//    Previous Displayed MemoryNX_VID_MEMORY_INFO *pPrevDsp = NULL;
#ifdef NV12_MEM_TESTNX_VID_MEMORY_INFO *pNV12Mem = NULL;
#endif// Current Vip BufferNX_VID_MEMORY_INFO *pCurCapturedBuf = NULL;NX_VID_MEMORY_INFO *pTmpMem = NULL;// Encoder ParametersNX_VID_ENC_INIT_PARAM encInitParam;unsigned char *seqBuffer = (unsigned char *)malloc( MAX_SEQ_BUF_SIZE );NX_VID_ENC_HANDLE hEnc;NX_VID_ENC_IN encIn;NX_VID_ENC_OUT encOut;long long totalSize = 0;long long vipTimeStamp;int instanceIdx;//  Set Image & Clipper InformationcropX = 0;cropY = 0;cropW = pAppData->width;cropH = pAppData->height;// Initialze Memory QueueNX_InitQueue( &memQueue, MAX_ENC_BUFFER );//   Allocate Memoryfor( i=0; i<MAX_ENC_BUFFER ; i++ ){hMem[i] = NX_VideoAllocateMemory( 4096, cropW, cropH, NX_MEM_MAP_LINEAR, FOURCC_MVS0 );NX_PushQueue( &memQueue, hMem[i] );}memset( &vipInfo, 0, sizeof(vipInfo) );vipInfo.port = 2;vipInfo.mode = VIP_MODE_CLIPPER;// Sensor Input SizevipInfo.width = pAppData->width;vipInfo.height = pAppData->height;vipInfo.numPlane = 1;// Clipper SettingvipInfo.cropX = cropX;vipInfo.cropY = cropY;vipInfo.cropWidth  = cropW;vipInfo.cropHeight = cropH;//  FpsvipInfo.fpsNum = pAppData->fpsNum;vipInfo.fpsDen = 1;//  Outputif( pAppData->outFileName )fdOut = fopen( pAppData->outFileName, "wb" );#ifndef ANDROID//  Initailize VIP & DisplaydspInfo.port = 0;dspInfo.module = 0;dspInfo.width = cropW;dspInfo.height = cropH;dspInfo.numPlane = 1;dspInfo.dspSrcRect.left = 0;dspInfo.dspSrcRect.top = 0;dspInfo.dspSrcRect.right = cropW;dspInfo.dspSrcRect.bottom = cropH;dspInfo.dspDstRect.left = 0;dspInfo.dspDstRect.top = 0;dspInfo.dspDstRect.right = cropW;dspInfo.dspDstRect.bottom = cropH;hDsp = NX_DspInit( &dspInfo );//  NX_DspVideoSetPriority(0, 0);
#endif//hVip = NX_VipInit(&vipInfo);//    Open EncoderhEnc = NX_VidEncOpen( NX_AVC_ENC,  &instanceIdx);//  Initialize Encodermemset( &encInitParam, 0, sizeof(encInitParam) );encInitParam.width = cropW;encInitParam.height = cropH;encInitParam.gopSize = pAppData->gop;encInitParam.bitrate = pAppData->kbitrate * 1024;encInitParam.fpsNum = pAppData->fpsNum;encInitParam.fpsDen = 1;
#ifdef NV12_MEM_TESTencInitParam.chromaInterleave = 1;
#elseencInitParam.chromaInterleave = 0;
#endif// Rate ControlencInitParam.enableRC = 1;       //  Enable Rate ControlencInitParam.disableSkip = 0; //  Enable SkipencInitParam.maximumQp = 51;  //  Max Qunatization ScaleencInitParam.initialQp = pAppData->qp;    //  Default Encoder API ( enableRC == 0 )encInitParam.enableAUDelimiter = 1; //  Enable / Disable AU DelimiterNX_VidEncInit( hEnc, &encInitParam );if( fdOut ){int size;//  Write Sequence DataNX_VidEncGetSeqInfo( hEnc, seqBuffer, &size );fwrite( seqBuffer, 1, size, fdOut );dumpdata( seqBuffer, size, "sps pps" );printf("Encoder Out Size = %d\n", size);}#ifdef NV12_MEM_TESTpNV12Mem = NX_VideoAllocateMemory( 4096, cropW, cropH, NX_MEM_MAP_LINEAR, FOURCC_NV12 );
#endif#ifndef ANDROID//   PopQueueNX_PopQueue( &memQueue, (void**)&pTmpMem );NX_VipQueueBuffer( hVip, pTmpMem );
#endifwhile(1){NX_PopQueue( &memQueue, (void**)&pTmpMem );NX_VipQueueBuffer( hVip, pTmpMem );NX_VipDequeueBuffer( hVip, &pCurCapturedBuf, &vipTimeStamp );NX_DspQueueBuffer( hDsp, pCurCapturedBuf );if( pPrevDsp ){NX_DspDequeueBuffer( hDsp );#ifdef NV12_MEM_TESTif( pNV12Mem ){int j;unsigned char *cbcr =(unsigned char*)pNV12Mem->cbVirAddr;unsigned char *cb   =(unsigned char*)pPrevDsp->cbVirAddr;unsigned char *cr   =(unsigned char*)pPrevDsp->crVirAddr;//   Copymemcpy( (unsigned char*)pNV12Mem->luVirAddr, (unsigned char*)pPrevDsp->luVirAddr, cropW*cropH );for( i=0 ; i<cropH/2 ; i++ ){for( j=0 ; j<cropW/2 ; j++ ){*cbcr++ = *cb++;*cbcr++ = *cr++;}}encIn.pImage = pNV12Mem;}else
#endif{encIn.pImage = pPrevDsp;}encIn.timeStamp = 0;encIn.forcedIFrame = 0;encIn.forcedSkipFrame = 0;encIn.quantParam = 25;NX_VidEncEncodeFrame( hEnc, &encIn, &encOut );if( fdOut && encOut.bufSize>0 ){double bitRate = 0.;//   Write Sequence Datafwrite( encOut.outBuf, 1, encOut.bufSize, fdOut );printf("FrameType = %d, size = %8d, ", encOut.frameType, encOut.bufSize);
#ifdef DUMP_DATAdumpdata( encOut.outBuf, 16, "" );
#endiftotalSize += encOut.bufSize;bitRate = (double)totalSize/(double)frameCnt*.8;printf("bitRate = %4.3f kbps\n", bitRate*30/1024.);}NX_PushQueue( &memQueue, pPrevDsp );}pPrevDsp = pCurCapturedBuf;frameCnt ++;}if( fdOut ){fclose( fdOut );}NX_DspClose( hDsp );NX_VipClose( hVip );return 0;
}
#endif//
//  Coda960 Performance Test Application
//
//  Application Sequence :
//
//  Step 1. Prepare Parameter
//  Step 2. Load YUV Image & Copy to Encoding Buffer
//  Step 3. Write Encoded Bitstream
//
static int32_t VpuEncPerfMain( CODEC_APP_DATA *pAppData )
{DISPLAY_HANDLE hDsp;                       // Display HandleNX_VID_ENC_HANDLE hEnc;                    // Encoder Handleuint64_t StrmTotalSize = 0;float    PSNRSum = 0;//  Input Imageint32_t inWidth = pAppData->width;int32_t inHeight = pAppData->height;////   In/Out/Log File Open//FILE *fdIn = fopen( pAppData->inFileName, "rb" );FILE *fdOut = fopen( pAppData->outFileName, "wb" );FILE *fdLog = fopen( pAppData->outLogFileName, "w" );FILE *fdRecon = ( pAppData->outImgName ) ? fopen( pAppData->outImgName, "wb" ) : NULL;if ( fdIn == NULL || fdOut == NULL ){printf("input file or output file open error!!\n");exit(-1);}//==============================================================================// INITIALIZATION//=============================================================================={NX_VID_ENC_INIT_PARAM encInitParam = {0, };                   // Encoder Parametersuint8_t *seqBuffer = (uint8_t *)malloc( MAX_SEQ_BUF_SIZE );  // SPS/PPS or JPEG Header
#ifndef ANDROIDDISPLAY_INFO dspInfo = {0, };// Initailize DisplaydspInfo.port = 0;dspInfo.module = 0;dspInfo.width = inWidth;dspInfo.height = inHeight;dspInfo.numPlane = 1;//  Source CropdspInfo.dspSrcRect.left = 0;dspInfo.dspSrcRect.top = 0;dspInfo.dspSrcRect.right = inWidth;dspInfo.dspSrcRect.bottom = inHeight;// Display ScalingdspInfo.dspDstRect.left = pAppData->dspX;dspInfo.dspDstRect.top = pAppData->dspY;dspInfo.dspDstRect.right = pAppData->dspX + pAppData->dspWidth;dspInfo.dspDstRect.bottom = pAppData->dspY + pAppData->dspHeight;hDsp = NX_DspInit( &dspInfo );NX_DspVideoSetPriority(dspInfo.module, 0);
#endif// Initialize Encoderif ( pAppData->codec == 0) pAppData->codec = NX_AVC_ENC;else if (pAppData->codec == 1) pAppData->codec = NX_MP4_ENC;else if (pAppData->codec == 2) pAppData->codec = NX_H263_ENC;else if (pAppData->codec == 3) pAppData->codec = NX_JPEG_ENC;hEnc = NX_VidEncOpen( (VID_TYPE_E)pAppData->codec, NULL );pAppData->fpsNum = ( pAppData->fpsNum ) ? ( pAppData->fpsNum ) : ( 30 );pAppData->fpsDen = ( pAppData->fpsDen ) ? ( pAppData->fpsDen ) : ( 1 );pAppData->gop = ( pAppData->gop ) ? ( pAppData->gop ) : ( pAppData->fpsNum / pAppData->fpsDen );encInitParam.width = inWidth;encInitParam.height = inHeight;encInitParam.fpsNum = pAppData->fpsNum;encInitParam.fpsDen = pAppData->fpsDen;encInitParam.gopSize = pAppData->gop;encInitParam.bitrate = pAppData->kbitrate * 1024;encInitParam.chromaInterleave = ENABLE_NV12;encInitParam.enableAUDelimiter = 0;           //  Enable / Disable AU DelimiterencInitParam.searchRange = 0;if ( pAppData->codec == NX_JPEG_ENC ){encInitParam.chromaInterleave = 0;encInitParam.jpgQuality = (pAppData->qp == 0) ? (90) : (pAppData->qp);}//  Rate ControlencInitParam.maximumQp= pAppData->maxQp;encInitParam.disableSkip = 0;encInitParam.initialQp = pAppData->qp;encInitParam.enableRC = ( encInitParam.bitrate ) ? ( 1 ) : ( 0 );encInitParam.RCAlgorithm = ( pAppData->RCAlgorithm == 0 ) ? ( 1 ) : ( 0 );encInitParam.rcVbvSize = ( pAppData->vbv ) ? (pAppData->vbv) : (encInitParam.bitrate * 2 / 8);if (NX_VidEncInit( hEnc, &encInitParam ) != VID_ERR_NONE){printf("NX_VidEncInit() failed \n");exit(-1);}printf("NX_VidEncInit() success \n");//  Get Sequence Data or Jpeg Headerif( fdOut ){int size;//    Write Sequence Dataif ( pAppData->codec != NX_JPEG_ENC )NX_VidEncGetSeqInfo( hEnc, seqBuffer, &size );elseNX_VidEncJpegGetHeader( hEnc, seqBuffer, &size );fwrite( seqBuffer, 1, size, fdOut );dumpdata( seqBuffer, size, "sps pps" );StrmTotalSize += size;printf("Encoder Header Size = %d\n", size);}if( fdLog ){fprintf(fdLog, "Frame Count\tFrame Size\tEncoding Time\tIs Key\n");}}//==============================================================================// ENCODE PROCESS UNIT//=============================================================================={NX_VID_MEMORY_HANDLE hMem[MAX_ENC_BUFFER];      // Allocate Memory for Encoder InputNX_VID_MEMORY_INFO *pPrevDsp = NULL;            // Previous Displayed MemoryNX_VID_ENC_IN encIn;NX_VID_ENC_OUT encOut;long long totalSize = 0;double bitRate = 0.;int32_t frameCnt = 0, i, readSize;uint64_t startTime, endTime, totalTime = 0;uint8_t *pSrcBuf = (uint8_t*)malloc(inWidth*inHeight*3/2);for( i=0; i<MAX_ENC_BUFFER ; i++ ){if ( pAppData->codec != NX_JPEG_ENC ){
#if ENABLE_NV12hMem[i] = NX_VideoAllocateMemory( 4096, inWidth, inHeight, NX_MEM_MAP_LINEAR, FOURCC_NV12 );
#elsehMem[i] = NX_VideoAllocateMemory( 4096, inWidth, inHeight, NX_MEM_MAP_LINEAR, /*FOURCC_NV12*/FOURCC_MVS0 );
#endif}elsehMem[i] = NX_VideoAllocateMemory( 4096, inWidth, inHeight, NX_MEM_MAP_LINEAR, /*FOURCC_NV12*/FOURCC_MVS0 );}while(1){
#ifdef TEST_CHG_PARATestChangeParameter( pAppData, hEnc, frameCnt );
#endif//if (frameCnt % 35 == 7)// encIn.forcedIFrame = 1;//else if (frameCnt % 35 == 20)//  encIn.forcedSkipFrame = 1;encIn.pImage = hMem[frameCnt%MAX_ENC_BUFFER];if( fdIn ){readSize = fread(pSrcBuf, 1, inWidth*inHeight*3/2, fdIn);if( readSize != inWidth*inHeight*3/2 || readSize == 0 ){printf("End of Stream!!!\n");break;}}LoadImage( pSrcBuf, inWidth, inHeight, encIn.pImage );if ( pAppData->codec != NX_JPEG_ENC ){encIn.forcedIFrame = 0;encIn.forcedSkipFrame = 0;encIn.quantParam = pAppData->qp;encIn.timeStamp = 0;//    Encode ImagestartTime = NX_GetTickCount();NX_VidEncEncodeFrame( hEnc, &encIn, &encOut );}else{startTime = NX_GetTickCount();NX_VidEncJpegRunFrame( hEnc, encIn.pImage, &encOut );}endTime = NX_GetTickCount();totalTime += (endTime-startTime);#ifndef ANDROID// Display ImageNX_DspQueueBuffer( hDsp, encIn.pImage );if( pPrevDsp ){NX_DspDequeueBuffer( hDsp );}pPrevDsp = encIn.pImage;
#endifif( fdOut && encOut.bufSize>0 ){float PSNR = GetPSNR((uint8_t *)encIn.pImage->luVirAddr, (uint8_t *)encOut.ReconImg.luVirAddr, encOut.width, encOut.height, encIn.pImage->luStride);totalSize += encOut.bufSize;bitRate = (double)totalSize*8/(double)frameCnt;// Write Sequence Datafwrite( encOut.outBuf, 1, encOut.bufSize, fdOut );printf("[%4d]FrameType = %d, size = %8d, ", frameCnt, encOut.frameType, encOut.bufSize);//dumpdata( encOut.outBuf, 16, "" );printf("bitRate = %6.3f kbps, Qp = %2d, PSNR = %f, time=%6lld\n", bitRate*pAppData->fpsNum/pAppData->fpsDen/1000., encIn.quantParam, PSNR, (endTime-startTime) );StrmTotalSize += encOut.bufSize;PSNRSum += PSNR;//   Frame Size, Encoding Time, Is Keyif( fdLog ){fprintf(fdLog, "%5d\t%7d\t%2d\t%lld\t%d\n", frameCnt, encOut.bufSize, encIn.quantParam, (endTime-startTime), encOut.frameType);fflush(fdLog);}if ( fdRecon ){if ( encOut.width == encOut.ReconImg.luStride ){fwrite( (void *)encOut.ReconImg.luVirAddr, 1, encOut.width * encOut.height, fdRecon );fwrite( (void *)encOut.ReconImg.cbVirAddr, 1, encOut.width * encOut.height / 4, fdRecon );fwrite( (void *)encOut.ReconImg.crVirAddr, 1, encOut.width * encOut.height / 4, fdRecon );}else{int32_t y;uint8_t *pbyTmp = (uint8_t *)encOut.ReconImg.luVirAddr;for (y=0 ; y<encOut.height ; y++){fwrite( (void *)pbyTmp, 1, encOut.width, fdRecon );pbyTmp += encOut.ReconImg.luStride;}pbyTmp = (uint8_t *)encOut.ReconImg.cbVirAddr;for (y=0 ; y<encOut.height/2 ; y++){fwrite( (void *)pbyTmp, 1, encOut.width/2, fdRecon );pbyTmp += encOut.ReconImg.cbStride;}pbyTmp = (uint8_t *)encOut.ReconImg.crVirAddr;for (y=0 ; y<encOut.height/2 ; y++){fwrite( (void *)pbyTmp, 1, encOut.width/2, fdRecon );pbyTmp += encOut.ReconImg.crStride;}}}}// if (frameCnt > 5) break;frameCnt ++;}{float TotalBps = (float)((StrmTotalSize * 8 * pAppData->fpsNum / pAppData->fpsDen) / (frameCnt * 1024));printf("[Summary]Bitrate = %.3fKBps(%.2f%), PSNR = %.3fdB, Frame Count = %d \n", TotalBps, TotalBps * 100 / pAppData->kbitrate, (PSNRSum / frameCnt), frameCnt );}}//==============================================================================// TERMINATION//==============================================================================if( fdLog ){fclose(fdLog);}if( fdIn ){fclose( fdIn );}if( fdOut ){fclose( fdOut );}if( hEnc ){NX_VidEncClose( hEnc );}#ifndef ANDROIDNX_DspClose( hDsp );
#endifreturn 0;
}int32_t VpuEncMain( CODEC_APP_DATA *pAppData )
{//  Performance Testif( pAppData->inFileName ){if( pAppData->outLogFileName == NULL ){pAppData->outLogFileName = (char*)malloc(strlen(pAppData->outFileName) + 5);strcpy(pAppData->outLogFileName, pAppData->outFileName);strcat(pAppData->outLogFileName, ".log");}return VpuEncPerfMain( pAppData );}//else//{//  return VpuCamEncMain( pAppData );//}return 0;
}

通过了一些改编写了一个相关的类,可以实现对于硬件编码的快捷使用

Vpu.cpp

#include "Vpu.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>//   getopt & optarg
#include <stdlib.h>//   atoi
#include <sys/time.h>//   gettimeofday
#include <math.h>#include <nx_fourcc.h>
#include <nx_vip.h>//   VIP
#include <nx_dsp.h>//   Display
#include <nx_video_api.h>//   Video En/Decoder#include "NX_Queue.h"
#include "Util.h"#define   MAX_SEQ_BUF_SIZE        (4*1024)
#define MAX_ENC_BUFFER          8
#define ENABLE_NV12             1enum
{MODE_NONE,DECODER_MODE,ENCODER_MODE,JPEG_MODE,MODE_MAX
};int32_t vpu:: LoadImage( uint8_t *pSrc, int32_t w, int32_t h, NX_VID_MEMORY_INFO *pImg )
{int32_t i, j;uint8_t *pDst, *pCb, *pCr;//  Copy LupDst = (uint8_t*)pImg->luVirAddr;for( i=0 ; i<h ; i++ ){memcpy(pDst, pSrc, w);pDst += pImg->luStride;pSrc += w;}pCb = pSrc;pCr = pSrc + w*h/4;uint8_t *pCbCr;pDst = (uint8_t*)pImg->cbVirAddr;for( i=0 ; i<h/2 ; i++ ){pCbCr = pDst + pImg->cbStride*i;for( j=0 ; j<w/2 ; j++ ){*pCbCr++ = *pCb++;*pCbCr++ = *pCr++;}}return 0;
}vpu::vpu(int width,int height,int Fps)
{inWidth=width;inHeight=height;seqBuffer = (unsigned char *)malloc( MAX_SEQ_BUF_SIZE );
long long totalSize = 0;
long long vipTimeStamp;
int instanceIdx;
hEnc = NX_VidEncOpen(NX_AVC_ENC, &instanceIdx);
memset( &encInitParam, 0, sizeof(encInitParam));
encInitParam.width = inWidth;
encInitParam.height = inHeight;
encInitParam.gopSize = 30/2;
encInitParam.bitrate = 1000;
encInitParam.fpsNum = Fps;
encInitParam.fpsDen = 1;
encInitParam.chromaInterleave = 1;encInitParam.enableRC = 1;
encInitParam.disableSkip = 0;
encInitParam.maximumQp = 51;
encInitParam.initialQp = 10;
encInitParam.enableAUDelimiter = 1;hInImage = NULL;
hInImage = NX_VideoAllocateMemory( 16, inWidth, inHeight, NX_MEM_MAP_LINEAR, FOURCC_NV12);encIn.timeStamp = 0;
encIn.forcedIFrame = 0;
encIn.forcedSkipFrame = 0;
encIn.quantParam = 23;
encIn.pImage = hInImage;      if (NX_VidEncInit( hEnc, &encInitParam ) != VID_ERR_NONE)
{printf("NX_VidEncInit() failed \n");exit(-1);
}printf("NX_VidEncInit() success \n");
NX_VidEncGetSeqInfo( hEnc, seqBuffer, &size );
}char*  vpu::DecodeNV12_To_H264(void *yuv420p,int *length)
{LoadImage((uint8_t*)yuv420p,inWidth , inHeight, encIn.pImage);NX_VidEncEncodeFrame( hEnc, &encIn, &encOut );*length=encOut.bufSize;char* data=(char*)encOut.outBuf;return data;
}vpu::~vpu()
{
}

Vpu.h

#ifndef VPU_H
#define VPU_H#include <unistd.h>//   getopt & optarg
#include <stdlib.h>//   atoi
#include <stdio.h>//   printf
#include <string.h>//   strdup
#include <sys/time.h>//   gettimeofday
#include <math.h>#include <nx_fourcc.h>
#include <nx_vip.h>//   VIP
#include <nx_dsp.h>//   Display
#include <nx_video_api.h>//   Video En/Decoder#include "NX_Queue.h"
#include <Util.h>class vpu
{
private:int32_t opt;int32_t mode;NX_VID_ENC_HANDLE hEnc;                    // Encoder HandleNX_VID_ENC_INIT_PARAM encInitParam;NX_VID_MEMORY_HANDLE hMem;      // Allocate Memory for Encoder InputNX_VID_MEMORY_INFO *hInImage;            // Previous Displayed Memoruint8_t *pSrcBuf ;int32_t inWidth;int32_t inHeight;FILE *fdOut;public:int32_t LoadImage( uint8_t *pSrc, int32_t w, int32_t h, NX_VID_MEMORY_INFO *pImg );char*  DecodeNV12_To_H264(void *nv12,int *length);NX_VID_ENC_IN encIn;NX_VID_ENC_OUT encOut;unsigned char *seqBuffer;int size;vpu(int width,int height,int Fps);~vpu();
};#endif

【视频处理】嵌入式硬件编码(6818)进行H264编码相关推荐

  1. 使用CUDA显卡加速SDK实现 H264编码

    CUDA(Compute Unified Device Architecture),显卡厂商NVIDIA推出的运算平台.CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂 ...

  2. Android视频编码--H264编码

    Android视频编码–H264编码 Android中的H264编码有两种编码方式: 硬编码 软编码 1.硬编码 Android中的H264硬编码主要是通过自身提供的API,调用底层的硬件模块实现编码 ...

  3. 采集音频和摄像头视频并实时H264编码及AAC编码

    0. 前言 我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法.那种方法有一些局限性,不适合实时性质的应用,如:视频会议.视频聊天.视频监控等.本文所使用的技术, ...

  4. 采集音频和摄像头视频并实时H264编码及AAC编码[转]

    0. 前言 我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法.那种方法有一些局限性,不适合实时性质的应用,如:视频会议.视频聊天.视频监控等.本文所使用的技术, ...

  5. ffmpeg的H264编码 视频逐渐模糊

    万能的互联网,又一次在临危之时解决了我的问题 最近在看ffmpeg里的H264编码,然后试着去做了一下.但是目前发现一个问题,就是编码写入的.264文件,用播放器(VLC,暴风都试过)播放后,发现编码 ...

  6. Android音视频【一】H264编码基础

    人间观察 岁月催人,时间过的太快了 音视频编码解码就是指通过特定的压缩/解压技术,将某个音视频格式的数据转换为另一种音视频格式数据.目前在Android中的音视频用的最多的就是H264+aac的方式进 ...

  7. 音视频开发系列-H264编码原理

    H264简介 来自百度百科的介绍: H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式. H.264是ITU-T以H.26x系列为名称命名的 ...

  8. FFmpeg简单使用:视频编码 ---- YUV转H264

    基本流程 从本地读取YUV数据编码为h264格式的数据,然后再存⼊到本地,编码后的数据有带startcode. 与FFmpeg 示例⾳频编码的流程基本⼀致. 函数说明: avcodec_find_en ...

  9. 流媒体播放器播放h264编码视频与h265编码视频哪个更清晰?

    h265编码是h264编码的升级版,h265目前在视频点播方面使用的更加普遍,而在视频直播方面,由于难以达到h265编码的解码速度,运用起来还是有些难度的,还需要看未来我们的流媒体技术的发展.那么既然 ...

  10. opencv录制视频 python_Python-OpenCV录制H264编码的MP4视频

    前言 因最近项目需求涉及计算机视觉相关内容,需要实现在Python录制视频,并且录制完成后可在浏览器前端中进行视频回放的功能:特写下此篇文章以记录整体实现过程. 2019-08-02 更新 之前一直在 ...

最新文章

  1. 清华团队将Transformer用到3D点云分割
  2. vc编写供vb使用的dll文档
  3. 频繁项集挖掘之Aprior和FPGrowth算法
  4. matlab语法手册下载,MATLAB及其在理工课程中的应用指南 第4版.pdf
  5. sscanf用法详解-hdu2072
  6. ExtJs2.0学习系列(6)--Ext.FormPanel之第三式(ComboBox篇)
  7. python关于二手房的课程论文_python之数据清理-以二手房信息为例
  8. Python基础——input交互功能
  9. 大数据安全分析有哪些常见问题
  10. 嵌入式系统、嵌入式设计软件概述
  11. PS 使用画笔修复工具去除文字
  12. IO IR 个人作业汇总——康熙
  13. 为什么邮件发的邮箱会进垃圾箱?企业邮箱进垃圾箱有什么处理方法?
  14. IMO班聊新版本更给力 企业用车、公费电话上线
  15. ePower入门-TLE9879连接不上JLink
  16. 工作流系统理解(1)
  17. Android手机IMEI码结构说明
  18. 100天精通Python(基础篇)——第4天:数据类型
  19. 阿里云网盘内测开启 填写申请表获取邀请码 附最新申请地址
  20. 三月随笔——漫长的等待

热门文章

  1. [CS15] Fast and Accurate Recurrent Neural Network Acoustic Models for Speech Recognition-Has¸im Sak
  2. 以太坊学习路线——(五)DApp开发:简易版去中心化微博
  3. Victoria(硬盘检测工具)v4.46F绿色版
  4. 项目三:公寓管理系统_ssm
  5. 使用STM32F103C8T6控制L298N电机驱动麦克纳姆轮小车(HAL库)
  6. 2022年全球与中国汽车毫米波雷达市场现状及未来发展趋势报告
  7. 曲线救国的就业路线是否合理?
  8. 地奥畅依笙 源于医药科技,忠于健康运动!
  9. arccotx图像在matlab,反三角函数图像与性质是什么?
  10. BUUCTF[GYCTF2020]Blacklist