Exemplo n.º 1
0
    bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp)
    {
        if(!process_waiter.wait_timeout())
        {
            int code = 0;
            if(!GetExitCodeProcess(process_waiter.list[0], (LPDWORD)&code))
                CrashError(TEXT("QSVHelper.exe exited!"));
            switch(code)
            {
            case EXIT_INCOMPATIBLE_CONFIGURATION:
                CrashError(TEXT("QSVHelper.exe has exited because of an incompatible qsvimpl custom parameter"));
            default:
                CrashError(TEXT("QSVHelper.exe has exited with code %i"), code);
            }
        }

        profileIn("ProcessEncodedFrame");
        do
        {
            ProcessEncodedFrame(packets, packetTypes, outputTimestamp, idle_tasks.Num() ? 0 : INFINITE);
        }
        while(!idle_tasks.Num());
        profileOut;

        if(picInPtr)
        {
            profileSegment("QueueEncodeTask");
            QueueEncodeTask(*(mfxFrameSurface1*)picInPtr);
        }
        return true;
    }
Exemplo n.º 2
0
bool RTMPPublisher::Init(RTMP *rtmpIn, UINT tcpBufferSize)
{
    rtmp = rtmpIn;

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

    //Log(TEXT("Using Send Buffer Size: %u"), sendBufferSize);

    rtmp->m_customSendFunc = (CUSTOMSEND)RTMPPublisher::BufferedSend;
    rtmp->m_customSendParam = this;
    rtmp->m_bCustomSend = TRUE;

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

    int curTCPBufSize, curTCPBufSizeSize = sizeof(curTCPBufSize);
    getsockopt (rtmp->m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, (char *)&curTCPBufSize, &curTCPBufSizeSize);

    Log(TEXT("SO_SNDBUF was at %u"), curTCPBufSize);

    if(curTCPBufSize < int(tcpBufferSize))
    {
        setsockopt (rtmp->m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, (const char *)&tcpBufferSize, sizeof(tcpBufferSize));
        getsockopt (rtmp->m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, (char *)&curTCPBufSize, &curTCPBufSizeSize);
        if(curTCPBufSize != tcpBufferSize)
            Log(TEXT("Could not set SO_SNDBUF to %u, value is now %u"), tcpBufferSize, curTCPBufSize);
    }

    Log(TEXT("SO_SNDBUF is now %u"), tcpBufferSize);

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

    hSendThread = OSCreateThread((XTHREAD)RTMPPublisher::SendThread, this);
    if(!hSendThread)
        CrashError(TEXT("RTMPPublisher: Could not create send thread"));

    hBufferEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    hBufferSpaceAvailableEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    hSendLoopExit = CreateEvent(NULL, FALSE, FALSE, NULL);
    hSocketLoopExit = CreateEvent(NULL, FALSE, FALSE, NULL);
    hSendBacklogEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    hDataBufferMutex = OSCreateMutex();

    dataBufferSize = (App->GetVideoEncoder()->GetBitRate() + App->GetAudioEncoder()->GetBitRate()) / 8 * 1024;

    dataBuffer = (BYTE *)Allocate(dataBufferSize);

    hSocketThread = OSCreateThread((XTHREAD)RTMPPublisher::SocketThread, this);
    if(!hSocketThread)
        CrashError(TEXT("RTMPPublisher: Could not create send thread"));

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

    packetWaitType = 0;

    return true;
}
Exemplo n.º 3
0
    BlankAudioPlayback(CTSTR lpDevice)
    {
        const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
        const IID IID_IMMDeviceEnumerator    = __uuidof(IMMDeviceEnumerator);
        const IID IID_IAudioClient           = __uuidof(IAudioClient);
        const IID IID_IAudioRenderClient     = __uuidof(IAudioRenderClient);

        HRESULT err;
        err = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&mmEnumerator);
        if(FAILED(err))
            CrashError(TEXT("Could not create IMMDeviceEnumerator: 0x%08lx"), err);

        if (scmpi(lpDevice, TEXT("Default")) == 0)
            err = mmEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &mmDevice);
        else
            err = mmEnumerator->GetDevice(lpDevice, &mmDevice);
        if(FAILED(err))
            CrashError(TEXT("Could not create IMMDevice"));

        err = mmDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&mmClient);
        if(FAILED(err))
            CrashError(TEXT("Could not create IAudioClient"));

        WAVEFORMATEX *pwfx;
        err = mmClient->GetMixFormat(&pwfx);
        if(FAILED(err))
            CrashError(TEXT("Could not get mix format from audio client"));

        UINT inputBlockSize = pwfx->nBlockAlign;

        err = mmClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, ConvertMSTo100NanoSec(1000), 0, pwfx, NULL);
        if(FAILED(err))
            CrashError(TEXT("Could not initialize audio client, error = %08lX"), err);

        err = mmClient->GetService(IID_IAudioRenderClient, (void**)&mmRender);
        if(FAILED(err))
            CrashError(TEXT("Could not get audio render client"));

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

        UINT bufferFrameCount;
        err = mmClient->GetBufferSize(&bufferFrameCount);
        if(FAILED(err))
            CrashError(TEXT("Could not get audio buffer size"));

        BYTE *lpData;
        err = mmRender->GetBuffer(bufferFrameCount, &lpData);
        if(FAILED(err))
            CrashError(TEXT("Could not get audio buffer"));

        zero(lpData, bufferFrameCount*inputBlockSize);

        mmRender->ReleaseBuffer(bufferFrameCount, 0);//AUDCLNT_BUFFERFLAGS_SILENT); //probably better if it doesn't know

        if(FAILED(mmClient->Start()))
            CrashError(TEXT("Could not start audio source"));
    }
