From: Vic Lee Date: Tue, 21 Apr 2015 05:59:01 +0000 (+0800) Subject: h264: change encoder api and add multi-thread support. X-Git-Tag: 2.0.0-beta1+android10~593^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=93d59ac3de03993d194ccecdc8540b9b9127054f;p=platform%2Fupstream%2Ffreerdp.git h264: change encoder api and add multi-thread support. --- diff --git a/include/freerdp/codec/h264.h b/include/freerdp/codec/h264.h index a8a33c3..b802082 100644 --- a/include/freerdp/codec/h264.h +++ b/include/freerdp/codec/h264.h @@ -30,7 +30,7 @@ typedef BOOL (*pfnH264SubsystemInit)(H264_CONTEXT* h264); typedef void (*pfnH264SubsystemUninit)(H264_CONTEXT* h264); typedef int (*pfnH264SubsystemDecompress)(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize); -typedef int (*pfnH264SubsystemCompress)(H264_CONTEXT* h264, UINT32 TargetFrameSizeInBits, BYTE** ppDstData, UINT32* pDstSize); +typedef int (*pfnH264SubsystemCompress)(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize); struct _H264_CONTEXT_SUBSYSTEM { @@ -48,6 +48,10 @@ struct _H264_CONTEXT UINT32 width; UINT32 height; + + UINT32 BitRate; + FLOAT FrameRate; + UINT32 NumberOfThreads; int iStride[3]; BYTE* pYUVData[3]; @@ -61,8 +65,7 @@ extern "C" { #endif FREERDP_API int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, - int nSrcStep, int nSrcWidth, int nSrcHeight, UINT32 TargetFrameSizeInBits, - BYTE** ppDstData, UINT32* pDstSize); + int nSrcStep, int nSrcWidth, int nSrcHeight, BYTE** ppDstData, UINT32* pDstSize); FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstWidth, int nDstHeight, diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index b731f62..846dec0 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -71,7 +71,7 @@ struct _H264_CONTEXT_OPENH264 { ISVCDecoder* pDecoder; ISVCEncoder* pEncoder; - SEncParamBase EncParamBase; + SEncParamExt EncParamExt; }; typedef struct _H264_CONTEXT_OPENH264 H264_CONTEXT_OPENH264; @@ -150,7 +150,7 @@ static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSiz return 1; } -static int openh264_compress(H264_CONTEXT* h264, UINT32 TargetFrameSizeInBits, BYTE** ppDstData, UINT32* pDstSize) +static int openh264_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize) { int i, j; int status; @@ -165,17 +165,41 @@ static int openh264_compress(H264_CONTEXT* h264, UINT32 TargetFrameSizeInBits, B if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2]) return -1; - if (sys->EncParamBase.iPicWidth != h264->width || - sys->EncParamBase.iPicHeight != h264->height) + if (sys->EncParamExt.iPicWidth != h264->width || + sys->EncParamExt.iPicHeight != h264->height) { - sys->EncParamBase.iUsageType = SCREEN_CONTENT_REAL_TIME; - sys->EncParamBase.iPicWidth = h264->width; - sys->EncParamBase.iPicHeight = h264->height; - sys->EncParamBase.iTargetBitrate = TargetFrameSizeInBits * 30; - sys->EncParamBase.iRCMode = RC_BITRATE_MODE; - sys->EncParamBase.fMaxFrameRate = 30.0f; + status = (*sys->pEncoder)->GetDefaultParams(sys->pEncoder, &sys->EncParamExt); - status = (*sys->pEncoder)->Initialize(sys->pEncoder, &sys->EncParamBase); + if (status < 0) + { + WLog_ERR(TAG, "Failed to get OpenH264 default parameters (status=%ld)", status); + return status; + } + + sys->EncParamExt.iUsageType = SCREEN_CONTENT_REAL_TIME; + sys->EncParamExt.iPicWidth = h264->width; + sys->EncParamExt.iPicHeight = h264->height; + sys->EncParamExt.iTargetBitrate = h264->BitRate; + sys->EncParamExt.iRCMode = RC_BITRATE_MODE; + sys->EncParamExt.fMaxFrameRate = h264->FrameRate; + sys->EncParamExt.iMaxBitrate = UNSPECIFIED_BIT_RATE; + sys->EncParamExt.bEnableDenoise = 0; + sys->EncParamExt.bEnableLongTermReference = 0; + sys->EncParamExt.bEnableFrameSkip = 0; + sys->EncParamExt.iSpatialLayerNum = 1; + sys->EncParamExt.iMultipleThreadIdc = h264->NumberOfThreads; + sys->EncParamExt.sSpatialLayers[0].fFrameRate = h264->FrameRate; + sys->EncParamExt.sSpatialLayers[0].iVideoWidth = sys->EncParamExt.iPicWidth; + sys->EncParamExt.sSpatialLayers[0].iVideoHeight = sys->EncParamExt.iPicHeight; + sys->EncParamExt.sSpatialLayers[0].iSpatialBitrate = sys->EncParamExt.iTargetBitrate; + sys->EncParamExt.sSpatialLayers[0].iMaxSpatialBitrate = sys->EncParamExt.iMaxBitrate; + + if (sys->EncParamExt.iMultipleThreadIdc > 1) + { + sys->EncParamExt.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_AUTO_SLICE; + } + + status = (*sys->pEncoder)->InitializeExt(sys->pEncoder, &sys->EncParamExt); if (status < 0) { @@ -183,18 +207,35 @@ static int openh264_compress(H264_CONTEXT* h264, UINT32 TargetFrameSizeInBits, B return status; } } - else if (sys->EncParamBase.iTargetBitrate != TargetFrameSizeInBits * 30) + else { - sys->EncParamBase.iTargetBitrate = TargetFrameSizeInBits * 30; - bitrate.iLayer = SPATIAL_LAYER_ALL; - bitrate.iBitrate = TargetFrameSizeInBits * 30; + if (sys->EncParamExt.iTargetBitrate != h264->BitRate) + { + sys->EncParamExt.iTargetBitrate = h264->BitRate; + bitrate.iLayer = SPATIAL_LAYER_ALL; + bitrate.iBitrate = h264->BitRate; - status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_BITRATE, &bitrate); + status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_BITRATE, + &bitrate); - if (status < 0) + if (status < 0) + { + WLog_ERR(TAG, "Failed to set encoder bitrate (status=%ld)", status); + return status; + } + } + if (sys->EncParamExt.fMaxFrameRate != h264->FrameRate) { - WLog_ERR(TAG, "Failed to set encoder bitrate (status=%ld)", status); - return status; + sys->EncParamExt.fMaxFrameRate = h264->FrameRate; + + status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_FRAME_RATE, + &sys->EncParamExt.fMaxFrameRate); + + if (status < 0) + { + WLog_ERR(TAG, "Failed to set encoder framerate (status=%ld)", status); + return status; + } } } @@ -598,8 +639,7 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, } int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, - int nSrcStep, int nSrcWidth, int nSrcHeight, UINT32 TargetFrameSizeInBits, - BYTE** ppDstData, UINT32* pDstSize) + int nSrcStep, int nSrcWidth, int nSrcHeight, BYTE** ppDstData, UINT32* pDstSize) { int status; prim_size_t roi; @@ -626,7 +666,7 @@ int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, prims->RGBToYUV420_8u_P3AC4R(pSrcData, nSrcStep, h264->pYUVData, h264->iStride, &roi); - status = h264->subsystem->Compress(h264, TargetFrameSizeInBits, ppDstData, pDstSize); + status = h264->subsystem->Compress(h264, ppDstData, pDstSize); free(h264->pYUVData[0]); free(h264->pYUVData[1]); @@ -676,6 +716,13 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) h264->subsystem = &g_Subsystem_dummy; + if (Compressor) + { + /* Default compressor settings, may be changed by caller */ + h264->BitRate = 1000000; + h264->FrameRate = 30; + } + if (!h264_context_init(h264)) { free(h264);