cudaEncode编码详细过程如下:
一,ParseInputParams(argc, argv,&sEncoderParams)
//配置参数:输入、输出文件,配置文件,基本的参数
二,pCudaEncoder = new VideoEncoder (&sEncoderParams);
执行的详细过程:
1,fpIn= fopen(m_pEncoderParams->inputFile,"rb")输入文件
2,fpOut= fopen(m_pEncoderParams->outputFile,"wb")输出文件
3,GetEncodeParamsConfig(m_pEncoderParams)
3.1 fopen_s(&fpConfig,pParams->configFile, "r");
3.2 fscanf_s(fpConfig, "%d",&(pParams->iCodecType));
3.3 同上…(从配置文件中获取参数)
3.4 fclose(fpConfig)
三,pCudaEncoder->InitEncoder (&sEncoderParams);
执行的详细过程:
1,NVCreateEncoder(&m_pEncoder)创建用于编码的NVIDIA CUDA 视频编码器库对象
2,SetCodecType(m_pEncoderParams)设置编码类型,VC-1已经不支持啦
2.1,NVSetCodec(m_pEncoder,pParams->iCodecType)设置压缩编解码器类型,H.264或VC-1编码
3,GetGPUCount(m_pEncoderParams,&gpuPerf, &bestGPU) 看有几个GPU,我们这里只有一个GPU,别无选择
3.1,GetParamValue(NVVE_GET_GPU_COUNT, &(pParams->GPU_count))
3.1.1,NVGetParamValue(m_pEncoder,dwParamType, pData)
4,SetActiveGPU(m_pEncoderParams,m_pEncoderParams->iForcedGPU)
设置使用哪一个GPU
4.1,SetParamValue(NVVE_FORCE_GPU_SELECTION,&gpuID)
4.1.1,NVSetParamValue(m_pEncoder,dwParamType, pData)
四,pCudaEncoder->SetEncodeParameters(&sEncoderParams);
设置编码器参数
执行的详细过程:
1,SetGPUOffloadLevel(m_pEncoderParams)设置GPU使用哪一种方式,默认为最大限度的使用GPU
1.1,GetParamValue(NVVE_GPU_OFFLOAD_LEVEL_MAX, 有三个选择,先获取&eMaxOffloadLevel)
1.2,SetParamValue(NVVE_GPU_OFFLOAD_LEVEL,再设置&(pParams->GPUOffloadLevel))
2,SetParameters (m_pEncoderParams)把刚才从配置文件读取的配置信息设置为我们的参数信息
2.1,SetParamValue(NVVE_OUT_SIZE, &(pParams->iOutputSize));
2.2,同上…同前面的读取配置文件信息一样
五, pCudaEncoder->SetCBFunctions(&sCBParams, (void *)pCudaEncoder );设置响应函数,主要用在后面的编码过程中
执行的详细过程:
NVRegisterCB(m_pEncoder, m_NVCB, pUserData);
有四个响应函数,执行过程如下:
HandleOnBeginFrame(const NVVE_BeginFrameInfo *pbfi, void*pUserData)
àHandleAcquireBitStream(int*pBufferSize, void *pUserData)
àHandleReleaseBitStream(intnBytesInBuffer, unsigned char *cb,void *pUserData)
这个函数中有 fwrite(cb,1,nBytesInBuffer,pCudaEncoder->fileOut() )向264文件里面写数据
àHandleOnEndFrame(constNVVE_EndFrameInfo *pefi, void *pUserData)
六,pCudaEncoder->CreateHWEncoder(&sEncoderParams );
给编码器分配硬件资源
执行的详细过程:
1,NVCreateHWEncoder(m_pEncoder)
2,NVGetSPSPPS(m_pEncoder, buf2, 10,&size)获取包含有SPS和PPS的缓存
开始编码(循环开始)
七,pCudaEncoder->ReadNextFrame();//bytes_read=506880
执行的详细过程:
1.1,fread(m_pVideoFrame, 1, m_nVideoFrameSize,fileIn())读取yuv文件
八,pCudaEncoder->GetVideoFrame();
returnm_pVideoFrame获取缓存区,用于存储
九,pCudaEncoder->EncodeFrame(efparams, dptrVideoFrame, cuCtxLock)
执行的详细过程:
1,如果iUseDeviceMem=1的话,注意,我们测试时都是取0的,除非在VideoEncoder.h中VideoEncoder( NVEncoderParams *pParams, bool bUseDeviceMem = false);把false改为true即可
1.1,CopyYV12orIYUVFrame(sFrameParams,dptr_VideoFrame, ctxLock)格式为YV12,4:2:0
1.2,NVEncodeFrame(m_pEncoder,&sFrameParams, 0, (void *)dptr_VideoFrame);
2,正常情况下,iUseDeviceMem=0时,
NVEncodeFrame(m_pEncoder, &sFrameParams, 0,m_pSNRData)
十,computeFPS();计算每秒编码帧数,默认为16帧统计一次
以下是详细过程:
ReadNextFrame(读yuv文件)第1帧
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
->computeFPS
-> ReadNextFrame(读yuv文件)第2帧
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
-> HandleOnBeginFrame
-> HandleAcquireBitStream
->computeFPS
-> ReadNextFrame(读yuv文件)第3-8帧
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
->computeFPS
-> ReadNextFrame(读yuv文件)第9帧(从第9帧才开始写入264文件)
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
->HandleReleaseBitStream(写入264文件)第1帧
->HandleOnEndFrame
-> HandleOnBeginFrame
-> HandleAcquireBitStream
->computeFPS
-> ReadNextFrame(读yuv文件)第10帧
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
->HandleReleaseBitStream注意此时264文件中没有写入第2帧
->HandleOnEndFrame
-> HandleOnBeginFrame
-> HandleAcquireBitStream
->computeFPS
-> ReadNextFrame(读yuv文件)第11帧
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
->HandleReleaseBitStream注意此时,一次写了第2和第3帧
->HandleOnEndFrame
-> HandleOnBeginFrame
-> HandleAcquireBitStream
->computeFPS
-> ReadNextFrame(读yuv文件)第12-60帧
-> GetVideoFrame
-> EncodeFrame
->NVEncodeFrame
->HandleReleaseBitStream写入264文件第4-52帧
->HandleOnEndFrame
-> HandleOnBeginFrame
-> HandleAcquireBitStream
->computeFPS
yuv文件总共60帧已全部读取,则下面过程一直循环直至编码够60帧
->HandleReleaseBitStream
->HandleOnEndFrame
-> HandleOnBeginFrame
-> HandleAcquireBitStream
之后
->computeFPS
编码结束
总结:从编码流程可以看出来,前面8帧输入缓存中,从第9帧开始编码为264文件。当第60帧读取完,不再读取,一直编码输出,直至输出60帧。