Exemplo n.º 4
0
RTMPPublisher::RTMPPublisher()
{
    //bufferedPackets.SetBaseSize(MAX_BUFFERED_PACKETS);

    bFirstKeyframe = true;

    hSendSempahore = CreateSemaphore(NULL, 0, 0x7FFFFFFFL, NULL);
    if(!hSendSempahore)
        CrashError(TEXT("RTMPPublisher: Could not create semaphore"));

    hDataMutex = OSCreateMutex();
    if(!hDataMutex)
        CrashError(TEXT("RTMPPublisher: Could not create mutex"));

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

    bframeDropThreshold = AppConfig->GetInt(TEXT("Publish"), TEXT("BFrameDropThreshold"), 400);
    if(bframeDropThreshold < 50)        bframeDropThreshold = 50;
    else if(bframeDropThreshold > 1000) bframeDropThreshold = 1000;

    dropThreshold = AppConfig->GetInt(TEXT("Publish"), TEXT("FrameDropThreshold"), 600);
    if(dropThreshold < 50)        dropThreshold = 50;
    else if(dropThreshold > 1000) dropThreshold = 1000;

    if (AppConfig->GetInt(TEXT("Publish"), TEXT("LowLatencyMode"), 0))
    {
        if (AppConfig->GetInt(TEXT("Publish"), TEXT("LowLatencyMethod"), 0) == 0)
        {
            latencyFactor = AppConfig->GetInt(TEXT("Publish"), TEXT("LatencyFactor"), 20);

            if (latencyFactor < 3)
                latencyFactor = 3;

            lowLatencyMode = LL_MODE_FIXED;
            Log(TEXT("Using fixed low latency mode, factor %d"), latencyFactor);
        }
        else
        {
            lowLatencyMode = LL_MODE_AUTO;
            Log(TEXT("Using automatic low latency mode"));
        }
    }
    else
        lowLatencyMode = LL_MODE_NONE;
    
    bFastInitialKeyframe = AppConfig->GetInt(TEXT("Publish"), TEXT("FastInitialKeyframe"), 0) == 1;

    strRTMPErrors.Clear();
}
Exemplo n.º 5
0
DXInput::DXInput()
{
    traceIn(DXInput::DXInput);

    Log(TEXT("Initializing DirectInput"));

    ++realtimeCounter;

    bDInputActive = 1;

    if(DirectInput8Create((HINSTANCE)hinstMain, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void**)&diDevice, NULL) != DI_OK)
        CrashError(TEXT("DInput: Could not create Direct Input device"));

    InputEvents[0] = CreateEvent(NULL, 0, 0, NULL);
    InputEvents[1] = CreateEvent(NULL, 0, 0, NULL);

    DICreateKeyboardDevice(hwndMain);
    DICreateMouseDevice(hwndMain);

    //DWORD dummy;
    //hInputThread = CreateThread(NULL, 0, InputThread, NULL, 0, &dummy);
    //if(hInputThread == INVALID_HANDLE_VALUE)
    //    CrashError(TEXT("DInput: could not create input thread"));

    traceOut;
}
Exemplo n.º 6
0
    void QueueEncodeTask(mfxFrameSurface1& pic)
    {
        encode_task& task = encode_tasks[idle_tasks[0]];

        auto lock_queue = lock_mutex(frame_queue);

        for(unsigned i = 0; i < frame_queue.size; i++)
        {
            queued_frame &info = frame_queue[i];

            if(info.is_new)
                continue;
            queued_tasks << idle_tasks[0];
            idle_tasks.Remove(0);
            info.is_new = true;

            info.request_keyframe = bRequestKeyframe;
            bRequestKeyframe = false;

            info.timestamp = task.surf.Data.TimeStamp = timestampFromMS(pic.Data.TimeStamp);
            info.frame_index = (uint32_t)pic.Data.MemId-1;
            auto lock_status = lock_mutex(frame_buff_status);
            frame_buff_status[info.frame_index] += 1;
            frame_queue.signal();
            return;
        }
        CrashError(TEXT("QSV encoder is too slow"));
    }
Exemplo n.º 7
0
void D3D10VertexShader::CreateVertexShaderBlob(ShaderBlob &blob, CTSTR lpShader, CTSTR lpFileName)
{
    D3D10System *d3d10Sys = static_cast<D3D10System*>(GS);
    LPCSTR lpVSType = d3d10Sys->bDisableCompatibilityMode ? "vs_4_0" : "vs_4_0_level_9_3";

    ComPtr<ID3D10Blob> errorMessages, shaderBlob;

    LPSTR lpAnsiShader = tstr_createUTF8(lpShader);
    LPSTR lpAnsiFileName = tstr_createUTF8(lpFileName);

    HRESULT err = D3DX11CompileFromMemory(lpAnsiShader, strlen(lpAnsiShader), lpAnsiFileName, NULL, NULL, "main", lpVSType, D3D10_SHADER_OPTIMIZATION_LEVEL3, 0, NULL, shaderBlob.Assign(), errorMessages.Assign(), NULL);

    Free(lpAnsiFileName);
    Free(lpAnsiShader);

    if (FAILED(err))
    {
        if (errorMessages)
        {
            if (errorMessages->GetBufferSize())
            {
                LPSTR lpErrors = (LPSTR)errorMessages->GetBufferPointer();
                Log(TEXT("Error compiling vertex shader '%s':\r\n\r\n%S\r\n"), lpFileName, lpErrors);
            }
        }

        CrashError(TEXT("Compilation of vertex shader '%s' failed, result = %08lX"), lpFileName, err);
        return;
    }

    blob.assign((char*)shaderBlob->GetBufferPointer(), (char*)shaderBlob->GetBufferPointer() + shaderBlob->GetBufferSize());
}
Exemplo n.º 8
0
Shader *D3D10PixelShader::CreatePixelShaderFromBlob(ShaderBlob const &blob, CTSTR lpShader, CTSTR lpFileName)
{
    ShaderProcessor shaderProcessor;
    if (!shaderProcessor.ProcessShader(lpShader, lpFileName))
        AppWarning(TEXT("Unable to process pixel shader '%s'"), lpFileName); //don't exit, leave it to the actual shader compiler to tell the errors

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

    if (!blob.size())
        return nullptr;

    ID3D11PixelShader *pShader;

    HRESULT err = GetD3D()->CreatePixelShader(&blob.front(), blob.size(), NULL, &pShader);
    if (FAILED(err))
    {
        CrashError(TEXT("Unable to create pixel shader '%s', result = %08lX"), lpFileName, err);
        return NULL;
    }

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

    D3D10PixelShader *shader = new D3D10PixelShader;
    shader->pixelShader = pShader;
    if (!shader->ProcessData(shaderProcessor, lpFileName))
    {
        delete shader;
        return NULL;
    }

    return shader;

}
Exemplo n.º 9
0
BOOL   STDCALL OSIncompatibleModulesLoaded()
{
    StringList  moduleList;
    
    //Modules that will likely cause OBS to crash because they hooked it.
    //This list is checked on stream start only.

    if (!OSGetLoadedModuleList(GetCurrentProcess(), moduleList))
        return 0;

    for(UINT i=0; i<moduleList.Num(); i++)
    {
        CTSTR moduleName = moduleList[i];

        if (!scmp(moduleName, TEXT("dxtorycore.dll")) ||        //DXTory
            !scmp(moduleName, TEXT("dxtorycore64.dll")) ||      //DXTory
            !scmp(moduleName, TEXT("dxtorymm.dll")) ||          //DXTory
            !scmp(moduleName, TEXT("dxtorymm64.dll")) ||        //DXTory
            !scmp(moduleName, TEXT("rtsshooks.dll")) ||         //EVGA Precision OSD
            !scmp(moduleName, TEXT("axonoverlay.dll")) ||       //Dolby Axon
            !scmp(moduleName, TEXT("action_x86.dll")) ||        //Action!
            !scmp(moduleName, TEXT("action_x64.dll")))          //Action!
        {
            return 1;
        }
        else if (!scmp(moduleName, TEXT("atkdx11disp.dll")))     //ASUS GamerOSD
        {
            //ASUS GamerOSD is so terrible we can't even cleanly shutdown once it loads, trying to unload D3D crashes too (!)
            CrashError (TEXT("ASUS GamerOSD has been detected. This program installs user mode driver hooks which will corrupt the Direct3D state and crash OBS. Please uninstall ASUS GamerOSD if you wish to use OBS."));
        }
    }

    return 0;
}
Exemplo n.º 10
0
    MP3Encoder(UINT bitRate)
    {
        curBitRate = bitRate;

        lgf = lame_init();
        if(!lgf)
            CrashError(TEXT("Unable to open mp3 encoder"));

        lame_set_in_samplerate(lgf, App->GetSampleRateHz());
        lame_set_out_samplerate(lgf, App->GetSampleRateHz());
        lame_set_num_channels(lgf, 2);
        lame_set_mode(lgf, STEREO);
        lame_set_disable_reservoir(lgf, TRUE); //bit reservoir has to be disabled for seamless streaming
        lame_set_VBR(lgf, vbr_off);
        lame_set_brate(lgf, bitRate);
        lame_init_params(lgf);

        outputFrameSize = lame_get_framesize(lgf); //1152 usually
        dwMP3MaxSize = DWORD(1.25*double(outputFrameSize*audioBlockSize) + 7200.0);
        MP3OutputBuffer.SetSize(dwMP3MaxSize+1);
        MP3OutputBuffer[0] = 0x2f;

        bFirstPacket = true;

        Log(TEXT("------------------------------------------"));
        Log(TEXT("%s"), GetInfoString().Array());
    }
