void AudioOutputStreamHandler::SetOutputParameters(String type, String typeDevice, String device, bool isAudioOutputToStream)
{
    this->isAudioOutputToStream = isAudioOutputToStream;

    if (isAudioOutputToStream) {
        libvlc_audio_set_callbacks(mediaPlayer, audioPlayCallbackProxy, nullptr, nullptr, nullptr, nullptr, this); 
    } else {
        auto *node = libvlc_audio_output_list_get(vlc);
        
        char *_type = type.CreateUTF8String();
        char *_typeDevice = typeDevice.CreateUTF8String();
        char *_device = device.CreateUTF8String();

        if (_type) {
            int i = libvlc_audio_output_set(mediaPlayer, _type);
            if (_device) {
                libvlc_audio_output_device_set(mediaPlayer, _typeDevice, _device);
            }
        }

        if (_type != nullptr) {
            Free(_type);
        }
        if (_typeDevice != nullptr) {
            Free(_typeDevice);
        }
        if (_device != nullptr) {
            Free(_device);
        }
    }
}
Ejemplo n.º 2
0
LPSTR getPluginConfigPath()
{
    if(configPath == NULL)
    {
        String pluginPath = OBSGetPluginDataPath();
        pluginPath << TEXT("\\OBSRemote.xconfig");
        configPath = pluginPath.CreateUTF8String();
    }

    return configPath;
}
Ejemplo n.º 3
0
    void InitSEIUserData()
    {
        List<mfxU8> payload;

        const mfxU8 UUID[] = { 0x6d, 0x1a, 0x26, 0xa0, 0xbd, 0xdc, 0x11, 0xe2,   //ISO-11578 UUID
                               0x90, 0x24, 0x00, 0x50, 0xc2, 0x49, 0x00, 0x48 }; //6d1a26a0-bddc-11e2-9024-0050c2490048
        payload.AppendArray(UUID, 16);

        String str;
        str << TEXT("QSV hardware encoder options:")
            << TEXT(" rate control: ") << (bUseCBR ? TEXT("cbr") : TEXT("vbr"))
            << TEXT("; target bitrate: ") << params.mfx.TargetKbps
            << TEXT("; max bitrate: ") << query.mfx.MaxKbps
            << TEXT("; buffersize: ") << query.mfx.BufferSizeInKB*8
            << TEXT("; API level: ") << ver.Major << TEXT(".") << ver.Minor;

        LPSTR info = str.CreateUTF8String();
        payload.AppendArray((LPBYTE)info, (unsigned)strlen(info)+1);
        Free(info);

        AddSEIData(payload, SEI_USER_DATA_UNREGISTERED);
    }
