break; case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: { int32_t iValue = * (static_cast<int32_t*> (pOption)); EParameterSetStrategy eNewStrategy = CONSTANT_ID; switch (iValue) { case 0: eNewStrategy = CONSTANT_ID; break; case 0x01: eNewStrategy = INCREASING_ID; break; case 0x02: eNewStrategy = SPS_LISTING; break; case 0x03: eNewStrategy = SPS_LISTING_AND_PPS_INCREASING; break; case 0x06: eNewStrategy = SPS_PPS_LISTING; break; default: WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy(%d) not in valid range, unchanged! existing=%d", iValue, m_pEncContext->pSvcParam->eSpsPpsIdStrategy); break; } if (((eNewStrategy & SPS_LISTING) || (m_pEncContext->pSvcParam->eSpsPpsIdStrategy & SPS_LISTING)) && m_pEncContext->pSvcParam->eSpsPpsIdStrategy != eNewStrategy) { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy changing in the middle of call is NOT allowed for eSpsPpsIdStrategy>INCREASING_ID: existing setting is %d and the new one is %d", m_pEncContext->pSvcParam->eSpsPpsIdStrategy, iValue); return cmInitParaError; } m_pEncContext->pSvcParam->eSpsPpsIdStrategy = eNewStrategy; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy = %d ", m_pEncContext->pSvcParam->eSpsPpsIdStrategy); } break; case ENCODER_OPTION_CURRENT_PATH: { if (m_pEncContext->pSvcParam != NULL) { char* path = static_cast<char*> (pOption); m_pEncContext->pSvcParam->pCurPath = path; } } break; case ENCODER_OPTION_DUMP_FILE: {#ifdef ENABLE_FRAME_DUMP if (m_pEncContext->pSvcParam != NULL) { SDumpLayer* pDump = (static_cast<SDumpLayer*> (pOption)); WelsStrncpy (m_pEncContext->pSvcParam->sDependencyLayers[pDump->iLayer].sRecFileName, sizeof (m_pEncContext->pSvcParam->sDependencyLayers[pDump->iLayer].sRecFileName), pDump->pFileName); }#endif } break; case ENCODER_OPTION_TRACE_LEVEL: { if (m_pWelsTrace) { uint32_t level = * ((uint32_t*)pOption); m_pWelsTrace->SetTraceLevel (level); } } break; case ENCODER_OPTION_TRACE_CALLBACK: { if (m_pWelsTrace) { WelsTraceCallback callback = * ((WelsTraceCallback*)pOption); m_pWelsTrace->SetTraceCallback (callback); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_TRACE_CALLBACK callback = %p.", callback); } } break; case ENCODER_OPTION_TRACE_CALLBACK_CONTEXT: { if (m_pWelsTrace) { void* ctx = * ((void**)pOption); m_pWelsTrace->SetTraceCallbackContext (ctx); } } break; case ENCODER_OPTION_PROFILE: { SProfileInfo* pProfileInfo = (static_cast<SProfileInfo*> (pOption)); if ((pProfileInfo->iLayer < SPATIAL_LAYER_0) || (pProfileInfo->iLayer > SPATIAL_LAYER_3)) { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_PROFILE,iLayer = %d(rang0-3)", pProfileInfo->iLayer); return cmInitParaError; } CheckProfileSetting (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, pProfileInfo->iLayer, pProfileInfo->uiProfileIdc); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_PROFILE,layerId = %d,expected profile = %d,actual profile = %d", pProfileInfo->iLayer, pProfileInfo->uiProfileIdc, m_pEncContext->pSvcParam->sSpatialLayers[pProfileInfo->iLayer].uiProfileIdc); } break; case ENCODER_OPTION_LEVEL: { SLevelInfo* pLevelInfo = (static_cast<SLevelInfo*> (pOption)); if ((pLevelInfo->iLayer < SPATIAL_LAYER_0) || (pLevelInfo->iLayer > SPATIAL_LAYER_3)) { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_PROFILE,iLayer = %d(rang0-3)", pLevelInfo->iLayer); return cmInitParaError; } CheckLevelSetting (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, pLevelInfo->iLayer, pLevelInfo->uiLevelIdc); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_LEVEL,layerId = %d,expected level = %d,actual level = %d", pLevelInfo->iLayer, pLevelInfo->uiLevelIdc, m_pEncContext->pSvcParam->sSpatialLayers[pLevelInfo->iLayer].uiLevelIdc); } break; case ENCODER_OPTION_NUMBER_REF: { int32_t iValue = * ((int32_t*)pOption); CheckReferenceNumSetting (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, iValue); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_NUMBER_REF,expected refNum = %d,actual refnum = %d", iValue, m_pEncContext->pSvcParam->iNumRefFrame); } break; case ENCODER_OPTION_DELIVERY_STATUS: { SDeliveryStatus* pValue = (static_cast<SDeliveryStatus*> (pOption)); m_pEncContext->bDeliveryFlag = pValue->bDeliveryFlag; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_DELIVERY_STATUS,bDeliveryFlag = %d", pValue->bDeliveryFlag); } break; case ENCODER_OPTION_COMPLEXITY: { int32_t iValue = * (static_cast<int32_t*> (pOption)); m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_COMPLEXITY,iComplexityMode = %d", iValue); } break; case ENCODER_OPTION_GET_STATISTICS: { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_GET_STATISTICS: this option is get-only!"); } break; case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: { int32_t iValue = * (static_cast<int32_t*> (pOption)); m_pEncContext->iStatisticsLogInterval = iValue; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_STATISTICS_LOG_INTERVAL,iStatisticsLogInterval = %d", iValue); } break; case ENCODER_OPTION_IS_LOSSLESS_LINK: { bool bValue = * (static_cast<bool*> (pOption)); m_pEncContext->pSvcParam->bIsLosslessLink = bValue; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_IS_LOSSLESS_LINK,bIsLosslessLink = %d", bValue); } break; case ENCODER_OPTION_BITS_VARY_PERCENTAGE: { int32_t iValue = * (static_cast<int32_t*> (pOption)); m_pEncContext->pSvcParam->iBitsVaryPercentage = WELS_CLIP3 (iValue, 0, 100); WelsEncoderApplyBitVaryRang (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, m_pEncContext->pSvcParam->iBitsVaryPercentage); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITS_VARY_PERCENTAGE,iBitsVaryPercentage = %d", iValue); } break; default: return cmInitParaError; } return 0;} int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) { if (NULL == pOption) { return cmInitParaError; } if (NULL == m_pEncContext || false == m_bInitialFlag) { return cmInitExpected; } switch (eOptionId) { case ENCODER_OPTION_INTER_SPATIAL_PRED: { // Inter spatial layer prediction flag WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ENCODER_OPTION_INTER_SPATIAL_PRED, this feature not supported at present."); } break; case ENCODER_OPTION_DATAFORMAT: { // Input color space WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_DATAFORMAT, m_iCspInternal= 0x%x", m_iCspInternal); * ((int32_t*)pOption) = m_iCspInternal; } break; case ENCODER_OPTION_IDR_INTERVAL: { // IDR Interval WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_IDR_INTERVAL, uiIntraPeriod= %d", m_pEncContext->pSvcParam->uiIntraPeriod); * ((int32_t*)pOption) = m_pEncContext->pSvcParam->uiIntraPeriod; } break; case ENCODER_OPTION_SVC_ENCODE_PARAM_EXT: { // SVC Encoding Parameter WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT"); memcpy (pOption, m_pEncContext->pSvcParam, sizeof (SEncParamExt)); // confirmed_safe_unsafe_usage } break; case ENCODER_OPTION_SVC_ENCODE_PARAM_BASE: { // SVC Encoding Parameter WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_BASE"); m_pEncContext->pSvcParam->GetBaseParams ((SEncParamBase*) pOption); } break; case ENCODER_OPTION_FRAME_RATE: { // Maximal input frame rate WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_FRAME_RATE, fMaxFrameRate = %.6ff", m_pEncContext->pSvcParam->fMaxFrameRate); * ((float*)pOption) = m_pEncContext->pSvcParam->fMaxFrameRate; } break; case ENCODER_OPTION_BITRATE: { // Target bit-rate SBitrateInfo* pInfo = (static_cast<SBitrateInfo*> (pOption)); if ((pInfo->iLayer != SPATIAL_LAYER_ALL) && (pInfo->iLayer != SPATIAL_LAYER_0) && (pInfo->iLayer != SPATIAL_LAYER_1) && (pInfo->iLayer != SPATIAL_LAYER_2) && (pInfo->iLayer != SPATIAL_LAYER_3)) return cmInitParaError; if (pInfo->iLayer == SPATIAL_LAYER_ALL) { pInfo->iBitrate = m_pEncContext->pSvcParam->iTargetBitrate; } else { pInfo->iBitrate = m_pEncContext->pSvcParam->sSpatialLayers[pInfo->iLayer].iSpatialBitrate; } WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_BITRATE, layerId =%d,iBitrate = %d", pInfo->iLayer, pInfo->iBitrate); } break; case ENCODER_OPTION_MAX_BITRATE: { // Target bit-rate SBitrateInfo* pInfo = (static_cast<SBitrateInfo*> (pOption)); if ((pInfo->iLayer != SPATIAL_LAYER_ALL) && (pInfo->iLayer != SPATIAL_LAYER_0) && (pInfo->iLayer != SPATIAL_LAYER_1) && (pInfo->iLayer != SPATIAL_LAYER_2) && (pInfo->iLayer != SPATIAL_LAYER_3)) return cmInitParaError; if (pInfo->iLayer == SPATIAL_LAYER_ALL) { pInfo->iBitrate = m_pEncContext->pSvcParam->iMaxBitrate; } else { pInfo->iBitrate = m_pEncContext->pSvcParam->sSpatialLayers[pInfo->iLayer].iMaxSpatialBitrate; } WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_MAX_BITRATE,, layerId =%d,iBitrate = %d", pInfo->iLayer, pInfo->iBitrate); } break; case ENCODER_OPTION_GET_STATISTICS: { SEncoderStatistics* pStatistics = (static_cast<SEncoderStatistics*> (pOption)); SEncoderStatistics* pEncStatistics = &m_pEncContext->sEncoderStatistics[m_pEncContext->pSvcParam->iSpatialLayerNum - 1]; pStatistics->uiWidth = pEncStatistics->uiWidth; pStatistics->uiHeight = pEncStatistics->uiHeight; pStatistics->fAverageFrameSpeedInMs = pEncStatistics->fAverageFrameSpeedInMs; // rate control related pStatistics->fAverageFrameRate = pEncStatistics->fAverageFrameRate; pStatistics->fLatestFrameRate = pEncStatistics->fLatestFrameRate; pStatistics->uiBitRate = pEncStatistics->uiBitRate; pStatistics->uiInputFrameCount = pEncStatistics->uiInputFrameCount; pStatistics->uiSkippedFrameCount = pEncStatistics->uiSkippedFrameCount; pStatistics->uiResolutionChangeTimes = pEncStatistics->uiResolutionChangeTimes; pStatistics->uiIDRReqNum = pEncStatistics->uiIDRReqNum; pStatistics->uiIDRSentNum = pEncStatistics->uiIDRSentNum; pStatistics->uiLTRSentNum = pEncStatistics->uiLTRSentNum; } break; case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: { * ((int32_t*)pOption) = m_pEncContext->iStatisticsLogInterval; } break; case ENCODER_OPTION_COMPLEXITY: { * ((int32_t*)pOption) = m_pEncContext->pSvcParam->iComplexityMode; } break; default: return cmInitParaError; } return 0;} void CWelsH264SVCEncoder::DumpSrcPicture (const uint8_t* pSrc) {#ifdef DUMP_SRC_PICTURE FILE* pFile = NULL; char strFileName[256] = {0}; const int32_t iDataLength = m_iMaxPicWidth * m_iMaxPicHeight; WelsStrncpy (strFileName, 256, "pic_in_"); // confirmed_safe_unsafe_usage if (m_iMaxPicWidth == 640) { WelsStrcat (strFileName, 256, "360p."); // confirmed_safe_unsafe_usage } else if (m_iMaxPicWidth == 320) { WelsStrcat (strFileName, 256, "180p."); // confirmed_safe_unsafe_usage } else if (m_iMaxPicWidth == 160) { WelsStrcat (strFileName, 256, "90p."); // confirmed_safe_unsafe_usage } switch (m_iCspInternal) { case videoFormatI420: case videoFormatYV12: WelsStrcat (strFileName, 256, "yuv"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); // WelsLog( &m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "WELS_CSP_I420, m_iCspInternal= 0x%x", m_iCspInternal); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), (iDataLength * 3) >> 1, pFile); fflush (pFile); fclose (pFile); } break; case videoFormatRGB: WelsStrcat (strFileName, 256, "rgb"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), iDataLength * 3, pFile); fflush (pFile); fclose (pFile); } case videoFormatBGR: WelsStrcat (strFileName, 256, "bgr"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); // WelsLog( &m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "WELS_CSP_BGR, m_iCspInternal= 0x%x", m_iCspInternal); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), iDataLength * 3, pFile); fflush (pFile); fclose (pFile); } break; case videoFormatYUY2: WelsStrcat (strFileName, 256, "yuy2"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), (CALC_BI_STRIDE (m_iMaxPicWidth, 16)) * m_iMaxPicHeight, pFile); fflush (pFile); fclose (pFile); } break; default: WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "Exclusive case, m_iCspInternal= 0x%x", m_iCspInternal); break; }#endif//DUMP_SRC_PICTURE return;}} using namespace WelsEnc; int32_t WelsCreateSVCEncoder (ISVCEncoder** ppEncoder) { if ((*ppEncoder = new CWelsH264SVCEncoder()) != NULL) { return 0; } return 1;} void WelsDestroySVCEncoder (ISVCEncoder* pEncoder) { CWelsH264SVCEncoder* pSVCEncoder = (CWelsH264SVCEncoder*)pEncoder; if (pSVCEncoder) { delete pSVCEncoder; pSVCEncoder = NULL; }} OpenH264Version WelsGetCodecVersion() { return g_stCodecVersion;} void WelsGetCodecVersionEx (OpenH264Version* pVersion) { *pVersion = g_stCodecVersion;}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////Lines 1001–1370 of 1370. Previous lines
break; case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: { int32_t iValue = * (static_cast<int32_t*> (pOption)); EParameterSetStrategy eNewStrategy = CONSTANT_ID; switch (iValue) { case 0: eNewStrategy = CONSTANT_ID; break; case 0x01: eNewStrategy = INCREASING_ID; break; case 0x02: eNewStrategy = SPS_LISTING; break; case 0x03: eNewStrategy = SPS_LISTING_AND_PPS_INCREASING; break; case 0x06: eNewStrategy = SPS_PPS_LISTING; break; default: WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy(%d) not in valid range, unchanged! existing=%d", iValue, m_pEncContext->pSvcParam->eSpsPpsIdStrategy); break; } if (((eNewStrategy & SPS_LISTING) || (m_pEncContext->pSvcParam->eSpsPpsIdStrategy & SPS_LISTING)) && m_pEncContext->pSvcParam->eSpsPpsIdStrategy != eNewStrategy) { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy changing in the middle of call is NOT allowed for eSpsPpsIdStrategy>INCREASING_ID: existing setting is %d and the new one is %d", m_pEncContext->pSvcParam->eSpsPpsIdStrategy, iValue); return cmInitParaError; } m_pEncContext->pSvcParam->eSpsPpsIdStrategy = eNewStrategy; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy = %d ", m_pEncContext->pSvcParam->eSpsPpsIdStrategy); } break; case ENCODER_OPTION_CURRENT_PATH: { if (m_pEncContext->pSvcParam != NULL) { char* path = static_cast<char*> (pOption); m_pEncContext->pSvcParam->pCurPath = path; } } break; case ENCODER_OPTION_DUMP_FILE: { #ifdef ENABLE_FRAME_DUMP if (m_pEncContext->pSvcParam != NULL) { SDumpLayer* pDump = (static_cast<SDumpLayer*> (pOption)); WelsStrncpy (m_pEncContext->pSvcParam->sDependencyLayers[pDump->iLayer].sRecFileName, sizeof (m_pEncContext->pSvcParam->sDependencyLayers[pDump->iLayer].sRecFileName), pDump->pFileName); } #endif } break; case ENCODER_OPTION_TRACE_LEVEL: { if (m_pWelsTrace) { uint32_t level = * ((uint32_t*)pOption); m_pWelsTrace->SetTraceLevel (level); } } break; case ENCODER_OPTION_TRACE_CALLBACK: { if (m_pWelsTrace) { WelsTraceCallback callback = * ((WelsTraceCallback*)pOption); m_pWelsTrace->SetTraceCallback (callback); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_TRACE_CALLBACK callback = %p.", callback); } } break; case ENCODER_OPTION_TRACE_CALLBACK_CONTEXT: { if (m_pWelsTrace) { void* ctx = * ((void**)pOption); m_pWelsTrace->SetTraceCallbackContext (ctx); } } break; case ENCODER_OPTION_PROFILE: { SProfileInfo* pProfileInfo = (static_cast<SProfileInfo*> (pOption)); if ((pProfileInfo->iLayer < SPATIAL_LAYER_0) || (pProfileInfo->iLayer > SPATIAL_LAYER_3)) { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_PROFILE,iLayer = %d(rang0-3)", pProfileInfo->iLayer); return cmInitParaError; } CheckProfileSetting (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, pProfileInfo->iLayer, pProfileInfo->uiProfileIdc); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_PROFILE,layerId = %d,expected profile = %d,actual profile = %d", pProfileInfo->iLayer, pProfileInfo->uiProfileIdc, m_pEncContext->pSvcParam->sSpatialLayers[pProfileInfo->iLayer].uiProfileIdc); } break; case ENCODER_OPTION_LEVEL: { SLevelInfo* pLevelInfo = (static_cast<SLevelInfo*> (pOption)); if ((pLevelInfo->iLayer < SPATIAL_LAYER_0) || (pLevelInfo->iLayer > SPATIAL_LAYER_3)) { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_PROFILE,iLayer = %d(rang0-3)", pLevelInfo->iLayer); return cmInitParaError; } CheckLevelSetting (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, pLevelInfo->iLayer, pLevelInfo->uiLevelIdc); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_LEVEL,layerId = %d,expected level = %d,actual level = %d", pLevelInfo->iLayer, pLevelInfo->uiLevelIdc, m_pEncContext->pSvcParam->sSpatialLayers[pLevelInfo->iLayer].uiLevelIdc); } break; case ENCODER_OPTION_NUMBER_REF: { int32_t iValue = * ((int32_t*)pOption); CheckReferenceNumSetting (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, iValue); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_NUMBER_REF,expected refNum = %d,actual refnum = %d", iValue, m_pEncContext->pSvcParam->iNumRefFrame); } break; case ENCODER_OPTION_DELIVERY_STATUS: { SDeliveryStatus* pValue = (static_cast<SDeliveryStatus*> (pOption)); m_pEncContext->bDeliveryFlag = pValue->bDeliveryFlag; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_DELIVERY_STATUS,bDeliveryFlag = %d", pValue->bDeliveryFlag); } break; case ENCODER_OPTION_COMPLEXITY: { int32_t iValue = * (static_cast<int32_t*> (pOption)); m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_COMPLEXITY,iComplexityMode = %d", iValue); } break; case ENCODER_OPTION_GET_STATISTICS: { WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_GET_STATISTICS: this option is get-only!"); } break; case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: { int32_t iValue = * (static_cast<int32_t*> (pOption)); m_pEncContext->iStatisticsLogInterval = iValue; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_STATISTICS_LOG_INTERVAL,iStatisticsLogInterval = %d", iValue); } break; case ENCODER_OPTION_IS_LOSSLESS_LINK: { bool bValue = * (static_cast<bool*> (pOption)); m_pEncContext->pSvcParam->bIsLosslessLink = bValue; WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_IS_LOSSLESS_LINK,bIsLosslessLink = %d", bValue); } break; case ENCODER_OPTION_BITS_VARY_PERCENTAGE: { int32_t iValue = * (static_cast<int32_t*> (pOption)); m_pEncContext->pSvcParam->iBitsVaryPercentage = WELS_CLIP3 (iValue, 0, 100); WelsEncoderApplyBitVaryRang (&m_pWelsTrace->m_sLogCtx, m_pEncContext->pSvcParam, m_pEncContext->pSvcParam->iBitsVaryPercentage); WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITS_VARY_PERCENTAGE,iBitsVaryPercentage = %d", iValue); } break; default: return cmInitParaError; } return 0; } int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) { if (NULL == pOption) { return cmInitParaError; } if (NULL == m_pEncContext || false == m_bInitialFlag) { return cmInitExpected; } switch (eOptionId) { case ENCODER_OPTION_INTER_SPATIAL_PRED: { // Inter spatial layer prediction flag WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ENCODER_OPTION_INTER_SPATIAL_PRED, this feature not supported at present."); } break; case ENCODER_OPTION_DATAFORMAT: { // Input color space WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_DATAFORMAT, m_iCspInternal= 0x%x", m_iCspInternal); * ((int32_t*)pOption) = m_iCspInternal; } break; case ENCODER_OPTION_IDR_INTERVAL: { // IDR Interval WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_IDR_INTERVAL, uiIntraPeriod= %d", m_pEncContext->pSvcParam->uiIntraPeriod); * ((int32_t*)pOption) = m_pEncContext->pSvcParam->uiIntraPeriod; } break; case ENCODER_OPTION_SVC_ENCODE_PARAM_EXT: { // SVC Encoding Parameter WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT"); memcpy (pOption, m_pEncContext->pSvcParam, sizeof (SEncParamExt)); // confirmed_safe_unsafe_usage } break; case ENCODER_OPTION_SVC_ENCODE_PARAM_BASE: { // SVC Encoding Parameter WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_BASE"); m_pEncContext->pSvcParam->GetBaseParams ((SEncParamBase*) pOption); } break; case ENCODER_OPTION_FRAME_RATE: { // Maximal input frame rate WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_FRAME_RATE, fMaxFrameRate = %.6ff", m_pEncContext->pSvcParam->fMaxFrameRate); * ((float*)pOption) = m_pEncContext->pSvcParam->fMaxFrameRate; } break; case ENCODER_OPTION_BITRATE: { // Target bit-rate SBitrateInfo* pInfo = (static_cast<SBitrateInfo*> (pOption)); if ((pInfo->iLayer != SPATIAL_LAYER_ALL) && (pInfo->iLayer != SPATIAL_LAYER_0) && (pInfo->iLayer != SPATIAL_LAYER_1) && (pInfo->iLayer != SPATIAL_LAYER_2) && (pInfo->iLayer != SPATIAL_LAYER_3)) return cmInitParaError; if (pInfo->iLayer == SPATIAL_LAYER_ALL) { pInfo->iBitrate = m_pEncContext->pSvcParam->iTargetBitrate; } else { pInfo->iBitrate = m_pEncContext->pSvcParam->sSpatialLayers[pInfo->iLayer].iSpatialBitrate; } WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_BITRATE, layerId =%d,iBitrate = %d", pInfo->iLayer, pInfo->iBitrate); } break; case ENCODER_OPTION_MAX_BITRATE: { // Target bit-rate SBitrateInfo* pInfo = (static_cast<SBitrateInfo*> (pOption)); if ((pInfo->iLayer != SPATIAL_LAYER_ALL) && (pInfo->iLayer != SPATIAL_LAYER_0) && (pInfo->iLayer != SPATIAL_LAYER_1) && (pInfo->iLayer != SPATIAL_LAYER_2) && (pInfo->iLayer != SPATIAL_LAYER_3)) return cmInitParaError; if (pInfo->iLayer == SPATIAL_LAYER_ALL) { pInfo->iBitrate = m_pEncContext->pSvcParam->iMaxBitrate; } else { pInfo->iBitrate = m_pEncContext->pSvcParam->sSpatialLayers[pInfo->iLayer].iMaxSpatialBitrate; } WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_MAX_BITRATE,, layerId =%d,iBitrate = %d", pInfo->iLayer, pInfo->iBitrate); } break; case ENCODER_OPTION_GET_STATISTICS: { SEncoderStatistics* pStatistics = (static_cast<SEncoderStatistics*> (pOption)); SEncoderStatistics* pEncStatistics = &m_pEncContext->sEncoderStatistics[m_pEncContext->pSvcParam->iSpatialLayerNum - 1]; pStatistics->uiWidth = pEncStatistics->uiWidth; pStatistics->uiHeight = pEncStatistics->uiHeight; pStatistics->fAverageFrameSpeedInMs = pEncStatistics->fAverageFrameSpeedInMs; // rate control related pStatistics->fAverageFrameRate = pEncStatistics->fAverageFrameRate; pStatistics->fLatestFrameRate = pEncStatistics->fLatestFrameRate; pStatistics->uiBitRate = pEncStatistics->uiBitRate; pStatistics->uiInputFrameCount = pEncStatistics->uiInputFrameCount; pStatistics->uiSkippedFrameCount = pEncStatistics->uiSkippedFrameCount; pStatistics->uiResolutionChangeTimes = pEncStatistics->uiResolutionChangeTimes; pStatistics->uiIDRReqNum = pEncStatistics->uiIDRReqNum; pStatistics->uiIDRSentNum = pEncStatistics->uiIDRSentNum; pStatistics->uiLTRSentNum = pEncStatistics->uiLTRSentNum; } break; case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: { * ((int32_t*)pOption) = m_pEncContext->iStatisticsLogInterval; } break; case ENCODER_OPTION_COMPLEXITY: { * ((int32_t*)pOption) = m_pEncContext->pSvcParam->iComplexityMode; } break; default: return cmInitParaError; } return 0; } void CWelsH264SVCEncoder::DumpSrcPicture (const uint8_t* pSrc) { #ifdef DUMP_SRC_PICTURE FILE* pFile = NULL; char strFileName[256] = {0}; const int32_t iDataLength = m_iMaxPicWidth * m_iMaxPicHeight; WelsStrncpy (strFileName, 256, "pic_in_"); // confirmed_safe_unsafe_usage if (m_iMaxPicWidth == 640) { WelsStrcat (strFileName, 256, "360p."); // confirmed_safe_unsafe_usage } else if (m_iMaxPicWidth == 320) { WelsStrcat (strFileName, 256, "180p."); // confirmed_safe_unsafe_usage } else if (m_iMaxPicWidth == 160) { WelsStrcat (strFileName, 256, "90p."); // confirmed_safe_unsafe_usage } switch (m_iCspInternal) { case videoFormatI420: case videoFormatYV12: WelsStrcat (strFileName, 256, "yuv"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); // WelsLog( &m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "WELS_CSP_I420, m_iCspInternal= 0x%x", m_iCspInternal); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), (iDataLength * 3) >> 1, pFile); fflush (pFile); fclose (pFile); } break; case videoFormatRGB: WelsStrcat (strFileName, 256, "rgb"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), iDataLength * 3, pFile); fflush (pFile); fclose (pFile); } case videoFormatBGR: WelsStrcat (strFileName, 256, "bgr"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); // WelsLog( &m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "WELS_CSP_BGR, m_iCspInternal= 0x%x", m_iCspInternal); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), iDataLength * 3, pFile); fflush (pFile); fclose (pFile); } break; case videoFormatYUY2: WelsStrcat (strFileName, 256, "yuy2"); // confirmed_safe_unsafe_usage pFile = WelsFopen (strFileName, "ab+"); if (NULL != pFile) { fwrite (pSrc, sizeof (uint8_t), (CALC_BI_STRIDE (m_iMaxPicWidth, 16)) * m_iMaxPicHeight, pFile); fflush (pFile); fclose (pFile); } break; default: WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "Exclusive case, m_iCspInternal= 0x%x", m_iCspInternal); break; } #endif//DUMP_SRC_PICTURE return; } } using namespace WelsEnc; int32_t WelsCreateSVCEncoder (ISVCEncoder** ppEncoder) { if ((*ppEncoder = new CWelsH264SVCEncoder()) != NULL) { return 0; } return 1; } void WelsDestroySVCEncoder (ISVCEncoder* pEncoder) { CWelsH264SVCEncoder* pSVCEncoder = (CWelsH264SVCEncoder*)pEncoder; if (pSVCEncoder) { delete pSVCEncoder; pSVCEncoder = NULL; } } OpenH264Version WelsGetCodecVersion() { return g_stCodecVersion; } void WelsGetCodecVersionEx (OpenH264Version* pVersion) { *pVersion = g_stCodecVersion; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////