Exemplo n.º 11
0
Shader* ResourceManager::GetVertexShader(CTSTR lpName)
{
    traceInFast(ResourceManager::GetVertexShader);

    assert(lpName);

    UINT val = VertexShaderNames.FindValueIndexI(lpName);
    if(val != INVALID)
        return VertexShaders[val];

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

    String path;
    if(!Engine::ConvertResourceName(lpName, TEXT("shaders"), path))
        return NULL;

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

    Shader *newVertexShader = GS->CreateVertexShaderFromFile(path);

    if(!newVertexShader)
    {
        CrashError(TEXT("Resource Manager: Could not find Vertex Shader %s"), lpName);
        return NULL;
    }

    VertexShaderNames << lpName;
    VertexShaders << newVertexShader;

    return newVertexShader;

    traceOutFast;
}
Exemplo n.º 12
0
Shader* D3D10VertexShader::CreateVertexShaderFromBlob(ShaderBlob const &blob, CTSTR lpShader, CTSTR lpFileName)
{
    ShaderProcessor shaderProcessor;
    if (!shaderProcessor.ProcessShader(lpShader, lpFileName))
        AppWarning(TEXT("Unable to process vertex shader '%s'"), lpFileName); //don't exit, leave it to the actual shader compiler to tell the errors

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

    if (!blob.size())
        return nullptr;

    ComPtr<ID3D11VertexShader> vShader;
    ID3D11InputLayout *vShaderLayout;

    HRESULT err = GetD3D()->CreateVertexShader(&blob.front(), blob.size(), NULL, vShader.Assign());
    if (FAILED(err))
    {
        CrashError(TEXT("Unable to create vertex shader '%s', result = %08lX"), lpFileName, err);
        return NULL;
    }

    err = GetD3D()->CreateInputLayout(shaderProcessor.generatedLayout.Array(), shaderProcessor.generatedLayout.Num(), &blob.front(), blob.size(), &vShaderLayout);
    if (FAILED(err))
    {
        CrashError(TEXT("Unable to create vertex layout for vertex shader '%s', result = %08lX"), lpFileName, err);
        return NULL;
    }

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

    D3D10VertexShader *shader = new D3D10VertexShader;
    shader->vertexShader = vShader.Detach();
    shader->inputLayout = vShaderLayout;
    if (!shader->ProcessData(shaderProcessor, lpFileName))
    {
        delete shader;
        return NULL;
    }

    shader->bHasNormals = shaderProcessor.bHasNormals;
    shader->bHasColors = shaderProcessor.bHasColors;
    shader->bHasTangents = shaderProcessor.bHasTangents;
    shader->nTextureCoords = shaderProcessor.numTextureCoords;
    shader->hViewProj = shader->GetParameterByName(TEXT("ViewProj"));

    return shader;
}
Exemplo n.º 13
0
float GetVolumeControlValue(HWND hwnd)
{
    VolumeControlData *control = GetVolumeControlData(hwnd);
    if(!control)
        CrashError(TEXT("GetVolumeControlValue called on a control that's not a volume control"));

    return control->curVolume;
}
Exemplo n.º 14
0
void D3D10System::ResizeView()
{
    LPVOID nullVal = NULL;
    d3d->OMSetRenderTargets(1, (ID3D10RenderTargetView**)&nullVal, NULL);

    SafeRelease(swapRenderView);

    swap->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0);

    ID3D10Texture2D *backBuffer = NULL;
    HRESULT err = swap->GetBuffer(0, IID_ID3D10Texture2D, (void**)&backBuffer);
    if(FAILED(err))
        CrashError(TEXT("Unable to get back buffer from swap chain"));

    err = d3d->CreateRenderTargetView(backBuffer, NULL, &swapRenderView);
    if(FAILED(err))
        CrashError(TEXT("Unable to get render view from back buffer"));

    backBuffer->Release();
}
Exemplo n.º 15
0
HANDLE STDCALL OSCreateThread(XTHREAD lpThreadFunc, LPVOID param)
{
    HANDLE hThread;
    DWORD dummy;

    hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lpThreadFunc, param, 0, &dummy);
    if (!hThread)
        CrashError (TEXT("CreateThread 0x%p failed: %d"), (LPVOID)lpThreadFunc, GetLastError());
    
    return hThread;
}
Exemplo n.º 16
0
void * FastAlloc::_Allocate(size_t dwSize)
{
    OSEnterMutex(hAllocationMutex);

    //assert(dwSize);
    if(!dwSize) dwSize = 1;

    LPVOID lpMemory;
    Pool *pool;

    if(dwSize < 0x8001)
    {
        MemInfo *meminfo = GetMemInfo(dwSize);

        if(!meminfo->nextFree) //no pools have been created for this section
        {
            lpMemory = OSVirtualAlloc(0x10000);
            if(!lpMemory) CrashError(TEXT("Out of memory"));

            Pool *&poollist = PoolList[PtrTo32(lpMemory)>>24];
            if(!poollist)
            {
                poollist = (Pool*)OSVirtualAlloc(sizeof(Pool)*256);
                if(!poollist) CrashError(TEXT("Out of memory"));
                zero(poollist, sizeof(Pool)*256);
            }
            pool = &poollist[(PtrTo32(lpMemory)>>16)&0xFF];

            pool->lpMem = lpMemory;
            pool->bytesTotal = 0x10000;
            pool->meminfo = meminfo;
            pool->firstFreeMem = (FreeMemInfo*)lpMemory;
            pool->lastFreeMem = (FreeMemInfo*)lpMemory;

            meminfo->nextFree = (FreeMemInfo*)lpMemory;
            meminfo->nextFree->num = meminfo->maxBlocks;
            meminfo->nextFree->lpPool = pool;
            meminfo->nextFree->lpPrev = meminfo->nextFree->lpNext = NULL;
        }
Exemplo n.º 17
0
void SetVolumeControlIcons(HWND hwnd, HICON hiconPlay, HICON hiconMute)
{
    VolumeControlData *control = GetVolumeControlData(hwnd);
    if(!control)
        CrashError(TEXT("GetVolumeControlValue called on a control that's not a volume control"));

    control->hiconPlay = hiconPlay;
    control->hiconMute = hiconMute;
    control->bDrawIcon = (control->cy == 32) && control->hiconPlay;

    HDC hDC = GetDC(hwnd);
    control->DrawVolumeControl(hDC);
    ReleaseDC(hwnd, hDC);
}
Exemplo n.º 18
0
void D3D10System::BlendFunction(GSBlendType srcFactor, GSBlendType destFactor, float fFactor)
{
    bool bUseFactor = (srcFactor >= GS_BLEND_FACTOR || destFactor >= GS_BLEND_FACTOR);

    if(bUseFactor)
        curBlendFactor[0] = curBlendFactor[1] = curBlendFactor[2] = curBlendFactor[3] = fFactor;

    for(UINT i=0; i<blends.Num(); i++)
    {
        SavedBlendState &blendInfo = blends[i];
        if(blendInfo.srcFactor == srcFactor && blendInfo.destFactor == destFactor)
        {
            if(bUseFactor || curBlendState != blendInfo.blendState)
            {
                d3d->OMSetBlendState(blendInfo.blendState, curBlendFactor, 0xFFFFFFFF);
                curBlendState = blendInfo.blendState;
            }
            return;
        }
    }

    //blend wasn't found, create a new one and save it for later
    D3D10_BLEND_DESC blendDesc;
    zero(&blendDesc, sizeof(blendDesc));
    for(int i=0; i<8; i++)
    {
        blendDesc.BlendEnable[i]            = TRUE;
        blendDesc.RenderTargetWriteMask[i]  = D3D10_COLOR_WRITE_ENABLE_ALL;
    }
    blendDesc.BlendOpAlpha              = D3D10_BLEND_OP_ADD;
    blendDesc.BlendOp                   = D3D10_BLEND_OP_ADD;
    blendDesc.SrcBlendAlpha             = D3D10_BLEND_ONE;
    blendDesc.DestBlendAlpha            = D3D10_BLEND_ZERO;
    blendDesc.SrcBlend                  = blendConvert[srcFactor];
    blendDesc.DestBlend                 = blendConvert[destFactor];

    SavedBlendState *savedBlend = blends.CreateNew();
    savedBlend->destFactor      = destFactor;
    savedBlend->srcFactor       = srcFactor;

    if(FAILED(d3d->CreateBlendState(&blendDesc, &savedBlend->blendState)))
        CrashError(TEXT("Could not set blend state"));

    if(bBlendingEnabled)
        d3d->OMSetBlendState(savedBlend->blendState, curBlendFactor, 0xFFFFFFFF);

    curBlendState = savedBlend->blendState;
}
Exemplo n.º 19
0
float SetVolumeControlValue(HWND hwnd, float fVal)
{
    VolumeControlData *control = GetVolumeControlData(hwnd);
    if(!control)
        CrashError(TEXT("SetVolumeControlValue called on a control that's not a volume control"));

    float lastVal = control->curVolume;

    control->curVolume = fVal;

    HDC hDC = GetDC(hwnd);
    control->DrawVolumeControl(hDC);
    ReleaseDC(hwnd, hDC);

    return lastVal;
}
Exemplo n.º 20
0
float SetVolumeMeterValue(HWND hwnd, float fVal, float fMax, float fPeak)
{
    VolumeMeterData *meter = GetVolumeMeterData(hwnd);
    if(!meter)
        CrashError(TEXT("SetVolumeMeterValue called on a control that's not a volume control"));

    float lastVal = meter->curVolume;

    meter->curVolume = fVal;
    meter->curMax = max(VOL_MIN, fMax);
    meter->curPeak = fPeak;

    HDC hDC = GetDC(hwnd);
    meter->DrawVolumeMeter(hDC);
    ReleaseDC(hwnd, hDC);

    return lastVal;
}
Exemplo n.º 21
0
void InitVolumeControl()
{
    WNDCLASS wnd;

    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = sizeof(LPVOID);
    wnd.hbrBackground = NULL;
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
    wnd.hIcon = NULL;
    wnd.hInstance = hinstMain;
    wnd.lpfnWndProc = VolumeControlProc;
    wnd.lpszClassName = VOLUME_CONTROL_CLASS;
    wnd.lpszMenuName = NULL;
    wnd.style = CS_PARENTDC | CS_VREDRAW | CS_HREDRAW;

    if(!RegisterClass(&wnd))
        CrashError(TEXT("Could not register volume control class"));
}
Exemplo n.º 22
0
// Basically the same as Open (and in fact Open could/should call ParseString to do its thing)
// But ParseString allows chunks of JSON type strings to be parse into the XConfig structure.
bool  XConfig::ParseString(const String& config)
{
    String safe_copy = config;
    TSTR lpTemp = safe_copy;

    RootElement = new XElement(this, NULL, TEXT("Root"));

    if(!ReadFileData2(RootElement, 0, lpTemp, true))
    {
        for(DWORD i=0; i<RootElement->SubItems.Num(); i++)
            delete RootElement->SubItems[i];

        CrashError(TEXT("Error parsing X string '%s'"), config.Array());

        Close(false);
    }

    return true;
}
Exemplo n.º 23
0
void InitVolumeMeter()
{
    /*initiate threshold values */
    maxLinear = DBtoLog(VOL_MAX);
    minLinear = DBtoLog(VOL_MIN);

    WNDCLASS wnd;

    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = sizeof(LPVOID);
    wnd.hbrBackground = NULL;
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
    wnd.hIcon = NULL;
    wnd.hInstance = hinstMain;
    wnd.lpfnWndProc = VolumeMeterProc;
    wnd.lpszClassName = VOLUME_METER_CLASS;
    wnd.lpszMenuName = NULL;
    wnd.style = CS_PARENTDC | CS_VREDRAW | CS_HREDRAW;

    if(!RegisterClass(&wnd))
        CrashError(TEXT("Could not register volume meter class"));
}
Exemplo n.º 24
0
void WINAPI DICreateMouseDevice(HANDLE window)
{
    traceIn(DICreateMouseDevice);

    if(bDInputActive)
    {
        HRESULT result;

        if(diDevice->CreateDevice(GUID_SysMouse, &diMouse, NULL) != DI_OK)
            CrashError(TEXT("DInput: Could not Create Mouse device"));
        if(diMouse->SetDataFormat(&c_dfDIMouse) != DI_OK)
            CrashError(TEXT("DInput: Could not set mouse data format"));
        if(diMouse->SetCooperativeLevel((HWND)window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
            CrashError(TEXT("DInput: Could not set mouse cooperation level"));

        if((result = diMouse->SetEventNotification(InputEvents[1])) != DI_OK)
            CrashError(TEXT("DInput: couldn't set a mouse notification.  that sucks."));

        if((result = diMouse->Acquire()) != DI_OK)
        {
            if(result != DIERR_OTHERAPPHASPRIO)
                CrashError(TEXT("DInput: Could not aquire mouse device"));
        }

        if((result = diMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mousestate)) != DI_OK)
        {
            if((result != DIERR_OTHERAPPHASPRIO) && (result != DIERR_NOTACQUIRED))
                CrashError(TEXT("DInput: Could not get mouse state"));

            curMouseButtonStates = 0;
        }
        else
        {
            if(mousestate.rgbButtons[0])
                curMouseButtonStates |= STATE_LBUTTONDOWN;
            if(mousestate.rgbButtons[1])
                curMouseButtonStates |= STATE_MBUTTONDOWN;
            if(mousestate.rgbButtons[2])
                curMouseButtonStates |= STATE_RBUTTONDOWN;
        }
    }

    traceOut;
}
Exemplo n.º 25
0
void WINAPI DICreateKeyboardDevice(HANDLE window)
{
    traceIn(DICreateKeyboardDevice);

    if(bDInputActive)
    {
        HRESULT result;

        if(diDevice->CreateDevice(GUID_SysKeyboard, &diKeyboard, NULL) != DI_OK)
            CrashError(TEXT("DInput: Could not Create Keyboard device"));

        if(diKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
            CrashError(TEXT("DInput: Could not set keyboard data format"));

        if(diKeyboard->SetCooperativeLevel((HWND)window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
            CrashError(TEXT("DInput: Could not set keyboard cooperation level"));


        if((result = diKeyboard->SetEventNotification(InputEvents[0])) != DI_OK)
            CrashError(TEXT("DInput: couldn't set a keyboard notification.  that sucks."));

        if((result = diKeyboard->Acquire()) != DI_OK)
        {
            if(result != DIERR_OTHERAPPHASPRIO)
                CrashError(TEXT("DInput: Could not aquire keyboard device"));
        }

        if((result = diKeyboard->GetDeviceState(256, keys)) != DI_OK)
        {
            if((result != DIERR_OTHERAPPHASPRIO) && (result != DIERR_NOTACQUIRED))
                CrashError(TEXT("DInput: Could not get keyboard device state"));
        }
        /*else
        {
            keys[DIK_LSHIFT] |= keys[DIK_RSHIFT];
            keys[DIK_RSHIFT] = 0;

            keys[DIK_LCONTROL] |= keys[DIK_RCONTROL];
            keys[DIK_RCONTROL] = 0;
        }*/
    }

    traceOut;
}
Exemplo n.º 26
0
float ToggleVolumeControlMute(HWND hwnd)
{
    VolumeControlData *control = GetVolumeControlData(hwnd);
    if(!control)
        CrashError(TEXT("ToggleVolumeControlMute called on a control that's not a volume control"));

    if(control->curVolume < VOLN_MUTELEVEL)
    {
        if(control->lastUnmutedVol < VOLN_MUTELEVEL)
            control->lastUnmutedVol = 1.0f;
        control->curVolume = control->lastUnmutedVol;
    }
    else
    {
        control->lastUnmutedVol = control->curVolume;
        control->curVolume = 0.0f;
    }

    HDC hDC = GetDC(hwnd);
    control->DrawVolumeControl(hDC);
    ReleaseDC(hwnd, hDC);

    return control->curVolume;
}
Exemplo n.º 27
0
void OBS::Start()
{
    if(bRunning) return;

    OSEnterMutex (hStartupShutdownMutex);

    scenesConfig.Save();

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

    fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 30);
    frameTime = 1000/fps;

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

    if(!bLoggedSystemStats)
    {
        LogSystemStats();
        bLoggedSystemStats = TRUE;
    }

    OSCheckForBuggyDLLs();

    //-------------------------------------------------------------
retryHookTest:
    bool alreadyWarnedAboutModules = false;
    if (OSIncompatibleModulesLoaded())
    {
        Log(TEXT("Incompatible modules (pre-D3D) detected."));
        int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE);
        if (ret == IDABORT)
        {
            OSLeaveMutex (hStartupShutdownMutex);
            return;
        }
        else if (ret == IDRETRY)
        {
            goto retryHookTest;
        }

        alreadyWarnedAboutModules = true;
    }

    String strPatchesError;
    if (OSIncompatiblePatchesLoaded(strPatchesError))
    {
        OSLeaveMutex (hStartupShutdownMutex);
        MessageBox(hwndMain, strPatchesError.Array(), NULL, MB_ICONERROR);
        Log(TEXT("Incompatible patches detected."));
        return;
    }

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

    String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal"));
    if (!scmp(processPriority, TEXT("Idle")))
        SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
    else if (!scmp(processPriority, TEXT("Above Normal")))
        SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
    else if (!scmp(processPriority, TEXT("High")))
        SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);

    int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2);
    DWORD delayTime = (DWORD)AppConfig->GetInt(TEXT("Publish"), TEXT("Delay"));

    String strError;

    bFirstConnect = !bReconnecting;

    if(bTestStream)
        network = CreateNullNetwork();
    else
    {
        switch(networkMode)
        {
        case 0: network = (delayTime > 0) ? CreateDelayedPublisher(delayTime) : CreateRTMPPublisher(); break;
        case 1: network = CreateNullNetwork(); break;
        }
    }

    if(!network)
    {
        OSLeaveMutex (hStartupShutdownMutex);

        if(!bReconnecting)
            MessageBox(hwndMain, strError, NULL, MB_ICONERROR);
        else
            DialogBox(hinstMain, MAKEINTRESOURCE(IDD_RECONNECTING), hwndMain, OBS::ReconnectDialogProc);
        return;
    }

    bReconnecting = false;

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

    Log(TEXT("=====Stream Start: %s==============================================="), CurrentDateTimeString().Array());

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

    bEnableProjectorCursor = GlobalConfig->GetInt(L"General", L"EnableProjectorCursor", 1) != 0;
    bPleaseEnableProjector = bPleaseDisableProjector = false;

    int monitorID = AppConfig->GetInt(TEXT("Video"), TEXT("Monitor"));
    if(monitorID >= (int)monitors.Num())
        monitorID = 0;

    RECT &screenRect = monitors[monitorID].rect;
    int defCX = screenRect.right  - screenRect.left;
    int defCY = screenRect.bottom - screenRect.top;

    downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0);
    downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f);
    baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"),  defCX);
    baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY);

    baseCX = MIN(MAX(baseCX, 128), 4096);
    baseCY = MIN(MAX(baseCY, 128), 4096);

    scaleCX = UINT(double(baseCX) / double(downscale));
    scaleCY = UINT(double(baseCY) / double(downscale));

    //align width to 128bit for fast SSE YUV4:2:0 conversion
    outputCX = scaleCX & 0xFFFFFFFC;
    outputCY = scaleCY & 0xFFFFFFFE;

    bUseMultithreadedOptimizations = AppConfig->GetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), TRUE) != 0;
    Log(TEXT("  Multithreaded optimizations: %s"), (CTSTR)(bUseMultithreadedOptimizations ? TEXT("On") : TEXT("Off")));

    encoderSkipThreshold = GlobalConfig->GetInt(TEXT("Video"), TEXT("EncoderSkipThreshold"), fps/4);

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

    Log(TEXT("  Base resolution: %ux%u"), baseCX, baseCY);
    Log(TEXT("  Output resolution: %ux%u"), outputCX, outputCY);
    Log(TEXT("------------------------------------------"));

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

    GS = new D3D10System;
    GS->Init();

    //Thanks to ASUS OSD hooking the goddamn user mode driver framework (!!!!), we have to re-check for dangerous
    //hooks after initializing D3D.