Ejemplo n.º 4
0
DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
{
    //------------------------------------------------------
    // set up URL

    bool bRetry = false;
    bool bSuccess = false;
    bool bCanRetry = false;

    String failReason;
    String strBindIP;

    int    serviceID    = AppConfig->GetInt   (TEXT("Publish"), TEXT("Service"));
    String strURL       = AppConfig->GetString(TEXT("Publish"), TEXT("URL"));
    String strPlayPath  = AppConfig->GetString(TEXT("Publish"), TEXT("PlayPath"));

    strURL.KillSpaces();
    strPlayPath.KillSpaces();

    LPSTR lpAnsiURL = NULL, lpAnsiPlaypath = NULL;
    RTMP *rtmp = NULL;

    //--------------------------------
    // unbelievably disgusting hack for elgato devices

    String strOldDirectory;
    UINT dirSize = GetCurrentDirectory(0, 0);
    strOldDirectory.SetLength(dirSize);
    GetCurrentDirectory(dirSize, strOldDirectory.Array());

    OSSetCurrentDirectory(API->GetAppPath());

    //--------------------------------

    if(!strURL.IsValid())
    {
        failReason = TEXT("No server specified to connect to");
        goto end;
    }

    if(serviceID != 0)
    {
        XConfig serverData;
        if(!serverData.Open(TEXT("services.xconfig")))
        {
            failReason = TEXT("Could not open services.xconfig");
            goto end;
        }

        XElement *services = serverData.GetElement(TEXT("services"));
        if(!services)
        {
            failReason = TEXT("Could not find any services in services.xconfig");
            goto end;
        }

        XElement *service = NULL;
        DWORD numServices = services->NumElements();
        for(UINT i=0; i<numServices; i++)
        {
            XElement *curService = services->GetElementByID(i);
            if(curService->GetInt(TEXT("id")) == serviceID)
            {
                service = curService;
                break;
            }
        }

        if(!service)
        {
            failReason = TEXT("Could not find the service specified in services.xconfig");
            goto end;
        }

        XElement *servers = service->GetElement(TEXT("servers"));
        if(!servers)
        {
            failReason = TEXT("Could not find any servers for the service specified in services.xconfig");
            goto end;
        }

        XDataItem *item = servers->GetDataItem(strURL);
        if(!item)
            item = servers->GetDataItemByID(0);

        strURL = item->GetData();

        Log(TEXT("Using RTMP service: %s"), service->GetName());
        Log(TEXT("  Server selection: %s"), strURL.Array());
    }

    //------------------------------------------------------
    // now back to the elgato directory if it needs the directory changed still to function *sigh*

    OSSetCurrentDirectory(strOldDirectory);

    //------------------------------------------------------

    rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);

    RTMP_LogSetCallback(librtmpErrorCallback);

    //RTMP_LogSetLevel(RTMP_LOGERROR);

    lpAnsiURL = strURL.CreateUTF8String();
    lpAnsiPlaypath = strPlayPath.CreateUTF8String();

    if(!RTMP_SetupURL2(rtmp, lpAnsiURL, lpAnsiPlaypath))
    {
        failReason = Str("Connection.CouldNotParseURL");
        goto end;
    }

    char *rtmpUser = AppConfig->GetString(TEXT("Publish"), TEXT("Username")).CreateUTF8String();
    char *rtmpPass = AppConfig->GetString(TEXT("Publish"), TEXT("Password")).CreateUTF8String();

    if (rtmpUser)
    {
        rtmp->Link.pubUser.av_val = rtmpUser;
        rtmp->Link.pubUser.av_len = (int)strlen(rtmpUser);
    }

    if (rtmpPass)
    {
        rtmp->Link.pubPasswd.av_val = rtmpPass;
        rtmp->Link.pubPasswd.av_len = (int)strlen(rtmpPass);
    }

    RTMP_EnableWrite(rtmp); //set it to publish

    rtmp->Link.swfUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.swfUrl.av_val = rtmp->Link.tcUrl.av_val;
    /*rtmp->Link.pageUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.pageUrl.av_val = rtmp->Link.tcUrl.av_val;*/
    rtmp->Link.flashVer.av_val = "FMLE/3.0 (compatible; FMSc/1.0)";
    rtmp->Link.flashVer.av_len = (int)strlen(rtmp->Link.flashVer.av_val);

    //-----------------------------------------

    UINT tcpBufferSize = AppConfig->GetInt(TEXT("Publish"), TEXT("TCPBufferSize"), 64*1024);

    if(tcpBufferSize < 8192)
        tcpBufferSize = 8192;
    else if(tcpBufferSize > 1024*1024)
        tcpBufferSize = 1024*1024;

    rtmp->m_outChunkSize = 4096;//RTMP_DEFAULT_CHUNKSIZE;//
    rtmp->m_bSendChunkSizeInfo = TRUE;

    rtmp->m_bUseNagle = TRUE;

    strBindIP = AppConfig->GetString(TEXT("Publish"), TEXT("BindToIP"), TEXT("Default"));
    if (scmp(strBindIP, TEXT("Default")))
    {
        rtmp->m_bindIP.addr.sin_family = AF_INET;
        rtmp->m_bindIP.addrLen = sizeof(rtmp->m_bindIP.addr);
        if (WSAStringToAddress(strBindIP.Array(), AF_INET, NULL, (LPSOCKADDR)&rtmp->m_bindIP.addr, &rtmp->m_bindIP.addrLen) == SOCKET_ERROR)
        {
            // no localization since this should rarely/never happen
            failReason = TEXT("WSAStringToAddress: Could not parse address");
            goto end;
        }
    }

    LogInterfaceType(rtmp);

    //-----------------------------------------

    if(!RTMP_Connect(rtmp, NULL))
    {
        failReason = Str("Connection.CouldNotConnect");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    if(!RTMP_ConnectStream(rtmp, 0))
    {
        failReason = Str("Connection.InvalidStream");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    //-----------------------------------------

    OSDebugOut(TEXT("Connected: %u\r\n"), OSGetTime());

    publisher->RequestKeyframe(1000);

    //-----------------------------------------

    bSuccess = true;

end:

    if (lpAnsiURL)
        Free(lpAnsiURL);

    if (lpAnsiPlaypath)
        Free(lpAnsiPlaypath);

    if(!bSuccess)
    {
        if(rtmp)
        {
            RTMP_Close(rtmp);
            RTMP_Free(rtmp);
        }

        if(failReason.IsValid())
            App->SetStreamReport(failReason);

        if(!publisher->bStopping)
            PostMessage(hwndMain, OBS_REQUESTSTOP, bCanRetry ? 0 : 1, 0);

        Log(TEXT("Connection to %s failed: %s"), strURL.Array(), failReason.Array());

        publisher->bStopping = true;
    }
    else
    {
        publisher->Init(rtmp, tcpBufferSize);
        publisher->bConnected = true;
        publisher->bConnecting = false;
    }

    return 0;
}
Ejemplo n.º 5
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(&paramData, sizeof(paramData));

        LPSTR lpPreset = curPreset.CreateUTF8String();
        LPSTR lpTune = curTune.CreateUTF8String();

        if (x264_param_default_preset(&paramData, 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(&paramData, 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 (&paramData, lpProfile))
                Log(TEXT("Failed to set x264 profile: %s"), curProfile.Array());

            Free(lpProfile);
        }

        x264 = x264_encoder_open(&paramData);
        if(!x264)
            CrashError(TEXT("Could not initialize x264"));

        Log(TEXT("------------------------------------------"));
        Log(TEXT("%s"), GetInfoString().Array());
        Log(TEXT("------------------------------------------"));

        DataPacket packet;
        GetHeaders(packet);
    }
Ejemplo n.º 6
0
	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(&paramData, sizeof(paramData));

		LPSTR lpPreset = curPreset.CreateUTF8String();
		LPSTR lpTune = curTune.CreateUTF8String();

		if (x264_param_default_preset(&paramData, 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(&paramData, 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(&paramData, lpProfile))
				Log::writeMessage(LOG_RTSPSERV,1,"LiveSDK_Log:Failed to set x264 profile: %s", curProfile.Array());

			Free(lpProfile);
		}

		
	}