virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize) { SetBitRateParams(maxBitrate, bufferSize); int retVal = x264_encoder_reconfig(x264, ¶mData); if(retVal < 0) Log(TEXT("Could not set new encoder bitrate, error value %u"), retVal); return retVal == 0; }
virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize) { DWORD old_bitrate = paramData.rc.i_vbv_max_bitrate; DWORD old_buffer = paramData.rc.i_vbv_buffer_size; SetBitRateParams(maxBitrate, bufferSize); int retVal = x264_encoder_reconfig(x264, ¶mData); if (retVal < 0) Log(TEXT("Could not set new encoder bitrate, error value %u"), retVal); else { String changes; if (old_bitrate != maxBitrate) changes << FormattedString(L"bitrate %d->%d", old_bitrate, maxBitrate); if (old_buffer != bufferSize) changes << FormattedString(L"%sbuffer size %d->%d", changes.Length() ? L", " : L"", old_buffer, bufferSize); if (changes) Log(L"x264: %s", changes.Array()); } return retVal == 0; }
virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize) { DWORD old_bitrate = paramData.rc.i_vbv_max_bitrate; DWORD old_buffer = paramData.rc.i_vbv_buffer_size; SetBitRateParams(maxBitrate, bufferSize); int retVal = x264_encoder_reconfig(x264, ¶mData); if (retVal < 0) { DOLOG("Could not set new encoder bitrate, error value " + retVal); } else { if (old_bitrate != maxBitrate){ DOLOG("bitrate " + old_bitrate + "->" + maxBitrate); } if (old_buffer != bufferSize){ DOLOG("bitrate size " + old_buffer + "->" + bufferSize); } } return retVal == 0; }
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, ColorDescription &colorDesc, int maxBitrate, int bufferSize, bool bUseCFR) { curPreset = preset; fps_ms = 1000/fps; StringList paramList; curProfile = AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), TEXT("high")); BOOL bUseCustomParams = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCustomSettings")); if(bUseCustomParams) { String strCustomParams = AppConfig->GetString(TEXT("Video Encoding"), TEXT("CustomSettings")); strCustomParams.KillSpaces(); if(strCustomParams.IsValid()) { Log(TEXT("Using custom x264 settings: \"%s\""), strCustomParams.Array()); strCustomParams.GetTokenList(paramList, ' ', FALSE); for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if(strParamName.CompareI(TEXT("preset"))) { if(valid_x264_string(strParamVal, (const char**)x264_preset_names)) curPreset = strParamVal; else Log(TEXT("invalid preset: %s"), strParamVal.Array()); paramList.Remove(i--); } else if(strParamName.CompareI(TEXT("tune"))) { if(valid_x264_string(strParamVal, (const char**)x264_tune_names)) curTune = strParamVal; else Log(TEXT("invalid tune: %s"), strParamVal.Array()); paramList.Remove(i--); } else if(strParamName.CompareI(TEXT("profile"))) { if(valid_x264_string(strParamVal, (const char **)x264_profile_names)) curProfile = strParamVal; else Log(TEXT("invalid profile: %s"), strParamVal.Array()); paramList.Remove(i--); } } } } zero(¶mData, sizeof(paramData)); LPSTR lpPreset = curPreset.CreateUTF8String(); LPSTR lpTune = curTune.CreateUTF8String(); if (x264_param_default_preset(¶mData, lpPreset, lpTune)) Log(TEXT("Failed to set x264 defaults: %s/%s"), curPreset.Array(), curTune.Array()); Free(lpTune); Free(lpPreset); this->width = width; this->height = height; paramData.b_deterministic = false; bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0; bPadCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("PadCBR"), 1) != 0; this->bUseCFR = bUseCFR; SetBitRateParams(maxBitrate, bufferSize); if(bUseCBR) { if(bPadCBR) paramData.i_nal_hrd = X264_NAL_HRD_CBR; paramData.rc.i_rc_method = X264_RC_ABR; paramData.rc.f_rf_constant = 0.0f; } else { paramData.rc.i_rc_method = X264_RC_CRF; paramData.rc.f_rf_constant = baseCRF+float(10-quality); } UINT keyframeInterval = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0); paramData.b_vfr_input = !bUseCFR; paramData.i_width = width; paramData.i_height = height; paramData.vui.b_fullrange = colorDesc.fullRange; paramData.vui.i_colorprim = colorDesc.primaries; paramData.vui.i_transfer = colorDesc.transfer; paramData.vui.i_colmatrix = colorDesc.matrix; if (keyframeInterval) paramData.i_keyint_max = fps*keyframeInterval; paramData.i_fps_num = fps; paramData.i_fps_den = 1; paramData.i_timebase_num = 1; paramData.i_timebase_den = 1000; paramData.pf_log = get_x264_log; paramData.i_log_level = X264_LOG_WARNING; for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if( strParamName.CompareI(TEXT("fps")) || strParamName.CompareI(TEXT("force-cfr"))) { Log(TEXT("The custom x264 command '%s' is unsupported, use the application settings instead"), strParam.Array()); continue; } else { LPSTR lpParam = strParamName.CreateUTF8String(); LPSTR lpVal = strParamVal.CreateUTF8String(); if(x264_param_parse(¶mData, lpParam, lpVal) != 0) Log(TEXT("The custom x264 command '%s' failed"), strParam.Array()); Free(lpParam); Free(lpVal); } } if(bUse444) paramData.i_csp = X264_CSP_I444; else paramData.i_csp = X264_CSP_I420; colorDesc.fullRange = paramData.vui.b_fullrange; colorDesc.primaries = paramData.vui.i_colorprim; colorDesc.transfer = paramData.vui.i_transfer; colorDesc.matrix = paramData.vui.i_colmatrix; if (curProfile) { LPSTR lpProfile = curProfile.CreateUTF8String(); if (x264_param_apply_profile (¶mData, lpProfile)) Log(TEXT("Failed to set x264 profile: %s"), curProfile.Array()); Free(lpProfile); } x264 = x264_encoder_open(¶mData); if(!x264) CrashError(TEXT("Could not initialize x264")); Log(TEXT("------------------------------------------")); Log(TEXT("%s"), GetInfoString().Array()); Log(TEXT("------------------------------------------")); DataPacket packet; GetHeaders(packet); }
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, CTSTR ProFile, bool bUse444, ColorDescription &colorDesc, int maxBitrate, int bufferSize, bool bUseCFR, bool bUesBackConfig) { frameShift = 0; curPreset = preset; FPS = fps; fps_ms = 1000 / fps; StringList paramList; curProfile = ProFile; zero(¶mData, sizeof(paramData)); LPSTR lpPreset = curPreset.CreateUTF8String(); LPSTR lpTune = curTune.CreateUTF8String(); if (x264_param_default_preset(¶mData, lpPreset, lpTune)) Log::writeError(LOG_RTSPSERV,1,"LiveSDK_Log:Failed to set x264 defaults: %s/%s", curPreset.Array(), curTune.Array()); Free(lpTune); Free(lpPreset); this->width = width; this->height = height; paramData.b_deterministic = false; //分主次直播 if (bUesBackConfig) { bUseCBR = CSLiveManager::GetInstance()->BSParam.LiveSetting.bUseCBRSec; } else { bUseCBR = CSLiveManager::GetInstance()->BSParam.LiveSetting.bUseCBR; } bPadCBR = true; this->bUseCFR = bUseCFR; SetBitRateParams(maxBitrate, bufferSize); if (bUseCBR) { if (bPadCBR) paramData.rc.b_filler = 1; //if(bPadCBR) paramData.i_nal_hrd = X264_NAL_HRD_CBR; paramData.rc.i_rc_method = X264_RC_ABR; paramData.rc.f_rf_constant = 0.0f; } else { paramData.i_frame_reference = 5; paramData.rc.i_rc_method = X264_RC_CRF; paramData.rc.f_rf_constant = baseCRF + float(10 - quality); } //分主次直播 UINT keyframeInterval = CSLiveManager::GetInstance()->BSParam.LiveSetting.KeyFrame; if (bUesBackConfig) { keyframeInterval = CSLiveManager::GetInstance()->BSParam.LiveSetting.KeyFrameSec; } paramData.b_vfr_input = !bUseCFR; paramData.i_width = width; paramData.i_height = height; paramData.vui.b_fullrange = colorDesc.fullRange; paramData.vui.i_colorprim = colorDesc.primaries; paramData.vui.i_transfer = colorDesc.transfer; paramData.vui.i_colmatrix = colorDesc.matrix; if (keyframeInterval) paramData.i_keyint_max = fps*keyframeInterval; paramData.i_fps_num = fps; paramData.i_fps_den = 1; paramData.i_timebase_num = 1; paramData.i_timebase_den = 1000; paramData.pf_log = get_x264_log; paramData.i_log_level = X264_LOG_WARNING; //分主次直播 int nBFrameCount = CSLiveManager::GetInstance()->BSParam.LiveSetting.BFrameCount; if (bUesBackConfig) { nBFrameCount = CSLiveManager::GetInstance()->BSParam.LiveSetting.BFrameCountSec; } if (-1 != nBFrameCount) { paramData.i_bframe = nBFrameCount; } //录制高品质不能播放 paramData.b_vfr_input = 0; if (0 == nBFrameCount) { // http://bbs.csdn.net/topics/390922653 paramData.rc.i_lookahead = 0; paramData.i_sync_lookahead = 0; paramData.i_bframe = 0; paramData.b_sliced_threads = 1; paramData.rc.b_mb_tree = 0; } if (scmpi(curProfile, L"main") == 0) paramData.i_level_idc = 41; // to ensure compatibility with portable devices for (UINT i = 0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if (!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if (strParamName.CompareI(TEXT("fps")) || strParamName.CompareI(TEXT("force-cfr"))) { Log(TEXT("The custom x264 command '%s' is unsupported, use the application settings instead"), strParam.Array()); continue; } else { LPSTR lpParam = strParamName.CreateUTF8String(); LPSTR lpVal = strParamVal.CreateUTF8String(); if (x264_param_parse(¶mData, lpParam, lpVal) != 0) Log(TEXT("The custom x264 command '%s' failed"), strParam.Array()); Free(lpParam); Free(lpVal); } } if (bUse444) paramData.i_csp = X264_CSP_I444; else paramData.i_csp = X264_CSP_I420; colorDesc.fullRange = paramData.vui.b_fullrange; colorDesc.primaries = paramData.vui.i_colorprim; colorDesc.transfer = paramData.vui.i_transfer; colorDesc.matrix = paramData.vui.i_colmatrix; if (curProfile) { LPSTR lpProfile = curProfile.CreateUTF8String(); if (x264_param_apply_profile(¶mData, lpProfile)) Log::writeMessage(LOG_RTSPSERV,1,"LiveSDK_Log:Failed to set x264 profile: %s", curProfile.Array()); Free(lpProfile); } }
X264Encoder(int fps, int width, int height, int quality/*建议设置成1*/, int maxBitrate, int bufferSize, bool bUseCFR) { fps_ms = 1000/fps; curProfile = "main"; // AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), TEXT("high")); ZeroMemory(¶mData, sizeof(paramData)); if (x264_param_default_preset(¶mData, "veryfast", NULL)) { DOLOG("Failed to set default preset"); } this->width = width; this->height = height; paramData.b_deterministic = false; bUseCBR = false; bPadCBR = false; this->bUseCFR = false; SetBitRateParams(maxBitrate, bufferSize); //-------------- 和是否是CBR有关 paramData.rc.i_rc_method = X264_RC_CRF; paramData.rc.f_rf_constant = baseCRF + float(10-quality); // 暂时采用固定公式。还不清楚到底怎么影响 UINT keyframeInterval = 0; // 关键帧间隔 paramData.b_vfr_input = true; paramData.i_width = width; paramData.i_height = height; // 暂时不知道是做什么的,就采用默认,并不设置 //paramData.vui.b_fullrange = colorDesc.fullRange; //paramData.vui.i_colorprim = colorDesc.primaries; //paramData.vui.i_transfer = colorDesc.transfer; //paramData.vui.i_colmatrix = colorDesc.matrix; if (keyframeInterval) paramData.i_keyint_max = fps*keyframeInterval; paramData.i_fps_num = fps; paramData.i_fps_den = 1; paramData.i_timebase_num = 1; paramData.i_timebase_den = 1000; paramData.pf_log = get_x264_log; paramData.i_log_level = X264_LOG_WARNING; paramData.i_level_idc = 41; // to ensure compatibility with portable devices paramData.i_csp = X264_CSP_I420; if (x264_param_apply_profile(¶mData, "main")) { DOLOG("Failed to set x264 profile: main"); } x264 = x264_encoder_open(¶mData); if (!x264) { DOLOG("Could not initialize x264"); } DataPacket packet; GetHeaders(packet); }