最近有个海康DVR转rtmp的项目,准备用openh264试试,相比x264性能非常强,但相同码率下画质不如x264
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nUser,long nReserved2) { hik_player_t *hp = (hik_player_t *)nUser; long lFrameType = pFrameInfo->nType; if (lFrameType ==T_AUDIO16) { printf("Audio nStamp:%d size:%d pFrameInfo:%dn",pFrameInfo->nStamp,nSize,pFrameInfo->nFrameRate); } else if(lFrameType ==T_YV12) { if(hp->in_width == 0 || hp->in_height == 0) { hp->in_width = pFrameInfo->nWidth; hp->in_height = pFrameInfo->nHeight; avpicture_alloc(&hp->in_yuv, AV_PIX_FMT_YUV420P, hp->in_width, hp->in_height); avpicture_alloc(&hp->out_yuv, AV_PIX_FMT_YUV420P, hp->out_width, hp->out_height); WelsCreateSVCEncoder(&hp->encoder_); //initilize with basic parameter SEncParamExt param; memset (¶m, 0, sizeof (SEncParamBase)); hp->encoder_->GetDefaultParams(¶m); param.iUsageType = CAMERA_VIDEO_REAL_TIME; param.fMaxFrameRate = pFrameInfo->nFrameRate; param.iPicWidth = hp->out_width; param.iPicHeight = hp->out_height; param.iTargetBitrate = hp->out_bitrate; param.iRCMode = RC_QUALITY_MODE; param.iTemporalLayerNum = 1; param.iSpatialLayerNum = 1; param.bEnableDenoise = 0; param.bEnableBackgroundDetection = 1; param.bEnableAdaptiveQuant = 1; // param.bEnableFrameSkip = 0; param.bEnableLongTermReference = 0; param.iLtrMarkPeriod = 30; param.uiIntraPeriod = (unsigned int)pFrameInfo->nFrameRate*2; param.eSpsPpsIdStrategy = CONSTANT_ID; param.bPrefixNalAddingCtrl = 0; param.sSpatialLayers[0].iVideoWidth = param.iPicWidth; param.sSpatialLayers[0].iVideoHeight = param.iPicHeight; param.sSpatialLayers[0].fFrameRate = param.fMaxFrameRate; param.sSpatialLayers[0].iSpatialBitrate = param.iTargetBitrate; param.sSpatialLayers[0].iMaxSpatialBitrate = param.iMaxBitrate; hp->encoder_->InitializeExt(¶m); // hp->encoder_->Initialize(¶m); //set option, set option during encoding process // int g_LevelSetting = 0; // hp->encoder_->SetOption(ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting); int videoFormat = videoFormatI420; hp->encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, &videoFormat); hp->file = fopen("d:\out.h264","wb+"); } //printf("Video nStamp:%d size:%d width:%d height:%d fps:%d n",pFrameInfo->nStamp,nSize,pFrameInfo->nWidth,pFrameInfo->nHeight,pFrameInfo->nFrameRate); avpicture_fill(&hp->in_yuv,(const uint8_t*)pBuf, AV_PIX_FMT_YUV420P,hp->in_width,hp->in_height); libyuv::I420Scale(hp->in_yuv.data[0],hp->in_yuv.linesize[0], hp->in_yuv.data[1],hp->in_yuv.linesize[1], hp->in_yuv.data[2],hp->in_yuv.linesize[2], hp->in_width,hp->in_height, hp->out_yuv.data[0],hp->out_yuv.linesize[0], hp->out_yuv.data[1],hp->out_yuv.linesize[1], hp->out_yuv.data[2],hp->out_yuv.linesize[2], hp->out_width,hp->out_height,libyuv::kFilterNone); SFrameBSInfo info; memset(&info, 0, sizeof (SFrameBSInfo)); SSourcePicture pic; memset (&pic, 0, sizeof (SSourcePicture)); pic.iPicWidth = hp->out_width; pic.iPicHeight = hp->out_height; pic.iColorFormat = videoFormatI420; pic.iStride[0] = hp->out_yuv.linesize[0]; pic.iStride[1] = pic.iStride[2] = hp->out_yuv.linesize[1]; pic.pData[0] = hp->out_yuv.data[0]; pic.pData[1] = hp->out_yuv.data[1]; pic.pData[2] = hp->out_yuv.data[2]; int ret = hp->encoder_->EncodeFrame(&pic, &info); if(info.eFrameType != videoFrameTypeSkip ) { if(info.eFrameType == videoFrameTypeIDR) { // printf("key framen"); } int first_layer = 0; if(hp->have_spspps) { first_layer = info.iLayerNum - 1; } else { hp->have_spspps = true; } for(int i=first_layer;i<info.iLayerNum;i++) { //printf("Layer:%d NalCount:%dn",i,info.sLayerInfo[i].iNalCount); int pos = 0; for (int j = 0; j < info.sLayerInfo[i].iNalCount; j++) { // printf("%d %d iFrameSizeInBytes:%d NalLengthInByte: %dn",i,j,info.iFrameSizeInBytes, info.sLayerInfo[i].pNalLengthInByte[j]); fwrite(info.sLayerInfo[i].pBsBuf+pos,*info.sLayerInfo[i].pNalLengthInByte,1,hp->file); pos+=*info.sLayerInfo[i].pNalLengthInByte; } } // } /* if (encoder_) { encoder_->Uninitialize(); WelsDestroySVCEncoder (encoder_); } */ } else { } } |
原创文章,转载请注明: 转载自贝壳博客
本文链接地址: 一段海康SDK解码回调后缩放并用openh264编码的代码
请问您文中提到的“性能非常强”、是指ciscoOpenH264的编码速度比x264要快吗?谢谢!
是的
请问 用openh264编码之前都要转一次yuv420吗?
我用android的编码格式本身就是yuv420还要么
本身是yuv420就不用啦,如果你是从摄像头取出来的,有可能是NV21,那需要转一下
您好!我搞了好几天openh264编码,编码没有错误提示,但info.iLayerNum始终为0,是参数不对还是yuv数据有错?求提示!
刚才邮箱地址有误。