retryHookTestV2:
    if (!alreadyWarnedAboutModules)
    {
        if (OSIncompatibleModulesLoaded())
        {
            Log(TEXT("Incompatible modules (post-D3D) detected."));
            int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE);
            if (ret == IDABORT)
            {
                //FIXME: really need a better way to abort startup than this...
                delete network;
                delete GS;

                OSLeaveMutex (hStartupShutdownMutex);
                return;
            }
            else if (ret == IDRETRY)
            {
                goto retryHookTestV2;
            }
        }
    }

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

    mainVertexShader    = CreateVertexShaderFromFile(TEXT("shaders/DrawTexture.vShader"));
    mainPixelShader     = CreatePixelShaderFromFile(TEXT("shaders/DrawTexture.pShader"));

    solidVertexShader   = CreateVertexShaderFromFile(TEXT("shaders/DrawSolid.vShader"));
    solidPixelShader    = CreatePixelShaderFromFile(TEXT("shaders/DrawSolid.pShader"));

    if(!mainVertexShader || !mainPixelShader)
        CrashError(TEXT("Unable to load DrawTexture shaders"));

    if(!solidVertexShader || !solidPixelShader)
        CrashError(TEXT("Unable to load DrawSolid shaders"));

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

    CTSTR lpShader;
    if(CloseFloat(downscale, 1.0))
        lpShader = TEXT("shaders/DrawYUVTexture.pShader");
    else if(downscale < 2.01)
    {
        switch(downscaleType)
        {
            case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break;
            case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break;
            case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break;
        }
    }
    else if(downscale < 3.01)
        lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader");
    else
        CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)"));

    yuvScalePixelShader = CreatePixelShaderFromFile(lpShader);
    if (!yuvScalePixelShader)
        CrashError(TEXT("Unable to create shader from file %s"), lpShader);

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

    for(UINT i=0; i<NUM_RENDER_BUFFERS; i++)
    {
        mainRenderTextures[i] = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE);
        yuvRenderTextures[i]  = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE);
    }

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

    D3D10_TEXTURE2D_DESC td;
    zero(&td, sizeof(td));
    td.Width            = outputCX;
    td.Height           = outputCY;
    td.Format           = DXGI_FORMAT_B8G8R8A8_UNORM;
    td.MipLevels        = 1;
    td.ArraySize        = 1;
    td.SampleDesc.Count = 1;
    td.ArraySize        = 1;
    td.Usage            = D3D10_USAGE_STAGING;
    td.CPUAccessFlags   = D3D10_CPU_ACCESS_READ;

    for(UINT i=0; i<NUM_RENDER_BUFFERS; i++)
    {
        HRESULT err = GetD3D()->CreateTexture2D(&td, NULL, &copyTextures[i]);
        if(FAILED(err))
        {
            CrashError(TEXT("Unable to create copy texture"));
            //todo - better error handling
        }
    }

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

    UINT format = AppConfig->GetInt(L"Audio Encoding", L"Format", 1);

    switch (format) {
    case 0: sampleRateHz = 44100; break;
    default:
    case 1: sampleRateHz = 48000; break;
    }

    Log(L"------------------------------------------");
    Log(L"Audio Format: %uhz", sampleRateHz);

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

    AudioDeviceList playbackDevices;
    GetAudioDevices(playbackDevices, ADT_PLAYBACK);

    String strPlaybackDevice = AppConfig->GetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default"));
    if(strPlaybackDevice.IsEmpty() || !playbackDevices.HasID(strPlaybackDevice))
    {
        AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default"));
        strPlaybackDevice = TEXT("Default");
    }

    Log(TEXT("Playback device %s"), strPlaybackDevice.Array());
    playbackDevices.FreeData();

    desktopAudio = CreateAudioSource(false, strPlaybackDevice);

    if(!desktopAudio) {
        CrashError(TEXT("Cannot initialize desktop audio sound, more info in the log file."));
    }

    AudioDeviceList audioDevices;
    GetAudioDevices(audioDevices, ADT_RECORDING);

    String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL);
    if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice))
    {
        AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable"));
        strDevice = TEXT("Disable");
    }

    audioDevices.FreeData();

    String strDefaultMic;
    bool bHasDefault = GetDefaultMicID(strDefaultMic);

    if(strDevice.CompareI(TEXT("Disable")))
        EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE);
    else
    {
        bool bUseDefault = strDevice.CompareI(TEXT("Default")) != 0;
        if(!bUseDefault || bHasDefault)
        {
            if(bUseDefault)
                strDevice = strDefaultMic;

            micAudio = CreateAudioSource(true, strDevice);

            if(!micAudio)
                MessageBox(hwndMain, Str("MicrophoneFailure"), NULL, 0);
            else
                micAudio->SetTimeOffset(AppConfig->GetInt(TEXT("Audio"), TEXT("MicTimeOffset"), 0));

            EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), micAudio != NULL);
        }
        else
            EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE);
    }

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

    bool bDisableEncoding = false;

    if (bTestStream)
        bDisableEncoding = GlobalConfig->GetInt(TEXT("General"), TEXT("DisablePreviewEncoding"), false) != 0;

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

    UINT bitRate = (UINT)AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96);
    String strEncoder = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC"));

    if (bDisableEncoding)
        audioEncoder = CreateNullAudioEncoder();
    else
