日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/3/12 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【视频处理】嵌入式硬件编码(6818)进行H264编码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有一個需要進行硬件編碼的項目,因為板子給的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编码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。