#ifdef USE_AAC
    if(strEncoder.CompareI(TEXT("AAC")))// && OSGetVersion() >= 7)
        audioEncoder = CreateAACEncoder(bitRate);
    else
#endif
        audioEncoder = CreateMP3Encoder(bitRate);

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

    desktopVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("DesktopVolume"), 1.0f);
    micVol     = AppConfig->GetFloat(TEXT("Audio"), TEXT("MicVolume"),     1.0f);

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

    bRunning = true;

    if(sceneElement)
    {
        scene = CreateScene(sceneElement->GetString(TEXT("class")), sceneElement->GetElement(TEXT("data")));
        XElement *sources = sceneElement->GetElement(TEXT("sources"));
        if(sources)
        {
            UINT numSources = sources->NumElements();
            for(UINT i=0; i<numSources; i++)
            {
                SceneItem *item = scene->AddImageSource(sources->GetElementByID(i));
                if(item)
                {
                    if(ListView_GetItemState(GetDlgItem(hwndMain, ID_SOURCES), i, LVIS_SELECTED) > 0)
                        item->Select(true);
                }
            }
        }

        scene->BeginScene();
    }

    if(scene && scene->HasMissingSources())
        MessageBox(hwndMain, Str("Scene.MissingSources"), NULL, 0);

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

    int maxBitRate = AppConfig->GetInt   (TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
    int bufferSize = AppConfig->GetInt   (TEXT("Video Encoding"), TEXT("BufferSize"), 1000);
    int quality    = AppConfig->GetInt   (TEXT("Video Encoding"), TEXT("Quality"),    8);
    String preset  = AppConfig->GetString(TEXT("Video Encoding"), TEXT("Preset"),     TEXT("veryfast"));
    bUsing444      = false;//AppConfig->GetInt   (TEXT("Video Encoding"), TEXT("Use444"),     0) != 0;
    bUseCFR        = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 1) != 0;

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

    bWriteToFile = networkMode == 1 || AppConfig->GetInt(TEXT("Publish"), TEXT("SaveToFile")) != 0;
    String strOutputFile = AppConfig->GetString(TEXT("Publish"), TEXT("SavePath"));

    strOutputFile.FindReplace(TEXT("\\"), TEXT("/"));

    if (bWriteToFile)
    {
        OSFindData ofd;
        HANDLE hFind = NULL;
        bool bUseDateTimeName = true;
        bool bOverwrite = GlobalConfig->GetInt(L"General", L"OverwriteRecordings", false) != 0;

        if(!bOverwrite && (hFind = OSFindFirstFile(strOutputFile, ofd)))
        {
            String strFileExtension = GetPathExtension(strOutputFile);
            String strFileWithoutExtension = GetPathWithoutExtension(strOutputFile);

            if(strFileExtension.IsValid() && !ofd.bDirectory)
            {
                String strNewFilePath;
                UINT curFile = 0;

                do 
                {
                    strNewFilePath.Clear() << strFileWithoutExtension << TEXT(" (") << FormattedString(TEXT("%02u"), ++curFile) << TEXT(").") << strFileExtension;
                } while(OSFileExists(strNewFilePath));

                strOutputFile = strNewFilePath;

                bUseDateTimeName = false;
            }

            if(ofd.bDirectory)
                strOutputFile.AppendChar('/');

            OSFindClose(hFind);
        }

        if(bUseDateTimeName)
        {
            String strFileName = GetPathFileName(strOutputFile);

            if(!strFileName.IsValid() || !IsSafeFilename(strFileName))
            {
                SYSTEMTIME st;
                GetLocalTime(&st);

                String strDirectory = GetPathDirectory(strOutputFile),
                       extension = GetPathExtension(strOutputFile);
                if(extension.IsEmpty())
                    extension = TEXT("mp4");
                strOutputFile = FormattedString(TEXT("%s/%u-%02u-%02u-%02u%02u-%02u.%s"), strDirectory.Array(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, extension.Array());
            }
        }
    }

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

    bufferingTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 700);
    Log(TEXT("Scene buffering time set to %u"), bufferingTime);

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

    bForceMicMono = AppConfig->GetInt(TEXT("Audio"), TEXT("ForceMicMono")) != 0;
    bRecievedFirstAudioFrame = false;

    //hRequestAudioEvent = CreateSemaphore(NULL, 0, 0x7FFFFFFFL, NULL);
    hSoundDataMutex = OSCreateMutex();
    hSoundThread = OSCreateThread((XTHREAD)OBS::MainAudioThread, NULL);

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

    StartBlankSoundPlayback(strPlaybackDevice);

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

    colorDesc.fullRange = false;
    colorDesc.primaries = ColorPrimaries_BT709;
    colorDesc.transfer  = ColorTransfer_IEC6196621;
    colorDesc.matrix    = outputCX >= 1280 || outputCY > 576 ? ColorMatrix_BT709 : ColorMatrix_SMPTE170M;

    videoEncoder = nullptr;
    if (bDisableEncoding)
        videoEncoder = CreateNullVideoEncoder();
    else if(AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0)
        videoEncoder = CreateQSVEncoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR);

    if(!videoEncoder)
        videoEncoder = CreateX264Encoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR);


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

    // Ensure that the render frame is properly sized
    ResizeRenderFrame(true);

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

    if(!bTestStream && bWriteToFile && strOutputFile.IsValid())
    {
        String strFileExtension = GetPathExtension(strOutputFile);
        if(strFileExtension.CompareI(TEXT("flv")))
            fileStream = CreateFLVFileStream(strOutputFile);
        else if(strFileExtension.CompareI(TEXT("mp4")))
            fileStream = CreateMP4FileStream(strOutputFile);

        if(!fileStream)
        {
            Log(TEXT("Warning - OBSCapture::Start: Unable to create the file stream. Check the file path in Broadcast Settings."));
            MessageBox(hwndMain, Str("Capture.Start.FileStream.Warning"), Str("Capture.Start.FileStream.WarningCaption"), MB_OK | MB_ICONWARNING);        
        }
    }

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

    curFramePic = NULL;
    bShutdownVideoThread = false;
    bShutdownEncodeThread = false;
    //ResetEvent(hVideoThread);
    hEncodeThread = OSCreateThread((XTHREAD)OBS::EncodeThread, NULL);
    hVideoThread = OSCreateThread((XTHREAD)OBS::MainCaptureThread, NULL);

    if(bTestStream)
    {
        EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), FALSE);
        SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.StopTest"));
    }
    else
    {
        EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), FALSE);
        SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StopStream"));
    }

    EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), TRUE);

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

    ReportStartStreamTrigger();
    
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, 0);
    SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED | ES_DISPLAY_REQUIRED);

    UpdateRenderViewMessage();

    //update notification icon to reflect current status
    UpdateNotificationAreaIcon();

    OSLeaveMutex (hStartupShutdownMutex);
}
Exemplo n.º 28
0
void AudioSource::InitAudioData(bool bFloat, UINT channels, UINT samplesPerSec, UINT bitsPerSample, UINT blockSize, DWORD channelMask, bool bSmoothTimestamps)
{
    this->bFloat = bFloat;
    this->bSmoothTimestamps = bSmoothTimestamps;
    inputChannels = channels;
    inputSamplesPerSec = samplesPerSec;
    inputBitsPerSample = bitsPerSample;
    inputBlockSize = blockSize;
    inputChannelMask = channelMask;

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

    if(inputSamplesPerSec != 44100)
    {
        int errVal;

        int converterType = SRC_SINC_FASTEST;
        resampler = src_new(converterType, 2, &errVal);
        if(!resampler)
            CrashError(TEXT("AudioSource::InitAudioData: Could not initiate resampler"));

        resampleRatio = 44100.0 / double(inputSamplesPerSec);
        bResample = true;

        //----------------------------------------------------
        // hack to get rid of that weird first quirky resampled packet size
        // (always returns a non-441 sized packet on the first resample)

        SRC_DATA data;
        data.src_ratio = resampleRatio;

        List<float> blankBuffer;
        blankBuffer.SetSize(inputSamplesPerSec/100*2);

        data.data_in = blankBuffer.Array();
        data.input_frames = inputSamplesPerSec/100;

        UINT frameAdjust = UINT((double(data.input_frames) * resampleRatio) + 1.0);
        UINT newFrameSize = frameAdjust*2;

        tempResampleBuffer.SetSize(newFrameSize);

        data.data_out = tempResampleBuffer.Array();
        data.output_frames = frameAdjust;

        data.end_of_input = 0;

        int err = src_process((SRC_STATE*)resampler, &data);

        nop();
    }

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

    if(inputChannels > 2)
    {
        if(inputChannelMask == 0)
        {
            switch(inputChannels)
            {
                case 3: inputChannelMask = KSAUDIO_SPEAKER_2POINT1; break;
                case 4: inputChannelMask = KSAUDIO_SPEAKER_QUAD;    break;
                case 5: inputChannelMask = KSAUDIO_SPEAKER_4POINT1; break;
                case 6: inputChannelMask = KSAUDIO_SPEAKER_5POINT1; break;
                case 8: inputChannelMask = KSAUDIO_SPEAKER_7POINT1; break;
            }
        }

        switch(inputChannelMask)
        {
            case KSAUDIO_SPEAKER_QUAD:              Log(TEXT("Using quad speaker setup"));                          break; //ocd anyone?
            case KSAUDIO_SPEAKER_2POINT1:           Log(TEXT("Using 2.1 speaker setup"));                           break;
            case KSAUDIO_SPEAKER_4POINT1:           Log(TEXT("Using 4.1 speaker setup"));                           break;
            case KSAUDIO_SPEAKER_SURROUND:          Log(TEXT("Using basic surround speaker setup"));                break;
            case KSAUDIO_SPEAKER_5POINT1:           Log(TEXT("Using 5.1 speaker setup"));                           break;
            case KSAUDIO_SPEAKER_5POINT1_SURROUND:  Log(TEXT("Using 5.1 surround speaker setup"));                  break;
            case KSAUDIO_SPEAKER_7POINT1:           Log(TEXT("Using 7.1 speaker setup (experimental)"));            break;
            case KSAUDIO_SPEAKER_7POINT1_SURROUND:  Log(TEXT("Using 7.1 surround speaker setup (experimental)"));   break;

            default:
                Log(TEXT("Using unknown speaker setup: 0x%lX"), inputChannelMask);
                CrashError(TEXT("Speaker setup not yet implemented -- dear god of all the audio APIs, the one I -have- to use doesn't support resampling or downmixing.  fabulous."));
                break;
        }
    }
}
Exemplo n.º 29
0
void ConfigFile::LoadData()
{
    TSTR lpCurLine = lpFileData, lpNextLine;
    ConfigSection *lpCurSection=NULL;
    DWORD i;

    lpNextLine = schr(lpCurLine, '\r');

    while(*(lpCurLine = (lpNextLine+2)))
    {
        lpNextLine = schr(lpCurLine, '\r');
        if (!lpNextLine)
            CrashError(TEXT("Your %s file is corrupt, please delete it and re-launch OBS."), strFileName.Array());
        *lpNextLine = 0;

        if((*lpCurLine == '[') && (*(lpNextLine-1) == ']'))
        {
            lpCurSection = Sections.CreateNew();

            lpCurSection->name = sfix(sdup(lpCurLine+1));
            lpCurSection->name[lpNextLine-lpCurLine-2] = 0;
        }
        else if(lpCurSection && *lpCurLine && (*(LPWORD)lpCurLine != '//'))
        {
            TSTR lpValuePtr = schr(lpCurLine, '=');
            if (!lpValuePtr)
                CrashError(TEXT("Your %s file is corrupt, please delete it and re-launch OBS."), strFileName.Array());

            if(lpValuePtr[1] != 0)
            {
                ConfigKey *key=NULL;

                *lpValuePtr = 0;

                for(i=0; i<lpCurSection->Keys.Num(); i++)
                {
                    if(scmpi(lpCurLine, lpCurSection->Keys[i].name) == 0)
                    {
                        key = &lpCurSection->Keys[i];
                        break;
                    }
                }

                if(!key)
                {
                    key = lpCurSection->Keys.CreateNew();
                    key->name = sfix(sdup(lpCurLine));
                }

                *lpValuePtr = '=';

                lpCurLine = lpValuePtr+1;

                TSTR value = sfix(sdup(lpCurLine));
                key->ValueList << value;
            }
        }

        *lpNextLine = '\r';
    }
}
Exemplo n.º 30
0
D3D10System::D3D10System()
{
    traceIn(D3D10System::D3D10System);

    HRESULT err;

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

    DXGI_SWAP_CHAIN_DESC swapDesc;
    zero(&swapDesc, sizeof(swapDesc));
    swapDesc.BufferCount = 2;
    swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    swapDesc.BufferDesc.Width  = App->renderFrameWidth;
    swapDesc.BufferDesc.Height = App->renderFrameHeight;
    swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapDesc.Flags = 0;
    swapDesc.OutputWindow = hwndRenderFrame;
    swapDesc.SampleDesc.Count = 1;
    swapDesc.Windowed = TRUE;

    bDisableCompatibilityMode = AppConfig->GetInt(TEXT("Video"), TEXT("DisableD3DCompatibilityMode"), 1) != 0;

    UINT createFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
    if(GlobalConfig->GetInt(TEXT("General"), TEXT("UseDebugD3D")))
        createFlags |= D3D10_CREATE_DEVICE_DEBUG;

    D3D10_FEATURE_LEVEL1 level = bDisableCompatibilityMode ? D3D10_FEATURE_LEVEL_10_1 : D3D10_FEATURE_LEVEL_9_3;

    //D3D10_CREATE_DEVICE_DEBUG
    //D3D11_DRIVER_TYPE_REFERENCE, D3D11_DRIVER_TYPE_HARDWARE
    err = D3D10CreateDeviceAndSwapChain1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createFlags, level, D3D10_1_SDK_VERSION, &swapDesc, &swap, &d3d);
    if(FAILED(err))
    {
        bDisableCompatibilityMode = !bDisableCompatibilityMode;
        level = bDisableCompatibilityMode ? D3D10_FEATURE_LEVEL_10_1 : D3D10_FEATURE_LEVEL_9_3;
        err = D3D10CreateDeviceAndSwapChain1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createFlags, level, D3D10_1_SDK_VERSION, &swapDesc, &swap, &d3d);
    }

    if(FAILED(err))
        CrashError(TEXT("Could not create D3D10 device and swap chain.  If you get this error, it's likely you probably use a GPU that is old, or that is unsupported."));

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

    Log(TEXT("Loading up D3D10..."));

    D3D10_DEPTH_STENCIL_DESC depthDesc;
    zero(&depthDesc, sizeof(depthDesc));
    depthDesc.DepthEnable = FALSE;

    err = d3d->CreateDepthStencilState(&depthDesc, &depthState);
    if(FAILED(err))
        CrashError(TEXT("Unable to create depth state"));

    d3d->OMSetDepthStencilState(depthState, 0);

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

    D3D10_RASTERIZER_DESC rasterizerDesc;
    zero(&rasterizerDesc, sizeof(rasterizerDesc));
    rasterizerDesc.FillMode = D3D10_FILL_SOLID;
    rasterizerDesc.CullMode = D3D10_CULL_NONE;
    rasterizerDesc.FrontCounterClockwise = FALSE;
    rasterizerDesc.DepthClipEnable = TRUE;

    err = d3d->CreateRasterizerState(&rasterizerDesc, &rasterizerState);
    if(FAILED(err))
        CrashError(TEXT("Unable to create rasterizer state"));

    d3d->RSSetState(rasterizerState);

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

    ID3D10Texture2D *backBuffer = NULL;
    err = swap->GetBuffer(0, IID_ID3D10Texture2D, (void**)&backBuffer);
    if(FAILED(err))
        CrashError(TEXT("Unable to get back buffer from swap chain"));

    err = d3d->CreateRenderTargetView(backBuffer, NULL, &swapRenderView);
    if(FAILED(err))
        CrashError(TEXT("Unable to get render view from back buffer"));

    backBuffer->Release();

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

    D3D10_BLEND_DESC disabledBlendDesc;
    zero(&disabledBlendDesc, sizeof(disabledBlendDesc));
    for(int i=0; i<8; i++)
    {
        disabledBlendDesc.BlendEnable[i]        = TRUE;
        disabledBlendDesc.RenderTargetWriteMask[i] = D3D10_COLOR_WRITE_ENABLE_ALL;
    }
    disabledBlendDesc.BlendOpAlpha          = D3D10_BLEND_OP_ADD;
    disabledBlendDesc.BlendOp               = D3D10_BLEND_OP_ADD;
    disabledBlendDesc.SrcBlendAlpha         = D3D10_BLEND_ONE;
    disabledBlendDesc.DestBlendAlpha        = D3D10_BLEND_ZERO;
    disabledBlendDesc.SrcBlend              = D3D10_BLEND_ONE;
    disabledBlendDesc.DestBlend             = D3D10_BLEND_ZERO;

    err = d3d->CreateBlendState(&disabledBlendDesc, &disabledBlend);
    if(FAILED(err))
        CrashError(TEXT("Unable to create disabled blend state"));

    this->BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, 1.0f);
    bBlendingEnabled = true;

    traceOut;
}