Moved QSV encoder implementation to QSVHelper
Notable improvements: - fixes d3d11 mode on all tested configurations - should improve compatibility with Optimus (untested)
This commit is contained in:
parent
9ef424ade8
commit
134a13c80d
21
OBS-All.sln
21
OBS-All.sln
@ -46,6 +46,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSVPlugin", "PSVPlugin\PSVP
|
||||
{11A35235-DD48-41E2-8F40-825C78024BC0} = {11A35235-DD48-41E2-8F40-825C78024BC0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QSVHelper", "QSVHelper\QSVHelper.vcxproj", "{F1C7033A-F050-46E3-9080-E129B9CD1010}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F} = {9E7B3527-11AA-46BA-A82F-C58761F9B56F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@ -136,12 +141,12 @@ Global
|
||||
{5465C79D-01DF-406C-AB2D-9C0764917131}.Release|x64.Build.0 = Release|x64
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Debug|x64.Build.0 = Debug|x64
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Debug|x64.Build.0 = Debug|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Release|Win32.Build.0 = Release|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Release|x64.ActiveCfg = Release|x64
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Release|x64.Build.0 = Release|x64
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Release|x64.ActiveCfg = Release|Win32
|
||||
{9E7B3527-11AA-46BA-A82F-C58761F9B56F}.Release|x64.Build.0 = Release|Win32
|
||||
{D13C4DA1-A806-49D0-9603-AF40D34D0EF3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D13C4DA1-A806-49D0-9603-AF40D34D0EF3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D13C4DA1-A806-49D0-9603-AF40D34D0EF3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@ -150,6 +155,14 @@ Global
|
||||
{D13C4DA1-A806-49D0-9603-AF40D34D0EF3}.Release|Win32.Build.0 = Release|Win32
|
||||
{D13C4DA1-A806-49D0-9603-AF40D34D0EF3}.Release|x64.ActiveCfg = Release|x64
|
||||
{D13C4DA1-A806-49D0-9603-AF40D34D0EF3}.Release|x64.Build.0 = Release|x64
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Debug|x64.Build.0 = Debug|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Release|Win32.Build.0 = Release|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Release|x64.ActiveCfg = Release|Win32
|
||||
{F1C7033A-F050-46E3-9080-E129B9CD1010}.Release|x64.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
16
OBS.vcxproj
16
OBS.vcxproj
@ -112,10 +112,10 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;libmfx.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>
|
||||
</Version>
|
||||
<AdditionalLibraryDirectories>libmfx/$(Platform)/$(Configuration);OBSApi/Debug;x264/libs/32bit;librtmp/debug;lame/output/32bit;libfaac/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>OBSApi/Debug;x264/libs/32bit;librtmp/debug;lame/output/32bit;libfaac/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>type=%27win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>rundir\pdb32\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
@ -147,10 +147,10 @@
|
||||
<PrecompiledHeaderFile>Main.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;libmfx.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>
|
||||
</Version>
|
||||
<AdditionalLibraryDirectories>libmfx/$(Platform)/$(Configuration);OBSApi/x64/Debug;x264/libs/64bit;librtmp/x64/debug;lame/output/64bit;libfaac/x64/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>OBSApi/x64/Debug;x264/libs/64bit;librtmp/x64/debug;lame/output/64bit;libfaac/x64/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>type=%27win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27amd64%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>rundir\pdb64\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
@ -180,10 +180,10 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;libmfx.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>
|
||||
</Version>
|
||||
<AdditionalLibraryDirectories>libmfx/$(Platform)/$(Configuration);OBSApi/Release;x264/libs/32bit;librtmp/release;lame/output/32bit;libfaac/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>OBSApi/Release;x264/libs/32bit;librtmp/release;lame/output/32bit;libfaac/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>rundir\pdb32\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
@ -218,10 +218,10 @@
|
||||
<PrecompiledHeaderFile>Main.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;libmfx.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Avrt.lib;dwmapi.lib;comctl32.lib;dxgi.lib;dxguid.lib;d3d10_1.lib;d3dx10.lib;ws2_32.lib;Iphlpapi.lib;Winmm.lib;librtmp.lib;libmp3lame-static.lib;libfaac.lib;dsound.lib;obsapi.lib;shell32.lib;gdiplus.lib;mfplat.lib;Mfuuid.lib;Winhttp.lib;libx264.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>
|
||||
</Version>
|
||||
<AdditionalLibraryDirectories>libmfx/$(Platform)/$(Configuration);OBSApi/x64/Release;x264/libs/64bit;librtmp/x64/release;lame/output/64bit;libfaac/x64/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>OBSApi/x64/Release;x264/libs/64bit;librtmp/x64/release;lame/output/64bit;libfaac/x64/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalManifestDependencies>type=%27win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27amd64%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>rundir\pdb64\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
|
436
QSVHelper/Encoder.h
Normal file
436
QSVHelper/Encoder.h
Normal file
@ -0,0 +1,436 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mfxvideo++.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "d3d11_allocator.h"
|
||||
#include "d3d11_device.h"
|
||||
|
||||
#include "IPCInfo.h"
|
||||
#include "IPCStructs.h"
|
||||
#include "SupportStuff.h"
|
||||
#include "WindowsStuff.h"
|
||||
|
||||
struct Encoder
|
||||
{
|
||||
bool use_cbr;
|
||||
|
||||
bool first_frame;
|
||||
|
||||
unsigned frame_time_ms;
|
||||
|
||||
int exit_code;
|
||||
|
||||
mfxIMPL requested, actual;
|
||||
mfxVersion version;
|
||||
|
||||
|
||||
Parameters params;
|
||||
mfxFrameAllocRequest req;
|
||||
mfxFrameAllocResponse alloc_res;
|
||||
|
||||
|
||||
bool using_d3d11;
|
||||
CD3D11Device d3d11;
|
||||
D3D11FrameAllocator d3d11_alloc;
|
||||
|
||||
|
||||
MFXVideoSession session;
|
||||
MFXVideoENCODE encoder;
|
||||
|
||||
|
||||
std::wstring event_prefix;
|
||||
|
||||
ipc_bitstream_buff bitstream;
|
||||
ipc_filled_bitstream filled_bitstream;
|
||||
ipc_bitstream_info bs_info;
|
||||
|
||||
ipc_frame_buff frame_buff;
|
||||
ipc_frame_buff_status frame_buff_status;
|
||||
ipc_frame_queue frame_queue;
|
||||
|
||||
ipc_sps_buff sps_buffer;
|
||||
ipc_pps_buff pps_buffer;
|
||||
ipc_spspps_size spspps_queried_size;
|
||||
|
||||
|
||||
std::vector<encode_task> encode_tasks;
|
||||
std::queue<size_t> idle_tasks, queued_tasks, encoded_tasks;
|
||||
|
||||
std::vector<mfxFrameSurface1> surfaces;
|
||||
std::queue<mfxFrameSurface1*> idle_surfaces;
|
||||
std::vector<std::pair<mfxFrameSurface1*, uint32_t>> msdk_locked_tasks;
|
||||
|
||||
std::vector<mfxFrameData> frames;
|
||||
|
||||
|
||||
EncodeCtrl keyframe_ctrl, sei_ctrl;
|
||||
|
||||
|
||||
std::wofstream &log_file;
|
||||
|
||||
|
||||
operator bool() { return static_cast<mfxSession>(session) != nullptr; }
|
||||
|
||||
Encoder(IPCSignalledType<init_request> &init_req, std::wstring event_prefix, std::wofstream &log_file)
|
||||
: use_cbr(init_req->use_cbr), first_frame(true), frame_time_ms(static_cast<unsigned>(1./init_req->fps*1000)), exit_code(0)
|
||||
, using_d3d11(false), session(), encoder(session), event_prefix(event_prefix), log_file(log_file)
|
||||
{
|
||||
params.Init(init_req->fps, init_req->keyint, init_req->bframes, init_req->width, init_req->height, init_req->max_bitrate, init_req->buffer_size, init_req->use_cbr);
|
||||
params.SetVideoSignalInfo(init_req->full_range, init_req->primaries, init_req->transfer, init_req->matrix);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
mfxStatus InitializeMFX(T& impl, bool force=false)
|
||||
{
|
||||
session.Close();
|
||||
|
||||
version = impl.version;
|
||||
requested = impl.type | impl.intf;
|
||||
auto result = session.Init(requested, &version);
|
||||
if(result < 0) return result;
|
||||
|
||||
session.QueryIMPL(&actual);
|
||||
|
||||
if(using_d3d11 = (actual & MFX_IMPL_VIA_D3D11) == MFX_IMPL_VIA_D3D11)
|
||||
{
|
||||
mfxU32 device = 0;
|
||||
switch(MFX_IMPL_BASETYPE(actual))
|
||||
{
|
||||
case MFX_IMPL_HARDWARE: device = 0; break;
|
||||
case MFX_IMPL_HARDWARE2: device = 1; break;
|
||||
case MFX_IMPL_HARDWARE3: device = 2; break;
|
||||
case MFX_IMPL_HARDWARE4: device = 3; break;
|
||||
default: exit_code = 1000; return MFX_ERR_DEVICE_FAILED;
|
||||
}
|
||||
|
||||
d3d11.Init(nullptr, 1, device);
|
||||
mfxHDL hdl = nullptr;
|
||||
d3d11.GetHandle(MFX_HANDLE_D3D11_DEVICE, &hdl);
|
||||
session.SetHandle(MFX_HANDLE_D3D11_DEVICE, hdl);
|
||||
|
||||
D3D11AllocatorParams alloc_params;
|
||||
alloc_params.pDevice = reinterpret_cast<ID3D11Device*>(hdl);
|
||||
d3d11_alloc.Init(&alloc_params);
|
||||
session.SetFrameAllocator(&d3d11_alloc);
|
||||
params->IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
|
||||
}
|
||||
|
||||
encoder = MFXVideoENCODE(session);
|
||||
|
||||
zero(req);
|
||||
result = encoder.QueryIOSurf(¶ms, &req);
|
||||
return result;
|
||||
}
|
||||
|
||||
void InitializeBuffers(ipc_init_response &init_res)
|
||||
{
|
||||
using namespace std;
|
||||
Parameters query = params;
|
||||
encoder.GetVideoParam(query);
|
||||
|
||||
unsigned num_bitstreams = max(6, req.NumFrameSuggested + query->AsyncDepth)+3, //+NUM_OUT_BUFFERS
|
||||
num_surf = num_bitstreams * (using_d3d11 ? 2 : 1),
|
||||
num_frames = using_d3d11 ? num_bitstreams : num_surf,
|
||||
num_d3d11_frames = num_surf;
|
||||
|
||||
encode_tasks.resize(num_bitstreams);
|
||||
|
||||
const unsigned bs_size = (max(query->mfx.BufferSizeInKB*1000, params->mfx.BufferSizeInKB*1000)+31)/32*32;
|
||||
params->mfx.BufferSizeInKB = bs_size/1000;
|
||||
init_res->bitstream_size = bs_size;
|
||||
|
||||
bitstream = ipc_bitstream_buff(event_prefix + BITSTREAM_BUFF, encode_tasks.size() * bs_size + 31);
|
||||
mfxU8 *bs_start = (mfxU8*)(((size_t)&bitstream + 31)/32*32);
|
||||
size_t index = 0;
|
||||
for(auto task = begin(encode_tasks); task != end(encode_tasks); task++, index++)
|
||||
{
|
||||
task->Init(bs_start, bs_size);
|
||||
idle_tasks.push(index);
|
||||
bs_start += bs_size;
|
||||
}
|
||||
|
||||
filled_bitstream = ipc_filled_bitstream(event_prefix + FILLED_BITSTREAM);
|
||||
{
|
||||
auto lock = lock_mutex(filled_bitstream);
|
||||
*filled_bitstream = -1;
|
||||
}
|
||||
|
||||
bs_info = ipc_bitstream_info(event_prefix + BITSTREAM_INFO, encode_tasks.size());
|
||||
|
||||
|
||||
if(using_d3d11)
|
||||
{
|
||||
req.NumFrameSuggested = num_d3d11_frames;
|
||||
d3d11_alloc.AllocFrames(&req, &alloc_res);
|
||||
}
|
||||
|
||||
mfxFrameInfo &fi = params->mfx.FrameInfo;
|
||||
|
||||
surfaces.resize(num_surf);
|
||||
for(size_t i = 0; i < surfaces.size(); i++)
|
||||
{
|
||||
idle_surfaces.emplace(&surfaces[i]);
|
||||
memcpy(&surfaces[i].Info, &fi, sizeof(fi));
|
||||
if(using_d3d11)
|
||||
surfaces[i].Data.MemId = alloc_res.mids[i];
|
||||
}
|
||||
|
||||
const unsigned lum_channel_size = fi.Width*fi.Height,
|
||||
uv_channel_size = fi.Width*fi.Height,
|
||||
frame_size = lum_channel_size + uv_channel_size;
|
||||
init_res->frame_size = frame_size;
|
||||
init_res->UV_offset = lum_channel_size;
|
||||
init_res->V_offset = lum_channel_size+1;
|
||||
init_res->frame_pitch = fi.Width;
|
||||
|
||||
frames.resize(num_frames);
|
||||
frame_queue = ipc_frame_queue(event_prefix + FRAME_QUEUE, frames.size());
|
||||
{
|
||||
auto lock = lock_mutex(frame_queue);
|
||||
zero(*static_cast<queued_frame*>(frame_queue), sizeof(queued_frame) * frame_queue.size);
|
||||
}
|
||||
|
||||
frame_buff = ipc_frame_buff(event_prefix + FRAME_BUFF, frames.size() * frame_size + 15);
|
||||
mfxU8 *frame_start = (mfxU8*)(((size_t)&frame_buff + 15)/16*16);
|
||||
zero(*frame_start, frame_size * frames.size());
|
||||
for(auto frame = begin(frames); frame != end(frames); frame++)
|
||||
{
|
||||
InitFrame(*frame, frame_start, frame_start + init_res->UV_offset, frame_start + init_res->V_offset, fi.Width);
|
||||
frame_start += frame_size;
|
||||
}
|
||||
|
||||
frame_buff_status = ipc_frame_buff_status(event_prefix + FRAME_BUFF_STATUS, frames.size());
|
||||
{
|
||||
auto lock = lock_mutex(frame_buff_status);
|
||||
zero(frame_buff_status[0], frames.size() * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
init_res->target_usage = params->mfx.TargetUsage;
|
||||
init_res->bitstream_num = encode_tasks.size();
|
||||
init_res->frame_num = frames.size();
|
||||
|
||||
keyframe_ctrl.ctrl.FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF | MFX_FRAMETYPE_IDR;
|
||||
sei_ctrl.AddSEIData(EncodeCtrl::SEI_USER_DATA_UNREGISTERED, InitSEIUserData(use_cbr, query, init_res->version));
|
||||
}
|
||||
|
||||
mfxStatus InitializeEncoder()
|
||||
{
|
||||
return encoder.Init(params);
|
||||
}
|
||||
|
||||
void RequestSPSPPS()
|
||||
{
|
||||
sps_buffer = ipc_sps_buff(event_prefix + SPS_BUFF, 100);
|
||||
pps_buffer = ipc_pps_buff(event_prefix + PPS_BUFF, 100);
|
||||
Parameters spspps_query;
|
||||
spspps_query.SetCodingOptionSPSPPS(sps_buffer, sps_buffer.size, pps_buffer, pps_buffer.size);
|
||||
encoder.GetVideoParam(spspps_query);
|
||||
spspps_queried_size = ipc_spspps_size(event_prefix + SPSPPS_SIZES);
|
||||
spspps_queried_size->sps_size = spspps_query.cospspps.SPSBufSize;
|
||||
spspps_queried_size->pps_size = spspps_query.cospspps.PPSBufSize;
|
||||
spspps_queried_size.signal();
|
||||
}
|
||||
|
||||
void ProcessEncodedFrame()
|
||||
{
|
||||
if(encoded_tasks.size())
|
||||
{
|
||||
encode_task& task = encode_tasks[encoded_tasks.front()];
|
||||
auto& sp = task.sp;
|
||||
|
||||
auto result = MFXVideoCORE_SyncOperation(session, sp, 0);
|
||||
if(result == MFX_WRN_IN_EXECUTION)
|
||||
return;
|
||||
|
||||
bitstream_info &info = bs_info[encoded_tasks.front()];
|
||||
info.time_stamp = task.bs.TimeStamp;
|
||||
info.data_length = task.bs.DataLength;
|
||||
info.data_offset = task.bs.DataOffset;
|
||||
info.pic_struct = task.bs.PicStruct;
|
||||
info.frame_type = task.bs.FrameType;
|
||||
|
||||
{
|
||||
auto lock = lock_mutex(filled_bitstream);
|
||||
if(*filled_bitstream >= 0)
|
||||
return;
|
||||
*filled_bitstream = encoded_tasks.front();
|
||||
}
|
||||
filled_bitstream.signal();
|
||||
|
||||
msdk_locked_tasks.emplace_back(std::make_pair(task.surf, task.frame_index));
|
||||
task.surf = nullptr;
|
||||
idle_tasks.emplace(encoded_tasks.front());
|
||||
encoded_tasks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void UnlockSurfaces()
|
||||
{
|
||||
for(size_t i = 0; i < msdk_locked_tasks.size();)
|
||||
{
|
||||
auto pair = msdk_locked_tasks[i];
|
||||
if(pair.first->Data.Locked)
|
||||
{
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
msdk_locked_tasks.erase(std::begin(msdk_locked_tasks)+i);
|
||||
|
||||
idle_surfaces.emplace(pair.first);
|
||||
|
||||
if(!using_d3d11)
|
||||
{
|
||||
auto lock = lock_mutex(frame_buff_status);
|
||||
frame_buff_status[pair.second] -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QueueTask()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(idle_tasks.empty())
|
||||
{
|
||||
log_file << "Warning: idle_tasks is empty (" << idle_tasks.size() << " idle, " << queued_tasks.size() << " queued, "
|
||||
<< encoded_tasks.size() << " encoded, " << msdk_locked_tasks.size() << " locked)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if(idle_surfaces.empty())
|
||||
{
|
||||
log_file << "Warning: idle_surfaces is empty (" << idle_tasks.size() << " idle, " << queued_tasks.size() << " queued, "
|
||||
<< encoded_tasks.size() << " encoded, " << msdk_locked_tasks.size() << " locked)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
auto end = static_cast<queued_frame*>(frame_queue)+frame_queue.size;
|
||||
auto lock = lock_mutex(frame_queue);
|
||||
auto oldest = min_element(static_cast<queued_frame*>(frame_queue), end, [](const queued_frame &f1, const queued_frame &f2) -> bool
|
||||
{
|
||||
if(f1.is_new)
|
||||
if(f2.is_new)
|
||||
return f1.timestamp < f2.timestamp;
|
||||
else
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
if(!oldest || !oldest->is_new)
|
||||
return;
|
||||
|
||||
oldest->is_new = false;
|
||||
|
||||
auto index = idle_tasks.front();
|
||||
queued_tasks.push(index);
|
||||
idle_tasks.pop();
|
||||
|
||||
encode_task &task = encode_tasks[index];
|
||||
task.bs.DataLength = 0;
|
||||
task.bs.DataOffset = 0;
|
||||
|
||||
task.surf = idle_surfaces.front();
|
||||
idle_surfaces.pop();
|
||||
|
||||
mfxFrameData &frame = frames[oldest->frame_index];
|
||||
if(using_d3d11)
|
||||
{
|
||||
d3d11_alloc.LockFrame(task.surf->Data.MemId, &task.surf->Data);
|
||||
for(size_t i = 0; i < task.surf->Info.Height; i++)
|
||||
memcpy(task.surf->Data.Y+i*task.surf->Data.Pitch, frame.Y+i*frame.Pitch, task.surf->Info.Width);
|
||||
for(size_t i = 0; i < (task.surf->Info.Height/2u); i++)
|
||||
memcpy(task.surf->Data.UV+i*task.surf->Data.Pitch, frame.UV+i*frame.Pitch, task.surf->Info.Width);
|
||||
d3d11_alloc.UnlockFrame(task.surf->Data.MemId, &task.surf->Data);
|
||||
auto lock = lock_mutex(frame_buff_status);
|
||||
frame_buff_status[oldest->frame_index] -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
task.surf->Data.Y = frame.Y;
|
||||
task.surf->Data.UV = frame.UV;
|
||||
task.surf->Data.V = frame.V;
|
||||
task.surf->Data.Pitch = frame.Pitch;
|
||||
}
|
||||
task.surf->Data.TimeStamp = oldest->timestamp;
|
||||
task.frame_index = oldest->frame_index;
|
||||
|
||||
if(oldest->request_keyframe)
|
||||
task.ctrl = &keyframe_ctrl;
|
||||
else
|
||||
task.ctrl = nullptr;
|
||||
|
||||
if(first_frame)
|
||||
task.ctrl = &sei_ctrl;
|
||||
first_frame = false;
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeTasks()
|
||||
{
|
||||
while(queued_tasks.size())
|
||||
{
|
||||
encode_task& task = encode_tasks[queued_tasks.front()];
|
||||
for(;;)
|
||||
{
|
||||
auto sts = encoder.EncodeFrameAsync(task.ctrl, task.surf, &task.bs, &task.sp);
|
||||
|
||||
if(sts == MFX_ERR_NONE || (MFX_ERR_NONE < sts && task.sp))
|
||||
break;
|
||||
if(sts == MFX_WRN_DEVICE_BUSY)
|
||||
return;
|
||||
if(sts == MFX_ERR_NOT_INITIALIZED) //returned after encoder.Init returns PARTIAL_ACCELERATION?
|
||||
{
|
||||
exit_code = EXIT_INCOMPATIBLE_CONFIGURATION;
|
||||
return;
|
||||
}
|
||||
//if(!sp); //sts == MFX_ERR_MORE_DATA usually; retry the call (see MSDK examples)
|
||||
//Log(TEXT("returned status %i, %u"), sts, insert);
|
||||
}
|
||||
encoded_tasks.push(queued_tasks.front());
|
||||
queued_tasks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
int EncodeLoop(IPCSignal &stop, safe_handle &obs_handle)
|
||||
{
|
||||
IPCWaiter waiter;
|
||||
waiter.push_back(stop.signal_);
|
||||
waiter.push_back(obs_handle);
|
||||
waiter.push_back(frame_queue.signal_);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(waiter.wait_for_two(0, 1, frame_time_ms/2) || exit_code)
|
||||
return exit_code;
|
||||
ProcessEncodedFrame();
|
||||
UnlockSurfaces();
|
||||
QueueTask();
|
||||
EncodeTasks();
|
||||
}
|
||||
}
|
||||
};
|
64
QSVHelper/IPCInfo.h
Normal file
64
QSVHelper/IPCInfo.h
Normal file
@ -0,0 +1,64 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "IPCStructs.h"
|
||||
#include "WindowsStuff.h"
|
||||
|
||||
|
||||
#define INIT_REQUEST L"init_request"
|
||||
typedef IPCSignalledType<init_request> ipc_init_request;
|
||||
|
||||
#define INIT_RESPONSE L"init_response"
|
||||
typedef IPCSignalledType<init_response> ipc_init_response;
|
||||
|
||||
#define BITSTREAM_BUFF L"bitstream_buff"
|
||||
typedef NamedSharedMemory ipc_bitstream_buff;
|
||||
|
||||
#define FILLED_BITSTREAM L"filled_bitstream"
|
||||
typedef IPCLockedSignalledType<int32_t> ipc_filled_bitstream;
|
||||
|
||||
#define BITSTREAM_INFO L"bitstream_info"
|
||||
typedef IPCArray<bitstream_info> ipc_bitstream_info;
|
||||
|
||||
#define FRAME_BUFF L"frame_buff"
|
||||
typedef NamedSharedMemory ipc_frame_buff;
|
||||
|
||||
#define FRAME_BUFF_STATUS L"frame_buff_status"
|
||||
typedef IPCLockedSignalledArray<uint32_t> ipc_frame_buff_status;
|
||||
|
||||
#define FRAME_QUEUE L"frame_queue"
|
||||
typedef IPCLockedSignalledArray<queued_frame> ipc_frame_queue;
|
||||
|
||||
#define SPS_BUFF L"sps_buff"
|
||||
typedef IPCArray<mfxU8> ipc_sps_buff;
|
||||
|
||||
#define PPS_BUFF L"pps_buff"
|
||||
typedef IPCArray<mfxU8> ipc_pps_buff;
|
||||
|
||||
#define SPSPPS_SIZES L"spspps_size"
|
||||
typedef IPCSignalledType<spspps_size> ipc_spspps_size;
|
||||
|
||||
#define STOP_REQUEST L"stop"
|
||||
typedef IPCSignal ipc_stop;
|
||||
|
||||
|
||||
#define EXIT_INCOMPATIBLE_CONFIGURATION 10
|
79
QSVHelper/IPCStructs.h
Normal file
79
QSVHelper/IPCStructs.h
Normal file
@ -0,0 +1,79 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mfxvideo++.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct init_request
|
||||
{
|
||||
enum { MODE_QUERY, MODE_ENCODE } mode;
|
||||
uint32_t obs_process_id;
|
||||
int32_t fps, keyint, bframes, width, height, max_bitrate, buffer_size;
|
||||
bool use_cbr;
|
||||
int32_t full_range, matrix, primaries, transfer;
|
||||
bool use_custom_impl;
|
||||
mfxVersion custom_version;
|
||||
mfxIMPL custom_impl, custom_intf;
|
||||
};
|
||||
|
||||
struct init_response
|
||||
{
|
||||
mfxU16 target_usage;
|
||||
mfxVersion version;
|
||||
mfxIMPL requested_impl,
|
||||
actual_impl;
|
||||
|
||||
bool using_custom_impl;
|
||||
|
||||
uint16_t bitstream_num,
|
||||
frame_num;
|
||||
uint32_t bitstream_size,
|
||||
frame_size,
|
||||
UV_offset,
|
||||
V_offset,
|
||||
frame_pitch;
|
||||
};
|
||||
|
||||
struct spspps_size
|
||||
{
|
||||
mfxU16 sps_size,
|
||||
pps_size;
|
||||
};
|
||||
|
||||
struct queued_frame
|
||||
{
|
||||
bool is_new;
|
||||
bool request_keyframe;
|
||||
mfxU64 timestamp;
|
||||
uint32_t frame_index;
|
||||
};
|
||||
|
||||
struct bitstream_info
|
||||
{
|
||||
mfxU64 time_stamp;
|
||||
mfxU32 data_offset, data_length;
|
||||
mfxU16 pic_struct, frame_type;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
177
QSVHelper/IntelSupport/include/base_allocator.h
Normal file
177
QSVHelper/IntelSupport/include/base_allocator.h
Normal file
@ -0,0 +1,177 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2008-2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#ifndef __BASE_ALLOCATOR_H__
|
||||
#define __BASE_ALLOCATOR_H__
|
||||
|
||||
#include <list>
|
||||
#include <string.h>
|
||||
#include <functional>
|
||||
#include "mfxvideo.h"
|
||||
|
||||
struct mfxAllocatorParams
|
||||
{
|
||||
virtual ~mfxAllocatorParams(){};
|
||||
};
|
||||
|
||||
// this class implements methods declared in mfxFrameAllocator structure
|
||||
// simply redirecting them to virtual methods which should be overridden in derived classes
|
||||
class MFXFrameAllocator : public mfxFrameAllocator
|
||||
{
|
||||
public:
|
||||
MFXFrameAllocator();
|
||||
virtual ~MFXFrameAllocator();
|
||||
|
||||
// optional method, override if need to pass some parameters to allocator from application
|
||||
virtual mfxStatus Init(mfxAllocatorParams *pParams) = 0;
|
||||
virtual mfxStatus Close() = 0;
|
||||
|
||||
virtual mfxStatus AllocFrames(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response) = 0;
|
||||
virtual mfxStatus LockFrame(mfxMemId mid, mfxFrameData *ptr) = 0;
|
||||
virtual mfxStatus UnlockFrame(mfxMemId mid, mfxFrameData *ptr) = 0;
|
||||
virtual mfxStatus GetFrameHDL(mfxMemId mid, mfxHDL *handle) = 0;
|
||||
virtual mfxStatus FreeFrames(mfxFrameAllocResponse *response) = 0;
|
||||
|
||||
private:
|
||||
static mfxStatus MFX_CDECL Alloc_(mfxHDL pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response);
|
||||
static mfxStatus MFX_CDECL Lock_(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
|
||||
static mfxStatus MFX_CDECL Unlock_(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
|
||||
static mfxStatus MFX_CDECL GetHDL_(mfxHDL pthis, mfxMemId mid, mfxHDL *handle);
|
||||
static mfxStatus MFX_CDECL Free_(mfxHDL pthis, mfxFrameAllocResponse *response);
|
||||
};
|
||||
|
||||
// This class implements basic logic of memory allocator
|
||||
// Manages responses for different components according to allocation request type
|
||||
// External frames of a particular component-related type are allocated in one call
|
||||
// Further calls return previously allocated response.
|
||||
// Ex. Preallocated frame chain with type=FROM_ENCODE | FROM_VPPIN will be returned when
|
||||
// request type contains either FROM_ENCODE or FROM_VPPIN
|
||||
|
||||
// This class does not allocate any actual memory
|
||||
class BaseFrameAllocator: public MFXFrameAllocator
|
||||
{
|
||||
public:
|
||||
BaseFrameAllocator();
|
||||
virtual ~BaseFrameAllocator();
|
||||
|
||||
virtual mfxStatus Init(mfxAllocatorParams *pParams) = 0;
|
||||
virtual mfxStatus Close();
|
||||
virtual mfxStatus AllocFrames(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response);
|
||||
virtual mfxStatus FreeFrames(mfxFrameAllocResponse *response);
|
||||
|
||||
protected:
|
||||
typedef std::list<mfxFrameAllocResponse>::iterator Iter;
|
||||
static const mfxU32 MEMTYPE_FROM_MASK = MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT;
|
||||
|
||||
struct UniqueResponse
|
||||
: mfxFrameAllocResponse
|
||||
{
|
||||
mfxU16 m_cropw;
|
||||
mfxU16 m_croph;
|
||||
mfxU32 m_refCount;
|
||||
mfxU16 m_type;
|
||||
|
||||
UniqueResponse()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
// compare responses by actual frame size, alignment (w and h) is up to application
|
||||
UniqueResponse(const mfxFrameAllocResponse & response, mfxU16 cropw, mfxU16 croph, mfxU16 type)
|
||||
: mfxFrameAllocResponse(response)
|
||||
, m_type(type)
|
||||
, m_refCount(1)
|
||||
, m_cropw(cropw)
|
||||
, m_croph(croph)
|
||||
{
|
||||
}
|
||||
//compare by resolution
|
||||
bool operator () (const UniqueResponse &response)const
|
||||
{
|
||||
return m_cropw == response.m_cropw && m_croph == response.m_croph;
|
||||
}
|
||||
};
|
||||
|
||||
std::list<mfxFrameAllocResponse> m_responses;
|
||||
std::list<UniqueResponse> m_ExtResponses;
|
||||
|
||||
struct IsSame
|
||||
: public std::binary_function<mfxFrameAllocResponse, mfxFrameAllocResponse, bool>
|
||||
{
|
||||
bool operator () (const mfxFrameAllocResponse & l, const mfxFrameAllocResponse &r)const
|
||||
{
|
||||
return r.mids != 0 && l.mids != 0 &&
|
||||
r.mids[0] == l.mids[0] &&
|
||||
r.NumFrameActual == l.NumFrameActual;
|
||||
}
|
||||
};
|
||||
|
||||
// checks if request is supported
|
||||
virtual mfxStatus CheckRequestType(mfxFrameAllocRequest *request);
|
||||
|
||||
// frees memory attached to response
|
||||
virtual mfxStatus ReleaseResponse(mfxFrameAllocResponse *response) = 0;
|
||||
// allocates memory
|
||||
virtual mfxStatus AllocImpl(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response) = 0;
|
||||
|
||||
template <class T>
|
||||
class safe_array
|
||||
{
|
||||
public:
|
||||
safe_array(T *ptr = 0):m_ptr(ptr)
|
||||
{ // construct from object pointer
|
||||
};
|
||||
~safe_array()
|
||||
{
|
||||
reset(0);
|
||||
}
|
||||
T* get()
|
||||
{ // return wrapped pointer
|
||||
return m_ptr;
|
||||
}
|
||||
T* release()
|
||||
{ // return wrapped pointer and give up ownership
|
||||
T* ptr = m_ptr;
|
||||
m_ptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
void reset(T* ptr)
|
||||
{ // destroy designated object and store new pointer
|
||||
if (m_ptr)
|
||||
{
|
||||
delete[] m_ptr;
|
||||
}
|
||||
m_ptr = ptr;
|
||||
}
|
||||
protected:
|
||||
T* m_ptr; // the wrapped object pointer
|
||||
};
|
||||
};
|
||||
|
||||
class MFXBufferAllocator : public mfxBufferAllocator
|
||||
{
|
||||
public:
|
||||
MFXBufferAllocator();
|
||||
virtual ~MFXBufferAllocator();
|
||||
|
||||
virtual mfxStatus AllocBuffer(mfxU32 nbytes, mfxU16 type, mfxMemId *mid) = 0;
|
||||
virtual mfxStatus LockBuffer(mfxMemId mid, mfxU8 **ptr) = 0;
|
||||
virtual mfxStatus UnlockBuffer(mfxMemId mid) = 0;
|
||||
virtual mfxStatus FreeBuffer(mfxMemId mid) = 0;
|
||||
|
||||
private:
|
||||
static mfxStatus MFX_CDECL Alloc_(mfxHDL pthis, mfxU32 nbytes, mfxU16 type, mfxMemId *mid);
|
||||
static mfxStatus MFX_CDECL Lock_(mfxHDL pthis, mfxMemId mid, mfxU8 **ptr);
|
||||
static mfxStatus MFX_CDECL Unlock_(mfxHDL pthis, mfxMemId mid);
|
||||
static mfxStatus MFX_CDECL Free_(mfxHDL pthis, mfxMemId mid);
|
||||
};
|
||||
|
||||
|
||||
#endif // __BASE_ALLOCATOR_H__
|
18
QSVHelper/IntelSupport/include/current_date.h
Normal file
18
QSVHelper/IntelSupport/include/current_date.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
#define CURRENT_DATE "Build_2013/6/27"
|
||||
|
||||
#define PRODUCT_NAME "Intel® Media SDK"
|
||||
|
||||
#define FILE_VERSION 4,13,6,27
|
||||
|
||||
#define FILE_VERSION_STRING "4,13,6,27"
|
||||
|
||||
#define FILTER_NAME_PREFIX "Intel® Media SDK"
|
||||
|
||||
#define FILTER_NAME_SUFFIX ""
|
||||
|
||||
#define PRODUCT_COPYRIGHT "Copyright© 2003-2013 Intel Corporation"
|
||||
|
||||
#define PRODUCT_VERSION 4,0,760,0
|
||||
|
||||
#define PRODUCT_VERSION_STRING "4,0,760,0"
|
253
QSVHelper/IntelSupport/include/d3d11_allocator.h
Normal file
253
QSVHelper/IntelSupport/include/d3d11_allocator.h
Normal file
@ -0,0 +1,253 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011-2013 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#ifndef __D3D11_ALLOCATOR_H__
|
||||
#define __D3D11_ALLOCATOR_H__
|
||||
|
||||
// defines MFX_D3D11_SUPPORT
|
||||
#include "sample_defs.h"
|
||||
|
||||
#include "base_allocator.h"
|
||||
#include <limits>
|
||||
|
||||
//application can provide either generic mid from surface or this wrapper
|
||||
//wrapper distinguishes from generic mid by highest 1 bit
|
||||
//if it set then remained pointer points to extended structure of memid
|
||||
//64 bits system layout
|
||||
/*----+-----------------------------------------------------------+
|
||||
|b63=1|63 bits remained for pointer to extended structure of memid|
|
||||
|b63=0|63 bits from original mfxMemId |
|
||||
+-----+----------------------------------------------------------*/
|
||||
//32 bits system layout
|
||||
/*--+---+--------------------------------------------+
|
||||
|b31=1|31 bits remained for pointer to extended memid|
|
||||
|b31=0|31 bits remained for surface pointer |
|
||||
+---+---+-------------------------------------------*/
|
||||
//#pragma warning (disable:4293)
|
||||
class MFXReadWriteMid
|
||||
{
|
||||
static const uintptr_t bits_offset = std::numeric_limits<uintptr_t>::digits - 1;
|
||||
static const uintptr_t clear_mask = ~((uintptr_t)1 << bits_offset);
|
||||
public:
|
||||
enum
|
||||
{
|
||||
//if flag not set it means that read and write
|
||||
not_set = 0,
|
||||
reuse = 1,
|
||||
read = 2,
|
||||
write = 4,
|
||||
};
|
||||
//here mfxmemid might be as MFXReadWriteMid or mfxMemId memid
|
||||
MFXReadWriteMid(mfxMemId mid, mfxU8 flag = not_set)
|
||||
{
|
||||
//setup mid
|
||||
m_mid_to_report = (mfxMemId)((uintptr_t)&m_mid | ((uintptr_t)1 << bits_offset));
|
||||
if (0 != ((uintptr_t)mid >> bits_offset))
|
||||
{
|
||||
//it points to extended structure
|
||||
mfxMedIdEx * pMemIdExt = reinterpret_cast<mfxMedIdEx *>((uintptr_t)mid & clear_mask);
|
||||
m_mid.pId = pMemIdExt->pId;
|
||||
if (reuse == flag)
|
||||
{
|
||||
m_mid.read_write = pMemIdExt->read_write;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mid.read_write = flag;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mid.pId = mid;
|
||||
if (reuse == flag)
|
||||
m_mid.read_write = not_set;
|
||||
else
|
||||
m_mid.read_write = flag;
|
||||
}
|
||||
|
||||
}
|
||||
bool isRead() const
|
||||
{
|
||||
return 0 != (m_mid.read_write & read) || !m_mid.read_write;
|
||||
}
|
||||
bool isWrite() const
|
||||
{
|
||||
return 0 != (m_mid.read_write & write) || !m_mid.read_write;
|
||||
}
|
||||
/// returns original memid without read write flags
|
||||
mfxMemId raw() const
|
||||
{
|
||||
return m_mid.pId;
|
||||
}
|
||||
operator mfxMemId() const
|
||||
{
|
||||
return m_mid_to_report;
|
||||
}
|
||||
|
||||
private:
|
||||
struct mfxMedIdEx
|
||||
{
|
||||
mfxMemId pId;
|
||||
mfxU8 read_write;
|
||||
};
|
||||
|
||||
mfxMedIdEx m_mid;
|
||||
mfxMemId m_mid_to_report;
|
||||
};
|
||||
|
||||
#if MFX_D3D11_SUPPORT
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
struct ID3D11VideoDevice;
|
||||
struct ID3D11VideoContext;
|
||||
|
||||
struct D3D11AllocatorParams : mfxAllocatorParams
|
||||
{
|
||||
ID3D11Device *pDevice;
|
||||
bool bUseSingleTexture;
|
||||
DWORD uncompressedResourceMiscFlags;
|
||||
|
||||
D3D11AllocatorParams()
|
||||
: pDevice()
|
||||
, bUseSingleTexture()
|
||||
, uncompressedResourceMiscFlags()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class D3D11FrameAllocator: public BaseFrameAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
D3D11FrameAllocator();
|
||||
virtual ~D3D11FrameAllocator();
|
||||
|
||||
virtual mfxStatus Init(mfxAllocatorParams *pParams);
|
||||
virtual mfxStatus Close();
|
||||
virtual ID3D11Device * GetD3D11Device()
|
||||
{
|
||||
return m_initParams.pDevice;
|
||||
};
|
||||
virtual mfxStatus LockFrame(mfxMemId mid, mfxFrameData *ptr);
|
||||
virtual mfxStatus UnlockFrame(mfxMemId mid, mfxFrameData *ptr);
|
||||
virtual mfxStatus GetFrameHDL(mfxMemId mid, mfxHDL *handle);
|
||||
|
||||
protected:
|
||||
static DXGI_FORMAT ConverColortFormat(mfxU32 fourcc);
|
||||
virtual mfxStatus CheckRequestType(mfxFrameAllocRequest *request);
|
||||
virtual mfxStatus ReleaseResponse(mfxFrameAllocResponse *response);
|
||||
virtual mfxStatus AllocImpl(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response);
|
||||
|
||||
D3D11AllocatorParams m_initParams;
|
||||
ID3D11DeviceContext *m_pDeviceContext;
|
||||
|
||||
struct TextureResource
|
||||
{
|
||||
std::vector<mfxMemId> outerMids;
|
||||
std::vector<ID3D11Texture2D*> textures;
|
||||
std::vector<ID3D11Texture2D*> stagingTexture;
|
||||
bool bAlloc;
|
||||
|
||||
TextureResource()
|
||||
: bAlloc(true)
|
||||
{
|
||||
}
|
||||
|
||||
static bool isAllocated (TextureResource & that)
|
||||
{
|
||||
return that.bAlloc;
|
||||
}
|
||||
ID3D11Texture2D* GetTexture(mfxMemId id)
|
||||
{
|
||||
if (outerMids.empty())
|
||||
return NULL;
|
||||
|
||||
return textures[((uintptr_t)id - (uintptr_t)outerMids.front()) % textures.size()];
|
||||
}
|
||||
UINT GetSubResource(mfxMemId id)
|
||||
{
|
||||
if (outerMids.empty())
|
||||
return NULL;
|
||||
|
||||
return (UINT)(((uintptr_t)id - (uintptr_t)outerMids.front()) / textures.size());
|
||||
}
|
||||
void Release()
|
||||
{
|
||||
size_t i = 0;
|
||||
for(i = 0; i < textures.size(); i++)
|
||||
{
|
||||
textures[i]->Release();
|
||||
}
|
||||
textures.clear();
|
||||
|
||||
for(i = 0; i < stagingTexture.size(); i++)
|
||||
{
|
||||
stagingTexture[i]->Release();
|
||||
}
|
||||
stagingTexture.clear();
|
||||
|
||||
//marking texture as deallocated
|
||||
bAlloc = false;
|
||||
}
|
||||
};
|
||||
class TextureSubResource
|
||||
{
|
||||
TextureResource * m_pTarget;
|
||||
ID3D11Texture2D * m_pTexture;
|
||||
ID3D11Texture2D * m_pStaging;
|
||||
UINT m_subResource;
|
||||
public:
|
||||
TextureSubResource(TextureResource * pTarget = NULL, mfxMemId id = 0)
|
||||
: m_pTarget(pTarget)
|
||||
, m_pTexture()
|
||||
, m_subResource()
|
||||
, m_pStaging(NULL)
|
||||
{
|
||||
if (NULL != m_pTarget && !m_pTarget->outerMids.empty())
|
||||
{
|
||||
ptrdiff_t idx = (uintptr_t)MFXReadWriteMid(id).raw() - (uintptr_t)m_pTarget->outerMids.front();
|
||||
m_pTexture = m_pTarget->textures[idx % m_pTarget->textures.size()];
|
||||
m_subResource = (UINT)(idx / m_pTarget->textures.size());
|
||||
m_pStaging = m_pTarget->stagingTexture.empty() ? NULL : m_pTarget->stagingTexture[idx];
|
||||
}
|
||||
}
|
||||
ID3D11Texture2D* GetStaging()const
|
||||
{
|
||||
return m_pStaging;
|
||||
}
|
||||
ID3D11Texture2D* GetTexture()const
|
||||
{
|
||||
return m_pTexture;
|
||||
}
|
||||
UINT GetSubResource()const
|
||||
{
|
||||
return m_subResource;
|
||||
}
|
||||
void Release()
|
||||
{
|
||||
if (NULL != m_pTarget)
|
||||
m_pTarget->Release();
|
||||
}
|
||||
};
|
||||
|
||||
TextureSubResource GetResourceFromMid(mfxMemId);
|
||||
|
||||
std::list <TextureResource> m_resourcesByRequest;//each alloc request generates new item in list
|
||||
|
||||
typedef std::list <TextureResource>::iterator referenceType;
|
||||
std::vector<referenceType> m_memIdMap;
|
||||
};
|
||||
|
||||
#endif // #if MFX_D3D11_SUPPORT
|
||||
|
||||
#endif // __D3D11_ALLOCATOR_H__
|
67
QSVHelper/IntelSupport/include/d3d11_device.h
Normal file
67
QSVHelper/IntelSupport/include/d3d11_device.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011 - 2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sample_defs.h" // defines MFX_D3D11_SUPPORT
|
||||
|
||||
#if MFX_D3D11_SUPPORT
|
||||
#include "hw_device.h"
|
||||
#include <windows.h>
|
||||
#include <d3d11.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
#include <dxgi1_2.h>
|
||||
|
||||
class CD3D11Device: public CHWDevice
|
||||
{
|
||||
public:
|
||||
CD3D11Device();
|
||||
virtual ~CD3D11Device();
|
||||
virtual mfxStatus Init(
|
||||
mfxHDL hWindow,
|
||||
mfxU16 nViews,
|
||||
mfxU32 nAdapterNum);
|
||||
virtual mfxStatus Reset();
|
||||
virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *pHdl);
|
||||
virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl);
|
||||
virtual mfxStatus RenderFrame(mfxFrameSurface1 * pSurface, mfxFrameAllocator * pmfxAlloc);
|
||||
virtual void Close();
|
||||
protected:
|
||||
virtual mfxStatus FillSCD(mfxHDL hWindow, DXGI_SWAP_CHAIN_DESC& scd);
|
||||
mfxStatus CreateVideoProcessor(mfxFrameSurface1 * pSrf);
|
||||
|
||||
CComPtr<ID3D11Device> m_pD3D11Device;
|
||||
CComPtr<ID3D11DeviceContext> m_pD3D11Ctx;
|
||||
CComQIPtr<ID3D11VideoDevice> m_pDX11VideoDevice;
|
||||
CComQIPtr<ID3D11VideoContext> m_pVideoContext;
|
||||
CComPtr<ID3D11VideoProcessorEnumerator> m_VideoProcessorEnum;
|
||||
|
||||
CComQIPtr<IDXGIDevice1> m_pDXGIDev;
|
||||
CComQIPtr<IDXGIAdapter> m_pAdapter;
|
||||
|
||||
CComPtr<IDXGIFactory2> m_pDXGIFactory;
|
||||
|
||||
CComPtr<IDXGISwapChain1> m_pSwapChain;
|
||||
CComPtr<ID3D11VideoProcessor> m_pVideoProcessor;
|
||||
|
||||
private:
|
||||
CComPtr<ID3D11VideoProcessorInputView> m_pInputViewLeft;
|
||||
CComPtr<ID3D11VideoProcessorInputView> m_pInputViewRight;
|
||||
CComPtr<ID3D11VideoProcessorOutputView> m_pOutputView;
|
||||
|
||||
CComPtr<ID3D11Texture2D> m_pDXGIBackBuffer;
|
||||
CComPtr<ID3D11Texture2D> m_pTempTexture;
|
||||
CComPtr<IDXGIDisplayControl> m_pDisplayControl;
|
||||
CComPtr<IDXGIOutput> m_pDXGIOutput;
|
||||
mfxU16 m_nViews;
|
||||
BOOL m_bDefaultStereoEnabled;
|
||||
};
|
||||
#endif //#if MFX_D3D11_SUPPORT
|
39
QSVHelper/IntelSupport/include/hw_device.h
Normal file
39
QSVHelper/IntelSupport/include/hw_device.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011 - 2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mfxvideo++.h"
|
||||
|
||||
/// Base class for hw device
|
||||
class CHWDevice
|
||||
{
|
||||
public:
|
||||
virtual ~CHWDevice(){}
|
||||
/** Initializes device for requested processing.
|
||||
@param[in] hWindow Window handle to bundle device to.
|
||||
@param[in] nViews Number of views to process.
|
||||
@param[in] nAdapterNum Number of adapter to use
|
||||
*/
|
||||
virtual mfxStatus Init(
|
||||
mfxHDL hWindow,
|
||||
mfxU16 nViews,
|
||||
mfxU32 nAdapterNum) = 0;
|
||||
/// Reset device.
|
||||
virtual mfxStatus Reset() = 0;
|
||||
/// Get handle can be used for MFX session SetHandle calls
|
||||
virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *pHdl) = 0;
|
||||
/** Set handle.
|
||||
Particular device implementation may require other objects to operate.
|
||||
*/
|
||||
virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl) = 0;
|
||||
virtual mfxStatus RenderFrame(mfxFrameSurface1 * pSurface, mfxFrameAllocator * pmfxAlloc) = 0;
|
||||
virtual void Close() = 0;
|
||||
};
|
92
QSVHelper/IntelSupport/include/sample_defs.h
Normal file
92
QSVHelper/IntelSupport/include/sample_defs.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* ////////////////////////////////////////////////////////////////////////////// */
|
||||
/*
|
||||
//
|
||||
// INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Intel Corporation and may not be copied
|
||||
// or disclosed except in accordance with the terms of that agreement.
|
||||
// Copyright (c) 2005-2013 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
//
|
||||
*/
|
||||
|
||||
#ifndef __SAMPLE_DEFS_H__
|
||||
#define __SAMPLE_DEFS_H__
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "mfxdefs.h"
|
||||
#include "vm/strings_defs.h"
|
||||
//#include "vm/file_defs.h"
|
||||
|
||||
#ifndef D3D_SURFACES_SUPPORT
|
||||
#define D3D_SURFACES_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(MFX_D3D11_SUPPORT)
|
||||
#include <sdkddkver.h>
|
||||
#if (NTDDI_VERSION >= NTDDI_VERSION_FROM_WIN32_WINNT2(0x0602)) // >= _WIN32_WINNT_WIN8
|
||||
#define MFX_D3D11_SUPPORT 1 // Enable D3D11 support if SDK allows
|
||||
#else
|
||||
#define MFX_D3D11_SUPPORT 0
|
||||
#endif
|
||||
#endif //defined(WIN32) || defined(WIN64)
|
||||
|
||||
//affects win32 winnt version macro
|
||||
#include "vm/time_defs.h"
|
||||
//#include "sample_utils.h"
|
||||
|
||||
|
||||
#define MSDK_DEC_WAIT_INTERVAL 60000
|
||||
#define MSDK_ENC_WAIT_INTERVAL 10000
|
||||
#define MSDK_VPP_WAIT_INTERVAL 60000
|
||||
#define MSDK_WAIT_INTERVAL MSDK_DEC_WAIT_INTERVAL+3*MSDK_VPP_WAIT_INTERVAL+MSDK_ENC_WAIT_INTERVAL // an estimate for the longest pipeline we have in samples
|
||||
|
||||
#define MSDK_INVALID_SURF_IDX 0xFFFF
|
||||
|
||||
#define MSDK_MAX_FILENAME_LEN 1024
|
||||
|
||||
#define MSDK_PRINT_RET_MSG(ERR) {msdk_printf(MSDK_STRING("\nReturn on error: error code %d,\t%s\t%d\n\n"), ERR, MSDK_STRING(__FILE__), __LINE__);}
|
||||
|
||||
#define MSDK_CHECK_ERROR(P, X, ERR) {if ((X) == (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}}
|
||||
#define MSDK_CHECK_NOT_EQUAL(P, X, ERR) {if ((X) != (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}}
|
||||
#define MSDK_CHECK_RESULT(P, X, ERR) {if ((X) > (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}}
|
||||
#define MSDK_CHECK_PARSE_RESULT(P, X, ERR) {if ((X) > (P)) {return ERR;}}
|
||||
#define MSDK_CHECK_RESULT_SAFE(P, X, ERR, ADD) {if ((X) > (P)) {ADD; MSDK_PRINT_RET_MSG(ERR); return ERR;}}
|
||||
#define MSDK_IGNORE_MFX_STS(P, X) {if ((X) == (P)) {P = MFX_ERR_NONE;}}
|
||||
#define MSDK_CHECK_POINTER(P, ...) {if (!(P)) {return __VA_ARGS__;}}
|
||||
#define MSDK_CHECK_POINTER_NO_RET(P) {if (!(P)) {return;}}
|
||||
#define MSDK_CHECK_POINTER_SAFE(P, ERR, ADD) {if (!(P)) {ADD; return ERR;}}
|
||||
#define MSDK_BREAK_ON_ERROR(P) {if (MFX_ERR_NONE != (P)) break;}
|
||||
#define MSDK_SAFE_DELETE_ARRAY(P) {if (P) {delete[] P; P = NULL;}}
|
||||
#define MSDK_SAFE_RELEASE(X) {if (X) { X->Release(); X = NULL; }}
|
||||
|
||||
#ifndef MSDK_SAFE_DELETE
|
||||
#define MSDK_SAFE_DELETE(P) {if (P) {delete P; P = NULL;}}
|
||||
#endif // MSDK_SAFE_DELETE
|
||||
|
||||
#define MSDK_ZERO_MEMORY(VAR) {memset(&VAR, 0, sizeof(VAR));}
|
||||
#define MSDK_MAX(A, B) (((A) > (B)) ? (A) : (B))
|
||||
#define MSDK_MIN(A, B) (((A) < (B)) ? (A) : (B))
|
||||
#define MSDK_ALIGN16(value) (((value + 15) >> 4) << 4) // round up to a multiple of 16
|
||||
#define MSDK_ALIGN32(value) (((value + 31) >> 5) << 5) // round up to a multiple of 32
|
||||
#define MSDK_ALIGN(value, alignment) (alignment) * ( (value) / (alignment) + (((value) % (alignment)) ? 1 : 0))
|
||||
#define MSDK_ARRAY_LEN(value) (sizeof(value) / sizeof(value[0]))
|
||||
|
||||
#define MSDK_MEMCPY_BITSTREAM(bitstream, offset, src, count) memcpy_s((bitstream).Data + (offset), (bitstream).MaxLength - (offset), (src), (count))
|
||||
|
||||
#define MSDK_MEMCPY_BUF(bufptr, offset, maxsize, src, count) memcpy_s((bufptr)+ (offset), (maxsize) - (offset), (src), (count))
|
||||
|
||||
#define MSDK_MEMCPY_VAR(dstVarName, src, count) memcpy_s(&(dstVarName), sizeof(dstVarName), (src), (count))
|
||||
|
||||
#ifndef UNREFERENCED_PARAMETER
|
||||
#define UNREFERENCED_PARAMETER(par) (par)
|
||||
#endif
|
||||
|
||||
#ifndef MFX_PRODUCT_VERSION
|
||||
#define MFX_PRODUCT_VERSION "4.0.760.60435"
|
||||
#endif
|
||||
|
||||
#define MSDK_SAMPLE_VERSION MSDK_STRING(MFX_PRODUCT_VERSION)
|
||||
|
||||
#endif //__SAMPLE_DEFS_H__
|
45
QSVHelper/IntelSupport/include/vm/strings_defs.h
Normal file
45
QSVHelper/IntelSupport/include/vm/strings_defs.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* ////////////////////////////////////////////////////////////////////////////// */
|
||||
/*
|
||||
//
|
||||
// INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Intel Corporation and may not be copied
|
||||
// or disclosed except in accordance with the terms of that agreement.
|
||||
// Copyright (c) 2011-2013 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
//
|
||||
*/
|
||||
|
||||
#ifndef __STRING_DEFS_H__
|
||||
#define __STRING_DEFS_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#define MSDK_STRING(x) _T(x)
|
||||
#define MSDK_CHAR(x) _T(x)
|
||||
typedef TCHAR msdk_char;
|
||||
|
||||
#define msdk_printf _tprintf
|
||||
#define msdk_fprintf _ftprintf
|
||||
#define msdk_sprintf _stprintf_s
|
||||
#define msdk_vprintf _vtprintf
|
||||
#define msdk_strlen _tcslen
|
||||
#define msdk_strcmp _tcscmp
|
||||
#define msdk_strncmp _tcsnicmp
|
||||
#define msdk_strstr _tcsstr
|
||||
#define msdk_sscanf _stscanf_s
|
||||
#define msdk_atoi _ttoi
|
||||
#define msdk_strtol _tcstol
|
||||
#define msdk_strtod _tcstod
|
||||
#define msdk_strchr _tcschr
|
||||
#define msdk_itoa_decimal(value, str) _itow_s(value, str, 4, 10)
|
||||
|
||||
// msdk_strcopy is intended to be used with 2 parmeters, i.e. msdk_strcopy(dst, src)
|
||||
// for _tcscpy_s that's possible if DST is declared as: TCHAR DST[n];
|
||||
#define msdk_strcopy _tcscpy_s
|
||||
|
||||
#endif //__STRING_DEFS_H__
|
19
QSVHelper/IntelSupport/include/vm/time_defs.h
Normal file
19
QSVHelper/IntelSupport/include/vm/time_defs.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#ifndef __TIME_DEFS_H__
|
||||
#define __TIME_DEFS_H__
|
||||
|
||||
#include "mfxdefs.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#define MSDK_SLEEP(msec) Sleep(msec)
|
||||
|
||||
#endif // #ifndef __TIME_DEFS_H__
|
263
QSVHelper/IntelSupport/src/base_allocator.cpp
Normal file
263
QSVHelper/IntelSupport/src/base_allocator.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2008-2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include "base_allocator.h"
|
||||
|
||||
MFXFrameAllocator::MFXFrameAllocator()
|
||||
{
|
||||
pthis = this;
|
||||
Alloc = Alloc_;
|
||||
Lock = Lock_;
|
||||
Free = Free_;
|
||||
Unlock = Unlock_;
|
||||
GetHDL = GetHDL_;
|
||||
}
|
||||
|
||||
MFXFrameAllocator::~MFXFrameAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
mfxStatus MFXFrameAllocator::Alloc_(mfxHDL pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
||||
|
||||
return self.AllocFrames(request, response);
|
||||
}
|
||||
|
||||
mfxStatus MFXFrameAllocator::Lock_(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
||||
|
||||
return self.LockFrame(mid, ptr);
|
||||
}
|
||||
|
||||
mfxStatus MFXFrameAllocator::Unlock_(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
||||
|
||||
return self.UnlockFrame(mid, ptr);
|
||||
}
|
||||
|
||||
mfxStatus MFXFrameAllocator::Free_(mfxHDL pthis, mfxFrameAllocResponse *response)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
||||
|
||||
return self.FreeFrames(response);
|
||||
}
|
||||
|
||||
mfxStatus MFXFrameAllocator::GetHDL_(mfxHDL pthis, mfxMemId mid, mfxHDL *handle)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
||||
|
||||
return self.GetFrameHDL(mid, handle);
|
||||
}
|
||||
|
||||
BaseFrameAllocator::BaseFrameAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
BaseFrameAllocator::~BaseFrameAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
mfxStatus BaseFrameAllocator::CheckRequestType(mfxFrameAllocRequest *request)
|
||||
{
|
||||
if (0 == request)
|
||||
return MFX_ERR_NULL_PTR;
|
||||
|
||||
// check that Media SDK component is specified in request
|
||||
if ((request->Type & MEMTYPE_FROM_MASK) != 0)
|
||||
return MFX_ERR_NONE;
|
||||
else
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mfxStatus BaseFrameAllocator::AllocFrames(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
|
||||
{
|
||||
if (0 == request || 0 == response || 0 == request->NumFrameSuggested)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
if (MFX_ERR_NONE != CheckRequestType(request))
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
|
||||
mfxStatus sts = MFX_ERR_NONE;
|
||||
|
||||
if ( (request->Type & MFX_MEMTYPE_EXTERNAL_FRAME) && (request->Type & MFX_MEMTYPE_FROM_DECODE) )
|
||||
{
|
||||
// external decoder allocations
|
||||
std::list<UniqueResponse>::iterator it =
|
||||
std::find_if( m_ExtResponses.begin()
|
||||
, m_ExtResponses.end()
|
||||
, UniqueResponse (*response, request->Info.CropW, request->Info.CropH, 0));
|
||||
|
||||
if (it != m_ExtResponses.end())
|
||||
{
|
||||
// check if enough frames were allocated
|
||||
if (request->NumFrameMin > it->NumFrameActual)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
it->m_refCount++;
|
||||
// return existing response
|
||||
*response = (mfxFrameAllocResponse&)*it;
|
||||
}
|
||||
else
|
||||
{
|
||||
sts = AllocImpl(request, response);
|
||||
if (sts == MFX_ERR_NONE)
|
||||
{
|
||||
m_ExtResponses.push_back(UniqueResponse(*response, request->Info.CropW, request->Info.CropH, request->Type & MEMTYPE_FROM_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal allocations
|
||||
|
||||
// reserve space before allocation to avoid memory leak
|
||||
m_responses.push_back(mfxFrameAllocResponse());
|
||||
|
||||
sts = AllocImpl(request, response);
|
||||
if (sts == MFX_ERR_NONE)
|
||||
{
|
||||
m_responses.back() = *response;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_responses.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
mfxStatus BaseFrameAllocator::FreeFrames(mfxFrameAllocResponse *response)
|
||||
{
|
||||
if (response == 0)
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
|
||||
mfxStatus sts = MFX_ERR_NONE;
|
||||
|
||||
// check whether response is an external decoder response
|
||||
std::list<UniqueResponse>::iterator i =
|
||||
std::find_if( m_ExtResponses.begin(), m_ExtResponses.end(), std::bind1st(IsSame(), *response));
|
||||
|
||||
if (i != m_ExtResponses.end())
|
||||
{
|
||||
if ((--i->m_refCount) == 0)
|
||||
{
|
||||
sts = ReleaseResponse(response);
|
||||
m_ExtResponses.erase(i);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
// if not found so far, then search in internal responses
|
||||
std::list<mfxFrameAllocResponse>::iterator i2 =
|
||||
std::find_if(m_responses.begin(), m_responses.end(), std::bind1st(IsSame(), *response));
|
||||
|
||||
if (i2 != m_responses.end())
|
||||
{
|
||||
sts = ReleaseResponse(response);
|
||||
m_responses.erase(i2);
|
||||
return sts;
|
||||
}
|
||||
|
||||
// not found anywhere, report an error
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
mfxStatus BaseFrameAllocator::Close()
|
||||
{
|
||||
std::list<UniqueResponse> ::iterator i;
|
||||
for (i = m_ExtResponses.begin(); i!= m_ExtResponses.end(); i++)
|
||||
{
|
||||
ReleaseResponse(&*i);
|
||||
}
|
||||
m_ExtResponses.clear();
|
||||
|
||||
std::list<mfxFrameAllocResponse> ::iterator i2;
|
||||
for (i2 = m_responses.begin(); i2!= m_responses.end(); i2++)
|
||||
{
|
||||
ReleaseResponse(&*i2);
|
||||
}
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
MFXBufferAllocator::MFXBufferAllocator()
|
||||
{
|
||||
pthis = this;
|
||||
Alloc = Alloc_;
|
||||
Lock = Lock_;
|
||||
Free = Free_;
|
||||
Unlock = Unlock_;
|
||||
}
|
||||
|
||||
MFXBufferAllocator::~MFXBufferAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
mfxStatus MFXBufferAllocator::Alloc_(mfxHDL pthis, mfxU32 nbytes, mfxU16 type, mfxMemId *mid)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
||||
|
||||
return self.AllocBuffer(nbytes, type, mid);
|
||||
}
|
||||
|
||||
mfxStatus MFXBufferAllocator::Lock_(mfxHDL pthis, mfxMemId mid, mfxU8 **ptr)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
||||
|
||||
return self.LockBuffer(mid, ptr);
|
||||
}
|
||||
|
||||
mfxStatus MFXBufferAllocator::Unlock_(mfxHDL pthis, mfxMemId mid)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
||||
|
||||
return self.UnlockBuffer(mid);
|
||||
}
|
||||
|
||||
mfxStatus MFXBufferAllocator::Free_(mfxHDL pthis, mfxMemId mid)
|
||||
{
|
||||
if (0 == pthis)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
||||
|
||||
return self.FreeBuffer(mid);
|
||||
}
|
||||
|
450
QSVHelper/IntelSupport/src/d3d11_allocator.cpp
Normal file
450
QSVHelper/IntelSupport/src/d3d11_allocator.cpp
Normal file
@ -0,0 +1,450 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011 - 2013 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#include "d3d11_allocator.h"
|
||||
|
||||
#if MFX_D3D11_SUPPORT
|
||||
|
||||
#include <objbase.h>
|
||||
#include <initguid.h>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
//#include "thread_defs.h"
|
||||
|
||||
#define D3DFMT_NV12 (DXGI_FORMAT)MAKEFOURCC('N','V','1','2')
|
||||
#define D3DFMT_YV12 (DXGI_FORMAT)MAKEFOURCC('Y','V','1','2')
|
||||
|
||||
//for generating sequence of mfx handles
|
||||
template <typename T>
|
||||
struct sequence {
|
||||
T x;
|
||||
sequence(T seed) : x(seed) { }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct sequence<mfxHDL> {
|
||||
mfxHDL x;
|
||||
sequence(mfxHDL seed) : x(seed) { }
|
||||
|
||||
mfxHDL operator ()()
|
||||
{
|
||||
mfxHDL y = x;
|
||||
x = (mfxHDL)(1 + (size_t)(x));
|
||||
return y;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
D3D11FrameAllocator::D3D11FrameAllocator()
|
||||
{
|
||||
m_pDeviceContext = NULL;
|
||||
}
|
||||
|
||||
D3D11FrameAllocator::~D3D11FrameAllocator()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
D3D11FrameAllocator::TextureSubResource D3D11FrameAllocator::GetResourceFromMid(mfxMemId mid)
|
||||
{
|
||||
size_t index = (size_t)MFXReadWriteMid(mid).raw() - 1;
|
||||
|
||||
if(m_memIdMap.size() <= index)
|
||||
return TextureSubResource();
|
||||
|
||||
//reverse iterator dereferencing
|
||||
TextureResource * p = &(*m_memIdMap[index]);
|
||||
if (!p->bAlloc)
|
||||
return TextureSubResource();
|
||||
|
||||
return TextureSubResource(p, mid);
|
||||
}
|
||||
|
||||
mfxStatus D3D11FrameAllocator::Init(mfxAllocatorParams *pParams)
|
||||
{
|
||||
D3D11AllocatorParams *pd3d11Params = 0;
|
||||
pd3d11Params = dynamic_cast<D3D11AllocatorParams *>(pParams);
|
||||
|
||||
if (NULL == pd3d11Params ||
|
||||
NULL == pd3d11Params->pDevice)
|
||||
{
|
||||
return MFX_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
m_initParams = *pd3d11Params;
|
||||
MSDK_SAFE_RELEASE(m_pDeviceContext);
|
||||
pd3d11Params->pDevice->GetImmediateContext(&m_pDeviceContext);
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus D3D11FrameAllocator::Close()
|
||||
{
|
||||
mfxStatus sts = BaseFrameAllocator::Close();
|
||||
for(referenceType i = m_resourcesByRequest.begin(); i != m_resourcesByRequest.end(); i++)
|
||||
{
|
||||
i->Release();
|
||||
}
|
||||
m_resourcesByRequest.clear();
|
||||
m_memIdMap.clear();
|
||||
MSDK_SAFE_RELEASE(m_pDeviceContext);
|
||||
return sts;
|
||||
}
|
||||
|
||||
mfxStatus D3D11FrameAllocator::LockFrame(mfxMemId mid, mfxFrameData *ptr)
|
||||
{
|
||||
HRESULT hRes = S_OK;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc = {0};
|
||||
D3D11_MAPPED_SUBRESOURCE lockedRect = {0};
|
||||
|
||||
|
||||
//check that texture exists
|
||||
TextureSubResource sr = GetResourceFromMid(mid);
|
||||
if (!sr.GetTexture())
|
||||
return MFX_ERR_LOCK_MEMORY;
|
||||
|
||||
D3D11_MAP mapType = D3D11_MAP_READ;
|
||||
UINT mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT;
|
||||
{
|
||||
if (NULL == sr.GetStaging())
|
||||
{
|
||||
hRes = m_pDeviceContext->Map(sr.GetTexture(), sr.GetSubResource(), D3D11_MAP_READ, D3D11_MAP_FLAG_DO_NOT_WAIT, &lockedRect);
|
||||
desc.Format = DXGI_FORMAT_P8;
|
||||
}
|
||||
else
|
||||
{
|
||||
sr.GetTexture()->GetDesc(&desc);
|
||||
|
||||
if (DXGI_FORMAT_NV12 != desc.Format &&
|
||||
DXGI_FORMAT_420_OPAQUE != desc.Format &&
|
||||
DXGI_FORMAT_YUY2 != desc.Format &&
|
||||
DXGI_FORMAT_P8 != desc.Format &&
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM != desc.Format)
|
||||
{
|
||||
return MFX_ERR_LOCK_MEMORY;
|
||||
}
|
||||
|
||||
//coping data only in case user wants to read from stored surface
|
||||
{
|
||||
|
||||
if (MFXReadWriteMid(mid, MFXReadWriteMid::reuse).isRead())
|
||||
{
|
||||
m_pDeviceContext->CopySubresourceRegion(sr.GetStaging(), 0, 0, 0, 0, sr.GetTexture(), sr.GetSubResource(), NULL);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
hRes = m_pDeviceContext->Map(sr.GetStaging(), 0, mapType, mapFlags, &lockedRect);
|
||||
if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes)
|
||||
{
|
||||
msdk_printf(MSDK_STRING("ERROR: m_pDeviceContext->Map = 0x%08lx\n"), hRes);
|
||||
}
|
||||
}
|
||||
while (DXGI_ERROR_WAS_STILL_DRAWING == hRes);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hRes))
|
||||
return MFX_ERR_LOCK_MEMORY;
|
||||
|
||||
switch (desc.Format)
|
||||
{
|
||||
case DXGI_FORMAT_NV12:
|
||||
ptr->Pitch = (mfxU16)lockedRect.RowPitch;
|
||||
ptr->Y = (mfxU8 *)lockedRect.pData;
|
||||
ptr->U = (mfxU8 *)lockedRect.pData + desc.Height * lockedRect.RowPitch;
|
||||
ptr->V = ptr->U + 1;
|
||||
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_420_OPAQUE: // can be unsupported by standard ms guid
|
||||
ptr->Pitch = (mfxU16)lockedRect.RowPitch;
|
||||
ptr->Y = (mfxU8 *)lockedRect.pData;
|
||||
ptr->V = ptr->Y + desc.Height * lockedRect.RowPitch;
|
||||
ptr->U = ptr->V + (desc.Height * lockedRect.RowPitch) / 4;
|
||||
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_YUY2:
|
||||
ptr->Pitch = (mfxU16)lockedRect.RowPitch;
|
||||
ptr->Y = (mfxU8 *)lockedRect.pData;
|
||||
ptr->U = ptr->Y + 1;
|
||||
ptr->V = ptr->Y + 3;
|
||||
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_P8 :
|
||||
ptr->Pitch = (mfxU16)lockedRect.RowPitch;
|
||||
ptr->Y = (mfxU8 *)lockedRect.pData;
|
||||
ptr->U = 0;
|
||||
ptr->V = 0;
|
||||
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM :
|
||||
ptr->Pitch = (mfxU16)lockedRect.RowPitch;
|
||||
ptr->B = (mfxU8 *)lockedRect.pData;
|
||||
ptr->G = ptr->B + 1;
|
||||
ptr->R = ptr->B + 2;
|
||||
ptr->A = ptr->B + 3;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return MFX_ERR_LOCK_MEMORY;
|
||||
}
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus D3D11FrameAllocator::UnlockFrame(mfxMemId mid, mfxFrameData *ptr)
|
||||
{
|
||||
//check that texture exists
|
||||
TextureSubResource sr = GetResourceFromMid(mid);
|
||||
if (!sr.GetTexture())
|
||||
return MFX_ERR_LOCK_MEMORY;
|
||||
|
||||
if (NULL == sr.GetStaging())
|
||||
{
|
||||
m_pDeviceContext->Unmap(sr.GetTexture(), sr.GetSubResource());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pDeviceContext->Unmap(sr.GetStaging(), 0);
|
||||
//only if user wrote something to texture
|
||||
if (MFXReadWriteMid(mid, MFXReadWriteMid::reuse).isWrite())
|
||||
{
|
||||
m_pDeviceContext->CopySubresourceRegion(sr.GetTexture(), sr.GetSubResource(), 0, 0, 0, sr.GetStaging(), 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
ptr->Pitch=0;
|
||||
ptr->U=ptr->V=ptr->Y=0;
|
||||
ptr->A=ptr->R=ptr->G=ptr->B=0;
|
||||
}
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
mfxStatus D3D11FrameAllocator::GetFrameHDL(mfxMemId mid, mfxHDL *handle)
|
||||
{
|
||||
if (NULL == handle)
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
|
||||
TextureSubResource sr = GetResourceFromMid(mid);
|
||||
|
||||
if (!sr.GetTexture())
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
|
||||
mfxHDLPair *pPair = (mfxHDLPair*)handle;
|
||||
|
||||
pPair->first = sr.GetTexture();
|
||||
pPair->second = (mfxHDL)(UINT_PTR)sr.GetSubResource();
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus D3D11FrameAllocator::CheckRequestType(mfxFrameAllocRequest *request)
|
||||
{
|
||||
mfxStatus sts = BaseFrameAllocator::CheckRequestType(request);
|
||||
if (MFX_ERR_NONE != sts)
|
||||
return sts;
|
||||
|
||||
if ((request->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) != 0)
|
||||
return MFX_ERR_NONE;
|
||||
else
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mfxStatus D3D11FrameAllocator::ReleaseResponse(mfxFrameAllocResponse *response)
|
||||
{
|
||||
if (NULL == response)
|
||||
return MFX_ERR_NULL_PTR;
|
||||
|
||||
if (response->mids && 0 != response->NumFrameActual)
|
||||
{
|
||||
//check whether texture exsist
|
||||
TextureSubResource sr = GetResourceFromMid(response->mids[0]);
|
||||
|
||||
if (!sr.GetTexture())
|
||||
return MFX_ERR_NULL_PTR;
|
||||
|
||||
sr.Release();
|
||||
|
||||
//if texture is last it is possible to remove also all handles from map to reduce fragmentation
|
||||
//search for allocated chunk
|
||||
if (m_resourcesByRequest.end() == std::find_if(m_resourcesByRequest.begin(), m_resourcesByRequest.end(), TextureResource::isAllocated))
|
||||
{
|
||||
m_resourcesByRequest.clear();
|
||||
m_memIdMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
mfxStatus D3D11FrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
|
||||
{
|
||||
HRESULT hRes;
|
||||
|
||||
DXGI_FORMAT colorFormat = ConverColortFormat(request->Info.FourCC);
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN == colorFormat)
|
||||
{
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
TextureResource newTexture;
|
||||
|
||||
if (request->Info.FourCC == MFX_FOURCC_P8)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = { 0 };
|
||||
|
||||
desc.ByteWidth = request->Info.Width * request->Info.Height;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.BindFlags = 0;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.MiscFlags = 0;
|
||||
desc.StructureByteStride = 0;
|
||||
|
||||
ID3D11Buffer * buffer = 0;
|
||||
hRes = m_initParams.pDevice->CreateBuffer(&desc, 0, &buffer);
|
||||
if (FAILED(hRes))
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
|
||||
newTexture.textures.push_back(reinterpret_cast<ID3D11Texture2D *>(buffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc = {0};
|
||||
|
||||
desc.Width = request->Info.Width;
|
||||
desc.Height = request->Info.Height;
|
||||
|
||||
desc.MipLevels = 1;
|
||||
//number of subresources is 1 in case of not single texture
|
||||
desc.ArraySize = m_initParams.bUseSingleTexture ? request->NumFrameSuggested : 1;
|
||||
desc.Format = ConverColortFormat(request->Info.FourCC);
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.MiscFlags = m_initParams.uncompressedResourceMiscFlags;
|
||||
|
||||
desc.BindFlags = D3D11_BIND_DECODER;
|
||||
|
||||
if ( (MFX_MEMTYPE_FROM_VPPIN & request->Type) && (DXGI_FORMAT_YUY2 == desc.Format) ||
|
||||
(DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) )
|
||||
{
|
||||
desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
if (desc.ArraySize > 2)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
|
||||
if ( (MFX_MEMTYPE_FROM_VPPOUT & request->Type) ||
|
||||
(MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & request->Type))
|
||||
{
|
||||
desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
if (desc.ArraySize > 2)
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
|
||||
if( DXGI_FORMAT_P8 == desc.Format )
|
||||
{
|
||||
desc.BindFlags = 0;
|
||||
}
|
||||
|
||||
ID3D11Texture2D* pTexture2D;
|
||||
|
||||
for(size_t i = 0; i < request->NumFrameSuggested / desc.ArraySize; i++)
|
||||
{
|
||||
hRes = m_initParams.pDevice->CreateTexture2D(&desc, NULL, &pTexture2D);
|
||||
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
msdk_printf(MSDK_STRING("CreateTexture2D(%d) failed, hr = 0x%08lx\n"), i, hRes);
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
newTexture.textures.push_back(pTexture2D);
|
||||
}
|
||||
|
||||
desc.ArraySize = 1;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.BindFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
for(size_t i = 0; i < request->NumFrameSuggested; i++)
|
||||
{
|
||||
hRes = m_initParams.pDevice->CreateTexture2D(&desc, NULL, &pTexture2D);
|
||||
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
printf("Create staging texture(%d) failed hr = 0x%X\n", i, hRes);
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
newTexture.stagingTexture.push_back(pTexture2D);
|
||||
}
|
||||
}
|
||||
|
||||
// mapping to self created handles array, starting from zero or from last assigned handle + 1
|
||||
sequence<mfxHDL> seq_initializer(m_resourcesByRequest.empty() ? 0 : m_resourcesByRequest.back().outerMids.back());
|
||||
|
||||
//incrementing starting index
|
||||
//1. 0(NULL) is invalid memid
|
||||
//2. back is last index not new one
|
||||
seq_initializer();
|
||||
|
||||
std::generate_n(std::back_inserter(newTexture.outerMids), request->NumFrameSuggested, seq_initializer);
|
||||
|
||||
//saving texture resources
|
||||
m_resourcesByRequest.push_back(newTexture);
|
||||
|
||||
//providing pointer to mids externally
|
||||
response->mids = &m_resourcesByRequest.back().outerMids.front();
|
||||
response->NumFrameActual = request->NumFrameSuggested;
|
||||
|
||||
//iterator prior end()
|
||||
std::list <TextureResource>::iterator it_last = m_resourcesByRequest.end();
|
||||
//fill map
|
||||
std::fill_n(std::back_inserter(m_memIdMap), request->NumFrameSuggested, --it_last);
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
DXGI_FORMAT D3D11FrameAllocator::ConverColortFormat(mfxU32 fourcc)
|
||||
{
|
||||
switch (fourcc)
|
||||
{
|
||||
case MFX_FOURCC_NV12:
|
||||
return DXGI_FORMAT_NV12;
|
||||
|
||||
case MFX_FOURCC_YUY2:
|
||||
return DXGI_FORMAT_YUY2;
|
||||
|
||||
case MFX_FOURCC_RGB4:
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
case MFX_FOURCC_P8:
|
||||
case MFX_FOURCC_P8_TEXTURE:
|
||||
return DXGI_FORMAT_P8;
|
||||
|
||||
default:
|
||||
return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if MFX_D3D11_SUPPORT
|
334
QSVHelper/IntelSupport/src/d3d11_device.cpp
Normal file
334
QSVHelper/IntelSupport/src/d3d11_device.cpp
Normal file
@ -0,0 +1,334 @@
|
||||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011 - 2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
|
||||
#include "d3d11_device.h"
|
||||
|
||||
#if MFX_D3D11_SUPPORT
|
||||
|
||||
#include "sample_defs.h"
|
||||
|
||||
CD3D11Device::CD3D11Device()
|
||||
{
|
||||
}
|
||||
|
||||
CD3D11Device::~CD3D11Device()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::FillSCD(mfxHDL hWindow, DXGI_SWAP_CHAIN_DESC& scd)
|
||||
{
|
||||
scd.Windowed = TRUE;
|
||||
scd.OutputWindow = (HWND)hWindow;
|
||||
scd.SampleDesc.Count = 1;
|
||||
scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
scd.BufferCount = 1;
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::Init(
|
||||
mfxHDL hWindow,
|
||||
mfxU16 nViews,
|
||||
mfxU32 nAdapterNum)
|
||||
{
|
||||
mfxStatus sts = MFX_ERR_NONE;
|
||||
HRESULT hres = S_OK;
|
||||
m_nViews = nViews;
|
||||
if (2 < nViews)
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
m_bDefaultStereoEnabled = FALSE;
|
||||
|
||||
static D3D_FEATURE_LEVEL FeatureLevels[] = {
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
};
|
||||
D3D_FEATURE_LEVEL pFeatureLevelsOut;
|
||||
|
||||
hres = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&m_pDXGIFactory) );
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
if (m_nViews == 2 && hWindow)
|
||||
{
|
||||
hres = m_pDXGIFactory->QueryInterface(__uuidof(IDXGIDisplayControl), (void **)&m_pDisplayControl);
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
m_bDefaultStereoEnabled = m_pDisplayControl->IsStereoEnabled();
|
||||
if (!m_bDefaultStereoEnabled)
|
||||
m_pDisplayControl->SetStereoEnabled(TRUE);
|
||||
}
|
||||
|
||||
hres = m_pDXGIFactory->EnumAdapters(nAdapterNum,&m_pAdapter);
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
hres = D3D11CreateDevice(m_pAdapter ,
|
||||
D3D_DRIVER_TYPE_UNKNOWN,
|
||||
NULL,
|
||||
0,
|
||||
FeatureLevels,
|
||||
MSDK_ARRAY_LEN(FeatureLevels),
|
||||
D3D11_SDK_VERSION,
|
||||
&m_pD3D11Device,
|
||||
&pFeatureLevelsOut,
|
||||
&m_pD3D11Ctx);
|
||||
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
m_pDXGIDev = m_pD3D11Device;
|
||||
m_pDX11VideoDevice = m_pD3D11Device;
|
||||
m_pVideoContext = m_pD3D11Ctx;
|
||||
|
||||
MSDK_CHECK_POINTER(m_pDXGIDev.p, MFX_ERR_NULL_PTR);
|
||||
MSDK_CHECK_POINTER(m_pDX11VideoDevice.p, MFX_ERR_NULL_PTR);
|
||||
MSDK_CHECK_POINTER(m_pVideoContext.p, MFX_ERR_NULL_PTR);
|
||||
|
||||
// turn on multithreading for the Context
|
||||
CComQIPtr<ID3D10Multithread> p_mt(m_pVideoContext);
|
||||
|
||||
if (p_mt)
|
||||
p_mt->SetMultithreadProtected(true);
|
||||
else
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
// create swap chain only for rendering use case (hWindow != 0)
|
||||
DXGI_SWAP_CHAIN_DESC scd;
|
||||
if (hWindow)
|
||||
{
|
||||
ZeroMemory(&scd, sizeof(scd));
|
||||
sts = FillSCD(hWindow, scd);
|
||||
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
|
||||
|
||||
MSDK_CHECK_POINTER (m_pDXGIFactory.p, MFX_ERR_NULL_PTR);
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
|
||||
swapChainDesc.Width = 0; // Use automatic sizing.
|
||||
swapChainDesc.Height = 0;
|
||||
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
|
||||
swapChainDesc.Stereo = m_nViews == 2 ? TRUE : FALSE;
|
||||
swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.BufferCount = 2; // Use double buffering to minimize latency.
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
hres = m_pDXGIFactory->CreateSwapChainForHwnd(m_pD3D11Device,
|
||||
(HWND)hWindow,
|
||||
&swapChainDesc,
|
||||
NULL,
|
||||
NULL,
|
||||
reinterpret_cast<IDXGISwapChain1**>(&m_pSwapChain) );
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::CreateVideoProcessor(mfxFrameSurface1 * pSrf)
|
||||
{
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
if (m_VideoProcessorEnum.p || NULL == pSrf)
|
||||
return MFX_ERR_NONE;
|
||||
|
||||
//create video processor
|
||||
D3D11_VIDEO_PROCESSOR_CONTENT_DESC ContentDesc;
|
||||
MSDK_ZERO_MEMORY( ContentDesc );
|
||||
|
||||
ContentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
|
||||
ContentDesc.InputFrameRate.Numerator = 30000;
|
||||
ContentDesc.InputFrameRate.Denominator = 1000;
|
||||
ContentDesc.InputWidth = pSrf->Info.CropW;
|
||||
ContentDesc.InputHeight = pSrf->Info.CropH;
|
||||
ContentDesc.OutputWidth = pSrf->Info.CropW;
|
||||
ContentDesc.OutputHeight = pSrf->Info.CropH;
|
||||
ContentDesc.OutputFrameRate.Numerator = 30000;
|
||||
ContentDesc.OutputFrameRate.Denominator = 1000;
|
||||
|
||||
ContentDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL;
|
||||
|
||||
hres = m_pDX11VideoDevice->CreateVideoProcessorEnumerator( &ContentDesc, &m_VideoProcessorEnum );
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
hres = m_pDX11VideoDevice->CreateVideoProcessor( m_VideoProcessorEnum, 0, &m_pVideoProcessor );
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::Reset()
|
||||
{
|
||||
// Changing video mode back to the original state
|
||||
if (2 == m_nViews && !m_bDefaultStereoEnabled)
|
||||
m_pDisplayControl->SetStereoEnabled(FALSE);
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::GetHandle(mfxHandleType type, mfxHDL *pHdl)
|
||||
{
|
||||
if (MFX_HANDLE_D3D11_DEVICE == type)
|
||||
{
|
||||
*pHdl = m_pD3D11Device.p;
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::SetHandle(mfxHandleType /*type*/, mfxHDL /*hdl*/)
|
||||
{
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mfxStatus CD3D11Device::RenderFrame(mfxFrameSurface1 * pSrf, mfxFrameAllocator * pAlloc)
|
||||
{
|
||||
HRESULT hres = S_OK;
|
||||
mfxStatus sts;
|
||||
|
||||
sts = CreateVideoProcessor(pSrf);
|
||||
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
|
||||
|
||||
hres = m_pSwapChain->GetBuffer(0, __uuidof( ID3D11Texture2D ), (void**)&m_pDXGIBackBuffer.p);
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC OutputViewDesc;
|
||||
if (2 == m_nViews)
|
||||
{
|
||||
m_pVideoContext->VideoProcessorSetStreamStereoFormat(m_pVideoProcessor, 0, TRUE,D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_SEPARATE,
|
||||
TRUE, TRUE, D3D11_VIDEO_PROCESSOR_STEREO_FLIP_NONE, NULL);
|
||||
m_pVideoContext->VideoProcessorSetOutputStereoMode(m_pVideoProcessor,TRUE);
|
||||
|
||||
OutputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2DARRAY;
|
||||
OutputViewDesc.Texture2DArray.ArraySize = 2;
|
||||
OutputViewDesc.Texture2DArray.MipSlice = 0;
|
||||
OutputViewDesc.Texture2DArray.FirstArraySlice = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
|
||||
OutputViewDesc.Texture2D.MipSlice = 0;
|
||||
}
|
||||
|
||||
if (1 == m_nViews || 0 == pSrf->Info.FrameId.ViewId)
|
||||
{
|
||||
hres = m_pDX11VideoDevice->CreateVideoProcessorOutputView(
|
||||
m_pDXGIBackBuffer,
|
||||
m_VideoProcessorEnum,
|
||||
&OutputViewDesc,
|
||||
&m_pOutputView.p );
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
}
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC InputViewDesc;
|
||||
InputViewDesc.FourCC = 0;
|
||||
InputViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
|
||||
InputViewDesc.Texture2D.MipSlice = 0;
|
||||
InputViewDesc.Texture2D.ArraySlice = 0;
|
||||
|
||||
mfxHDLPair pair = {NULL};
|
||||
sts = pAlloc->GetHDL(pAlloc->pthis, pSrf->Data.MemId, (mfxHDL*)&pair);
|
||||
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
|
||||
|
||||
ID3D11Texture2D *pRTTexture2D = reinterpret_cast<ID3D11Texture2D*>(pair.first);
|
||||
D3D11_TEXTURE2D_DESC RTTexture2DDesc;
|
||||
|
||||
if(!m_pTempTexture && m_nViews == 2)
|
||||
{
|
||||
pRTTexture2D->GetDesc(&RTTexture2DDesc);
|
||||
hres = m_pD3D11Device->CreateTexture2D(&RTTexture2DDesc,NULL,&m_pTempTexture.p);
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
}
|
||||
|
||||
// Creating input views for left and righ eyes
|
||||
if (1 == m_nViews)
|
||||
{
|
||||
hres = m_pDX11VideoDevice->CreateVideoProcessorInputView(
|
||||
pRTTexture2D,
|
||||
m_VideoProcessorEnum,
|
||||
&InputViewDesc,
|
||||
&m_pInputViewLeft.p );
|
||||
|
||||
}
|
||||
else if (2 == m_nViews && 0 == pSrf->Info.FrameId.ViewId)
|
||||
{
|
||||
m_pD3D11Ctx->CopyResource(m_pTempTexture,pRTTexture2D);
|
||||
hres = m_pDX11VideoDevice->CreateVideoProcessorInputView(
|
||||
m_pTempTexture,
|
||||
m_VideoProcessorEnum,
|
||||
&InputViewDesc,
|
||||
&m_pInputViewLeft.p );
|
||||
}
|
||||
else
|
||||
{
|
||||
hres = m_pDX11VideoDevice->CreateVideoProcessorInputView(
|
||||
pRTTexture2D,
|
||||
m_VideoProcessorEnum,
|
||||
&InputViewDesc,
|
||||
&m_pInputViewRight.p );
|
||||
|
||||
}
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
|
||||
// NV12 surface to RGB backbuffer
|
||||
RECT rect = {0};
|
||||
rect.right = pSrf->Info.CropW;
|
||||
rect.bottom = pSrf->Info.CropH;
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_STREAM StreamData;
|
||||
|
||||
if (1 == m_nViews || pSrf->Info.FrameId.ViewId == 1)
|
||||
{
|
||||
StreamData.Enable = TRUE;
|
||||
StreamData.OutputIndex = 0;
|
||||
StreamData.InputFrameOrField = 0;
|
||||
StreamData.PastFrames = 0;
|
||||
StreamData.FutureFrames = 0;
|
||||
StreamData.ppPastSurfaces = NULL;
|
||||
StreamData.ppFutureSurfaces = NULL;
|
||||
StreamData.pInputSurface = m_pInputViewLeft;
|
||||
StreamData.ppPastSurfacesRight = NULL;
|
||||
StreamData.ppFutureSurfacesRight = NULL;
|
||||
StreamData.pInputSurfaceRight = m_nViews == 2 ? m_pInputViewRight : NULL;
|
||||
|
||||
m_pVideoContext->VideoProcessorSetStreamSourceRect(m_pVideoProcessor, 0, true, &rect);
|
||||
m_pVideoContext->VideoProcessorSetStreamFrameFormat( m_pVideoProcessor, 0, D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE);
|
||||
hres = m_pVideoContext->VideoProcessorBlt( m_pVideoProcessor, m_pOutputView, 0, 1, &StreamData );
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
}
|
||||
|
||||
if (1 == m_nViews || 1 == pSrf->Info.FrameId.ViewId)
|
||||
{
|
||||
DXGI_PRESENT_PARAMETERS parameters = {0};
|
||||
hres = m_pSwapChain->Present1(0, 0, ¶meters);
|
||||
if (FAILED(hres))
|
||||
return MFX_ERR_DEVICE_FAILED;
|
||||
}
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
void CD3D11Device::Close()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
#endif // #if MFX_D3D11_SUPPORT
|
160
QSVHelper/QSVHelper.cpp
Normal file
160
QSVHelper/QSVHelper.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include <mfxvideo++.h>
|
||||
|
||||
#include "Encoder.h"
|
||||
#include "IPCInfo.h"
|
||||
#include "QSVStuff.h"
|
||||
#include "SupportStuff.h"
|
||||
#include "WindowsStuff.h"
|
||||
|
||||
namespace {
|
||||
const struct impl_parameters
|
||||
{
|
||||
mfxIMPL type,
|
||||
intf;
|
||||
mfxVersion version;
|
||||
} valid_impl[] = {
|
||||
{ MFX_IMPL_HARDWARE_ANY, MFX_IMPL_VIA_D3D11, {6, 1} },
|
||||
{ MFX_IMPL_HARDWARE, MFX_IMPL_VIA_D3D11, {6, 1} },
|
||||
{ MFX_IMPL_HARDWARE_ANY, MFX_IMPL_VIA_D3D9, {6, 1} }, //Ivy Bridge+ with non-functional D3D11 support?
|
||||
{ MFX_IMPL_HARDWARE, MFX_IMPL_VIA_D3D9, {6, 1} },
|
||||
{ MFX_IMPL_HARDWARE_ANY, MFX_IMPL_VIA_D3D9, {4, 1} }, //Sandy Bridge
|
||||
{ MFX_IMPL_HARDWARE, MFX_IMPL_VIA_D3D9, {4, 1} },
|
||||
};
|
||||
|
||||
std::wofstream log_file;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nShowCmd)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
wstringstream cmdss(GetCommandLineW());
|
||||
wstring wstr;
|
||||
cmdss >> wstr;
|
||||
wstringstream wss;
|
||||
wss << wstr << GetCurrentProcessId();
|
||||
wstring event_prefix;
|
||||
wss >> event_prefix;
|
||||
|
||||
|
||||
std::string log_path = GetCommandLineA();
|
||||
log_path.erase(log_path.begin(), find(log_path.begin(), log_path.end(), ' ')+1);
|
||||
log_path += "/pluginData/QSVHelper.log";
|
||||
|
||||
log_file.open(log_path, ios::out | ios::trunc);
|
||||
if(!log_file.is_open())
|
||||
return 200;
|
||||
|
||||
ipc_init_request init_req(event_prefix + INIT_REQUEST);
|
||||
|
||||
if(!init_req.is_signalled(INFINITE))
|
||||
return 1;
|
||||
|
||||
if(init_req->mode == init_req->MODE_QUERY)
|
||||
{
|
||||
MFXVideoSession session;
|
||||
for(auto impl = begin(valid_impl); impl != std::end(valid_impl); impl++)
|
||||
{
|
||||
auto ver = impl->version;
|
||||
auto result = session.Init(impl->intf | impl->type, &ver);
|
||||
if(result == MFX_ERR_NONE)
|
||||
return 0;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
safe_handle obs_handle(OpenProcess(SYNCHRONIZE, false, init_req->obs_process_id));
|
||||
if(!obs_handle)
|
||||
return 2;
|
||||
|
||||
ipc_init_response init_res(event_prefix + INIT_RESPONSE);
|
||||
zero(*&init_res);
|
||||
|
||||
Encoder encoder(init_req, event_prefix, log_file);
|
||||
|
||||
init_res->using_custom_impl = false;
|
||||
if(init_req->use_custom_impl)
|
||||
{
|
||||
impl_parameters p;
|
||||
p.intf = init_req->custom_intf;
|
||||
p.type = init_req->custom_impl;
|
||||
p.version = init_req->custom_version;
|
||||
auto result = encoder.InitializeMFX(p, true);
|
||||
if(result >= MFX_ERR_NONE)
|
||||
{
|
||||
init_res->using_custom_impl = true;
|
||||
init_res->actual_impl = p.intf | p.type;
|
||||
init_res->version = p.version;
|
||||
}
|
||||
}
|
||||
|
||||
if(!init_res->using_custom_impl || !encoder)
|
||||
{
|
||||
decltype(begin(valid_impl)) best = nullptr;
|
||||
for(auto impl = begin(valid_impl); impl != std::end(valid_impl); impl++)
|
||||
{
|
||||
auto result = encoder.InitializeMFX(*impl);
|
||||
if(result == MFX_WRN_PARTIAL_ACCELERATION && !best)
|
||||
best = impl;
|
||||
if(result == MFX_ERR_NONE)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!encoder)
|
||||
{
|
||||
if(!best)
|
||||
return 5;
|
||||
auto ver = best->version;
|
||||
encoder.InitializeMFX(*best);
|
||||
log_file << "No valid implementation detected, using best implementation instead\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(!encoder)
|
||||
return 6;
|
||||
|
||||
init_res->version = encoder.version;
|
||||
init_res->requested_impl = encoder.requested;
|
||||
init_res->actual_impl = encoder.actual;
|
||||
|
||||
encoder.InitializeBuffers(init_res);
|
||||
|
||||
encoder.InitializeEncoder();
|
||||
|
||||
init_res.signal();
|
||||
|
||||
log_file << "Using " << encoder.encode_tasks.size() << " encode tasks and " << encoder.surfaces.size() << " internal frame buffers\n";
|
||||
|
||||
encoder.RequestSPSPPS();
|
||||
|
||||
ipc_stop stop(event_prefix + STOP_REQUEST);
|
||||
|
||||
return encoder.EncodeLoop(stop, obs_handle);
|
||||
}
|
126
QSVHelper/QSVHelper.vcxproj
Normal file
126
QSVHelper/QSVHelper.vcxproj
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{F1C7033A-F050-46E3-9080-E129B9CD1010}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>QSVHelper</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(WindowsSDK80Path)Include\um;$(WindowsSDK80Path)Include\shared;$(DXSDK_DIR)Include;IntelSupport\include;IntelSupport\include\vm;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(WindowsSDK80Path)Lib\win8\um\x86;$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(WindowsSDK80Path)Include\um;$(WindowsSDK80Path)Include\shared;$(DXSDK_DIR)Include;IntelSupport\include;IntelSupport\include\vm;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../libmfx/include/msdk/include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>../libmfx/$(Platform)/$(Configuration)/libmfx.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<ProgramDatabaseFile>..\rundir\pdb32\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<StripPrivateSymbols>..\rundir\pdb32\stripped\$(TargetName).pdb</StripPrivateSymbols>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(OutDir)$(TargetName).exe" ..\rundir\</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../libmfx/include/msdk/include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>../libmfx/$(Platform)/$(Configuration)/libmfx.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ProgramDatabaseFile>..\rundir\pdb32\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<StripPrivateSymbols>..\rundir\pdb32\stripped\$(TargetName).pdb</StripPrivateSymbols>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(OutDir)$(TargetName).exe" ..\rundir\</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="IntelSupport\src\base_allocator.cpp" />
|
||||
<ClCompile Include="IntelSupport\src\d3d11_allocator.cpp" />
|
||||
<ClCompile Include="IntelSupport\src\d3d11_device.cpp" />
|
||||
<ClCompile Include="QSVStuff.cpp" />
|
||||
<ClCompile Include="QSVHelper.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Encoder.h" />
|
||||
<ClInclude Include="IntelSupport\include\base_allocator.h" />
|
||||
<ClInclude Include="IntelSupport\include\current_date.h" />
|
||||
<ClInclude Include="IntelSupport\include\d3d11_allocator.h" />
|
||||
<ClInclude Include="IntelSupport\include\d3d11_device.h" />
|
||||
<ClInclude Include="IntelSupport\include\hw_device.h" />
|
||||
<ClInclude Include="IntelSupport\include\sample_defs.h" />
|
||||
<ClInclude Include="IntelSupport\include\vm\strings_defs.h" />
|
||||
<ClInclude Include="IntelSupport\include\vm\time_defs.h" />
|
||||
<ClInclude Include="IPCStructs.h" />
|
||||
<ClInclude Include="IPCInfo.h" />
|
||||
<ClInclude Include="SupportStuff.h" />
|
||||
<ClInclude Include="Utilities.h" />
|
||||
<ClInclude Include="WindowsStuff.h" />
|
||||
<ClInclude Include="QSVStuff.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
87
QSVHelper/QSVHelper.vcxproj.filters
Normal file
87
QSVHelper/QSVHelper.vcxproj.filters
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="IntelSupport">
|
||||
<UniqueIdentifier>{ca840a93-0bea-4a93-83c9-0476c240c3a8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="IntelSupport\Headers">
|
||||
<UniqueIdentifier>{fd95e3a4-45a3-40e5-a120-1e3a476e1fc0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="QSVHelper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QSVStuff.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntelSupport\src\base_allocator.cpp">
|
||||
<Filter>IntelSupport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntelSupport\src\d3d11_allocator.cpp">
|
||||
<Filter>IntelSupport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntelSupport\src\d3d11_device.cpp">
|
||||
<Filter>IntelSupport</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="WindowsStuff.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="QSVStuff.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SupportStuff.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IPCStructs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Encoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IPCInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\base_allocator.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\current_date.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\d3d11_allocator.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\d3d11_device.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\hw_device.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\sample_defs.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\vm\strings_defs.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntelSupport\include\vm\time_defs.h">
|
||||
<Filter>IntelSupport\Headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
172
QSVHelper/QSVStuff.cpp
Normal file
172
QSVHelper/QSVStuff.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#include "QSVStuff.h"
|
||||
|
||||
#include "Utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
void ConvertFrameRate(mfxF64 dFrameRate, mfxU32& pnFrameRateExtN, mfxU32& pnFrameRateExtD)
|
||||
{
|
||||
mfxU32 fr;
|
||||
|
||||
fr = (mfxU32)(dFrameRate + .5);
|
||||
|
||||
if(fabs(fr - dFrameRate) < 0.0001)
|
||||
{
|
||||
pnFrameRateExtN = fr;
|
||||
pnFrameRateExtD = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fr = (mfxU32)(dFrameRate * 1.001 + .5);
|
||||
|
||||
if(fabs(fr * 1000 - dFrameRate * 1001) < 10)
|
||||
{
|
||||
pnFrameRateExtN = fr * 1000;
|
||||
pnFrameRateExtD = 1001;
|
||||
return;
|
||||
}
|
||||
|
||||
pnFrameRateExtN = (mfxU32)(dFrameRate * 10000 + .5);
|
||||
pnFrameRateExtD = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
Parameters::Parameters()
|
||||
{
|
||||
zero(params);
|
||||
}
|
||||
|
||||
void Parameters::Init(int fps, int keyframe_interval_frames, int bframes, int width, int height, int max_bitrate, int buffer_size, bool use_cbr)
|
||||
{
|
||||
params.mfx.CodecId = MFX_CODEC_AVC;
|
||||
params.mfx.TargetUsage = MFX_TARGETUSAGE_BEST_QUALITY;
|
||||
params.mfx.TargetKbps = max_bitrate;
|
||||
params.mfx.MaxKbps = max_bitrate;
|
||||
params.mfx.BufferSizeInKB = buffer_size/8;
|
||||
params.mfx.GopOptFlag = MFX_GOP_CLOSED;
|
||||
params.mfx.GopPicSize = keyframe_interval_frames;
|
||||
params.mfx.GopRefDist = bframes+1;
|
||||
params.mfx.NumSlice = 1;
|
||||
|
||||
params.mfx.RateControlMethod = use_cbr ? MFX_RATECONTROL_CBR : MFX_RATECONTROL_VBR;
|
||||
params.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
|
||||
|
||||
auto& fi = params.mfx.FrameInfo;
|
||||
ConvertFrameRate(fps, fi.FrameRateExtN, fi.FrameRateExtD);
|
||||
|
||||
fi.FourCC = MFX_FOURCC_NV12;
|
||||
fi.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
||||
fi.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
|
||||
|
||||
fi.Width = align16(width);
|
||||
fi.Height = align16(height);
|
||||
|
||||
fi.CropX = 0;
|
||||
fi.CropY = 0;
|
||||
fi.CropW = width;
|
||||
fi.CropH = height;
|
||||
}
|
||||
|
||||
void Parameters::SetCodingOptionSPSPPS(mfxU8 *sps_buff, mfxU16 sps_size, mfxU8 *pps_buff, mfxU16 pps_size)
|
||||
{
|
||||
if(!FindExt(cospspps))
|
||||
{
|
||||
zero(cospspps);
|
||||
cospspps.Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS;
|
||||
cospspps.Header.BufferSz = sizeof(cospspps);
|
||||
|
||||
AddExt(cospspps);
|
||||
}
|
||||
cospspps.SPSBuffer = sps_buff;
|
||||
cospspps.SPSBufSize = sps_size;
|
||||
cospspps.PPSBuffer = pps_buff;
|
||||
cospspps.PPSBufSize = pps_size;
|
||||
}
|
||||
|
||||
void Parameters::SetVideoSignalInfo(int full_range, int primaries, int transfer, int matrix)
|
||||
{
|
||||
if(!FindExt(vsi))
|
||||
{
|
||||
zero(vsi);
|
||||
vsi.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
|
||||
vsi.Header.BufferSz = sizeof(vsi);
|
||||
|
||||
AddExt(vsi);
|
||||
}
|
||||
|
||||
vsi.ColourDescriptionPresent = 1;
|
||||
vsi.VideoFullRange = full_range;
|
||||
vsi.ColourPrimaries = primaries;
|
||||
vsi.TransferCharacteristics = transfer;
|
||||
vsi.MatrixCoefficients = matrix;
|
||||
vsi.VideoFormat = 5; //unspecified
|
||||
}
|
||||
|
||||
void Parameters::UpdateExt()
|
||||
{
|
||||
params.ExtParam = &ext_buffers.front();
|
||||
params.NumExtParam = ext_buffers.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EncodeCtrl::AddSEIData(sei_type type, vector<mfxU8> data)
|
||||
{
|
||||
unsigned payload_size = data.size();
|
||||
vector<mfxU8> buffer;
|
||||
|
||||
mfxU16 type_ = type;
|
||||
while(type_ > 255)
|
||||
{
|
||||
buffer.emplace_back(0xff);
|
||||
type_ -= 255;
|
||||
}
|
||||
buffer.emplace_back((mfxU8)type_);
|
||||
|
||||
while(payload_size > 255)
|
||||
{
|
||||
buffer.emplace_back(0xff);
|
||||
payload_size -= 255;
|
||||
}
|
||||
buffer.emplace_back(payload_size);
|
||||
|
||||
buffer.insert(end(buffer), begin(data), end(data));
|
||||
|
||||
data_buffers.emplace_back(buffer);
|
||||
payloads.emplace_back(mfxPayload());
|
||||
|
||||
mfxPayload &sei_payload = payloads.back();
|
||||
|
||||
zero(sei_payload);
|
||||
|
||||
sei_payload.Type = type;
|
||||
sei_payload.BufSize = buffer.size();
|
||||
sei_payload.NumBit = sei_payload.BufSize*8;
|
||||
sei_payload.Data = &data_buffers.back().front();
|
||||
|
||||
payload_list.clear();
|
||||
for(auto &payload = begin(payloads); payload != end(payloads); payload++)
|
||||
payload_list.emplace_back(&*payload);
|
||||
|
||||
ctrl.Payload = &payload_list.front();
|
||||
ctrl.NumPayload = payload_list.size();
|
||||
}
|
78
QSVHelper/QSVStuff.h
Normal file
78
QSVHelper/QSVStuff.h
Normal file
@ -0,0 +1,78 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mfxvideo++.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "Utilities.h"
|
||||
|
||||
template <class T>
|
||||
inline T align16(T t)
|
||||
{
|
||||
return (((t + 15) >> 4) << 4);
|
||||
}
|
||||
|
||||
struct Parameters
|
||||
{
|
||||
private:
|
||||
mfxVideoParam params;
|
||||
std::vector<mfxExtBuffer*> ext_buffers;
|
||||
|
||||
public:
|
||||
mfxExtCodingOptionSPSPPS cospspps;
|
||||
mfxExtVideoSignalInfo vsi;
|
||||
|
||||
|
||||
operator mfxVideoParam() { return params; }
|
||||
operator mfxVideoParam*() { return ¶ms; }
|
||||
mfxVideoParam* operator&() { return ¶ms; }
|
||||
mfxVideoParam* operator->() { return ¶ms; }
|
||||
|
||||
void Init(int fps, int keyframe_interval_frames, int bframes, int width, int height, int max_bitrate, int buffer_size, bool use_cbr);
|
||||
void SetCodingOptionSPSPPS(mfxU8 *sps_buff, mfxU16 sps_size, mfxU8 *pps_buff, mfxU16 pps_size);
|
||||
void SetVideoSignalInfo(int full_range, int primaries, int transfer, int matrix);
|
||||
|
||||
Parameters();
|
||||
protected:
|
||||
void UpdateExt();
|
||||
template <class T>
|
||||
bool FindExt(T& t) { return std::find(std::begin(ext_buffers), std::end(ext_buffers), reinterpret_cast<mfxExtBuffer*>(&t)) != std::end(ext_buffers); }
|
||||
template <class T>
|
||||
void AddExt(T& t) { ext_buffers.emplace_back(reinterpret_cast<mfxExtBuffer*>(&t)); UpdateExt(); }
|
||||
};
|
||||
|
||||
|
||||
struct EncodeCtrl
|
||||
{
|
||||
enum sei_type {SEI_USER_DATA_UNREGISTERED=0x5};
|
||||
mfxEncodeCtrl ctrl;
|
||||
std::vector<mfxPayload*> payload_list;
|
||||
std::vector<mfxPayload> payloads;
|
||||
std::vector<std::vector<mfxU8>> data_buffers;
|
||||
|
||||
operator mfxEncodeCtrl() { return ctrl; }
|
||||
mfxEncodeCtrl *operator&() { return &ctrl; }
|
||||
|
||||
void AddSEIData(sei_type type, std::vector<mfxU8> payload);
|
||||
|
||||
EncodeCtrl() { zero(ctrl); }
|
||||
};
|
76
QSVHelper/SupportStuff.h
Normal file
76
QSVHelper/SupportStuff.h
Normal file
@ -0,0 +1,76 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mfxvideo++.h>
|
||||
|
||||
#include "Utilities.h"
|
||||
#include "QSVStuff.h"
|
||||
|
||||
struct encode_task
|
||||
{
|
||||
mfxFrameSurface1 *surf;
|
||||
mfxBitstream bs;
|
||||
mfxSyncPoint sp;
|
||||
mfxEncodeCtrl *ctrl;
|
||||
size_t frame_index;
|
||||
|
||||
void Init(mfxU8 *bs_start, mfxU32 bs_size)
|
||||
{
|
||||
sp = nullptr;
|
||||
ctrl = nullptr;
|
||||
surf = nullptr;
|
||||
|
||||
zero(bs);
|
||||
bs.Data = bs_start;
|
||||
bs.MaxLength = bs_size;
|
||||
}
|
||||
};
|
||||
|
||||
void InitFrame(mfxFrameData &frame, mfxU8 *Y, mfxU8 *UV, mfxU8 *V, mfxU16 pitch)
|
||||
{
|
||||
zero(frame);
|
||||
frame.Y = Y;
|
||||
frame.UV = UV;
|
||||
frame.V = V;
|
||||
frame.Pitch = pitch;
|
||||
}
|
||||
|
||||
std::vector<mfxU8> InitSEIUserData(bool use_cbr, const mfxVideoParam& params, const mfxVersion& ver)
|
||||
{
|
||||
using namespace std;
|
||||
vector<mfxU8> data;
|
||||
|
||||
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
|
||||
data.insert(end(data), begin(UUID), end(UUID));
|
||||
|
||||
ostringstream str;
|
||||
str << "QSV hardware encoder options:"
|
||||
<< " rate control: " << (use_cbr ? "cbr" : "vbr")
|
||||
<< "; target bitrate: " << params.mfx.TargetKbps
|
||||
<< "; max bitrate: " << params.mfx.MaxKbps
|
||||
<< "; buffersize: " << params.mfx.BufferSizeInKB*8
|
||||
<< "; API level: " << ver.Major << "." << ver.Minor;
|
||||
string str_(str.str());
|
||||
|
||||
data.insert(end(data), begin(str_), end(str_));
|
||||
|
||||
return data;
|
||||
}
|
25
QSVHelper/Utilities.h
Normal file
25
QSVHelper/Utilities.h
Normal file
@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
template <class T>
|
||||
void zero(T& t, size_t size=sizeof(T))
|
||||
{
|
||||
memset(&t, 0, size);
|
||||
}
|
221
QSVHelper/WindowsStuff.h
Normal file
221
QSVHelper/WindowsStuff.h
Normal file
@ -0,0 +1,221 @@
|
||||
/********************************************************************************
|
||||
Copyright (C) 2013 Ruwen Hahn <palana@stunned.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct safe_handle
|
||||
{
|
||||
HANDLE h;
|
||||
operator bool() const { return h != nullptr; }
|
||||
operator HANDLE() { return h; }
|
||||
|
||||
void reset(HANDLE h_=nullptr) { if(h) CloseHandle(h); h = h_; }
|
||||
|
||||
bool operator!() const { return !h; }
|
||||
|
||||
safe_handle &operator=(safe_handle &&other) { reset(other.h); other.h = nullptr; return *this; }
|
||||
|
||||
safe_handle(HANDLE h=nullptr) : h(h) {}
|
||||
~safe_handle() { if(h) CloseHandle(h); }
|
||||
safe_handle(safe_handle &&other) : h(other.h) { other.h = nullptr; };
|
||||
private:
|
||||
safe_handle(const safe_handle&);
|
||||
};
|
||||
|
||||
struct NamedSharedMemory
|
||||
{
|
||||
std::wstring name;
|
||||
uint64_t size;
|
||||
void *memory;
|
||||
safe_handle file;
|
||||
|
||||
bool operator!() const { return !memory || !file; }
|
||||
void *operator&() { return memory; }
|
||||
|
||||
template <class T>
|
||||
T &as() { return *reinterpret_cast<T*>(memory); }
|
||||
|
||||
NamedSharedMemory &operator=(NamedSharedMemory &&other)
|
||||
{ FreeMemory(); name = other.name; size = other.size; memory = other.memory; other.memory = nullptr; file = std::move(other.file); return *this; }
|
||||
|
||||
//NamedSharedMemory(const NamedSharedMemory& other) : name(other.name), size(other.size), memory(nullptr) { InitMemory(); }
|
||||
NamedSharedMemory(NamedSharedMemory&& other)
|
||||
: name(std::move(other.name)), size(std::move(other.size)), memory(std::move(other.memory)), file(std::move(other.file)) { other.memory = nullptr; }
|
||||
~NamedSharedMemory() { FreeMemory(); }
|
||||
NamedSharedMemory(std::wstring name, uint64_t size=1) : name(name), size(size), memory(nullptr) { InitMemory(); }
|
||||
NamedSharedMemory() : memory(nullptr) {}
|
||||
|
||||
private:
|
||||
void FreeMemory() { if(memory) UnmapViewOfFile(memory); memory = nullptr; }
|
||||
void InitMemory()
|
||||
{
|
||||
if(!size)
|
||||
size = 1;
|
||||
file.reset(CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, size>>32, size & 0xffffffff, name.c_str()));
|
||||
if(file)
|
||||
memory = MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
struct IPCSignal
|
||||
{
|
||||
safe_handle signal_;
|
||||
|
||||
bool is_signalled(DWORD timeout=0) { return WaitForSingleObject(signal_, timeout) == WAIT_OBJECT_0; }
|
||||
void signal() { SetEvent(signal_); }
|
||||
|
||||
bool operator!() const { return !signal_; }
|
||||
|
||||
IPCSignal &operator=(IPCSignal &&other) { signal_ = std::move(other.signal_); return *this; }
|
||||
|
||||
IPCSignal(std::wstring name) { signal_.reset(CreateEvent(nullptr, false, false, name.c_str())); }
|
||||
IPCSignal() {}
|
||||
};
|
||||
|
||||
struct IPCWaiter
|
||||
{
|
||||
std::vector<HANDLE> list;
|
||||
void push_back(const HANDLE &h) { list.push_back(h); }
|
||||
bool wait(DWORD timeout=0) { if(!list.size()) return false; auto res = wait_for_multiple_objects(timeout); return WAIT_OBJECT_0 <= res && res < (WAIT_OBJECT_0+list.size()); }
|
||||
bool wait_for(DWORD object, DWORD timeout=0) { if(!list.size()) return false; return wait_for_multiple_objects(timeout) == (WAIT_OBJECT_0 + object); }
|
||||
bool wait_for_two(DWORD first, DWORD second, DWORD timeout=0) { if(!list.size()) return false; auto res = wait_for_multiple_objects(timeout); return res == (WAIT_OBJECT_0 + first) || res == (WAIT_OBJECT_0 + second); }
|
||||
bool wait_timeout(DWORD timeout=0) { if(!list.size()) return false; return wait_for_multiple_objects(timeout) == WAIT_TIMEOUT; }
|
||||
|
||||
private:
|
||||
DWORD wait_for_multiple_objects(DWORD timeout) { return WaitForMultipleObjects(static_cast<DWORD>(list.size()), &list.front(), false, timeout); }
|
||||
};
|
||||
|
||||
struct IPCMutex
|
||||
{
|
||||
safe_handle mutex_;
|
||||
|
||||
void lock() { if(mutex_) WaitForSingleObject(mutex_, INFINITE); }
|
||||
void unlock() { if(mutex_) ReleaseMutex(mutex_); }
|
||||
|
||||
bool operator!() { return !mutex_; }
|
||||
|
||||
IPCMutex &operator=(IPCMutex &&other) { mutex_ = std::move(other.mutex_); return *this; }
|
||||
|
||||
IPCMutex(std::wstring name) { mutex_.reset(CreateMutex(nullptr, false, name.c_str())); }
|
||||
IPCMutex() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct IPCMutexLock
|
||||
{
|
||||
T& t;
|
||||
bool enabled;
|
||||
|
||||
IPCMutexLock(T &t) : t(t), enabled(true) { t.lock(); }
|
||||
~IPCMutexLock() { if(enabled) t.unlock(); }
|
||||
IPCMutexLock(IPCMutexLock &&other) : t(other.t), enabled(other.enabled) { other.enabled = false; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
IPCMutexLock<T> lock_mutex(T &t) { return IPCMutexLock<T>(t); }
|
||||
|
||||
template <class T, class F>
|
||||
void with_locked(T &t, F &f) { IPCMutexLock<T> lock(t); f(); }
|
||||
|
||||
template <class T>
|
||||
struct IPCType
|
||||
{
|
||||
NamedSharedMemory memory;
|
||||
|
||||
bool operator!() const { return !memory; }
|
||||
operator T() { return memory.as<T>(); }
|
||||
T *operator&() { return &memory.as<T>(); }
|
||||
T *operator->() { return &memory.as<T>(); }
|
||||
T &operator*() { return memory.as<T>(); }
|
||||
|
||||
IPCType &operator=(IPCType &&other) { memory = std::move(other.memory); return *this; }
|
||||
|
||||
IPCType(std::wstring name) : memory(name, sizeof(T)) {}
|
||||
IPCType() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct IPCSignalledType : IPCType<T>, IPCSignal
|
||||
{
|
||||
bool operator!() const { return !memory || !signal_; }
|
||||
|
||||
IPCSignalledType &operator=(IPCSignalledType &&other) { memory = std::move(other.memory); signal_ = std::move(other.signal_); return *this; }
|
||||
|
||||
IPCSignalledType(std::wstring name) : IPCType(name), IPCSignal(name+L"Signal") {}
|
||||
IPCSignalledType() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct IPCLockedSignalledType : IPCSignalledType<T>, IPCMutex
|
||||
{
|
||||
bool operator!() const { return !memory || !signal_ || !mutex_; }
|
||||
|
||||
IPCLockedSignalledType &operator=(IPCLockedSignalledType &&other) { memory = std::move(other.memory); signal_ = std::move(other.signal_); mutex_ = std::move(other.mutex_); return *this; }
|
||||
|
||||
IPCLockedSignalledType(std::wstring name) : IPCSignalledType(name), IPCMutex(name+L"Lock") {}
|
||||
IPCLockedSignalledType() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct IPCArray
|
||||
{
|
||||
NamedSharedMemory memory;
|
||||
size_t size;
|
||||
|
||||
bool operator!() const { return !memory; }
|
||||
operator T*() { return static_cast<T*>(&memory); }
|
||||
|
||||
IPCArray &operator=(IPCArray &&other) { memory = std::move(other.memory); size = other.size; return *this; }
|
||||
|
||||
IPCArray(std::wstring name, size_t size) : memory(name, sizeof(T)*size), size(size) {}
|
||||
IPCArray() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct IPCSignalledArray : IPCArray<T>, IPCSignal
|
||||
{
|
||||
bool operator!() const { return !memory || !signal_; }
|
||||
|
||||
IPCSignalledArray &operator=(IPCSignalledArray &&other) { memory = std::move(other.memory); signal_ = std::move(other.signal_); size = other.size; return *this; }
|
||||
|
||||
IPCSignalledArray(std::wstring name, size_t size) : IPCArray(name, size), IPCSignal(name+L"Signal") {}
|
||||
IPCSignalledArray() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct IPCLockedSignalledArray : IPCSignalledArray<T>, IPCMutex
|
||||
{
|
||||
bool operator!() { return !memory || !signal_ || !mutex_; }
|
||||
|
||||
IPCLockedSignalledArray &operator=(IPCLockedSignalledArray &&other)
|
||||
{ memory = std::move(other.memory); signal_ = std::move(other.signal_); mutex_ = std::move(other.mutex_); size = other.size; return *this; }
|
||||
|
||||
IPCLockedSignalledArray(std::wstring name, size_t size) : IPCSignalledArray(name, size), IPCMutex(name+L"Lock") {}
|
||||
IPCLockedSignalledArray() {}
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,7 @@ copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\32
|
||||
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\32bit\plugins\graphicscapture
|
||||
copy ..\injectHelper\x64\release\injectHelper64.exe .\32bit\plugins\graphicscapture
|
||||
copy ..\x264\libs\32bit\libx264-136.dll .\32bit
|
||||
copy ..\QSVHelper\Release\QSVHelper.exe .\32bit
|
||||
copy "%WindowsSDK80Path%Debuggers\x86\dbghelp.dll" .\32bit
|
||||
|
||||
copy ..\x64\release\obs.exe .\64bit\
|
||||
@ -63,6 +64,7 @@ copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\64
|
||||
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\64bit\plugins\graphicscapture
|
||||
copy ..\injectHelper\release\injectHelper.exe .\64bit\plugins\graphicscapture
|
||||
copy ..\x264\libs\64bit\libx264-136.dll .\64bit
|
||||
copy ..\QSVHelper\Release\QSVHelper.exe .\64bit
|
||||
copy "%WindowsSDK80Path%Debuggers\x64\dbghelp.dll" .\64bit
|
||||
|
||||
copy ..\rundir\pdb32\*.pdb .\pdbs\32bit
|
||||
@ -128,6 +130,7 @@ copy ..\obsapi\release\obsapi.dll .\upload\OBS\32bit\
|
||||
copy ..\OBSHelp\OBSHelp.chm .\upload\OBS\32bit\
|
||||
copy ..\rundir\pdb32\stripped\*.pdb .\upload\OBS\32bit\
|
||||
copy ..\x264\libs\32bit\libx264-136.dll .\upload\OBS\32bit
|
||||
copy ..\QSVHelper\Release\QSVHelper.exe .\upload\OBS\32bit
|
||||
copy "%WindowsSDK80Path%Debuggers\x86\dbghelp.dll" .\upload\OBS\32bit
|
||||
|
||||
copy ..\x64\release\obs.exe .\upload\OBS\64bit\
|
||||
@ -135,6 +138,7 @@ copy ..\obsapi\x64\release\obsapi.dll .\upload\OBS\64bit\
|
||||
copy ..\OBSHelp\OBSHelp.chm .\upload\OBS\64bit\
|
||||
copy ..\rundir\pdb64\stripped\*.pdb .\upload\OBS\64bit\
|
||||
copy ..\x264\libs\64bit\libx264-136.dll .\upload\OBS\64bit
|
||||
copy ..\QSVHelper\Release\QSVHelper.exe .\upload\OBS\64bit
|
||||
copy "%WindowsSDK80Path%Debuggers\x64\dbghelp.dll" .\upload\OBS\64bit
|
||||
|
||||
copy ..\rundir\locale\*.txt .\upload\OBS\locale\
|
||||
|
@ -44,6 +44,7 @@ copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\32
|
||||
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\32bit\plugins\graphicscapture
|
||||
copy ..\injectHelper\x64\release\injectHelper64.exe .\32bit\plugins\graphicscapture
|
||||
copy ..\x264\libs\32bit\libx264-136.dll .\32bit
|
||||
copy ..\QSVHelper\Release\QSVHelper.exe .\32bit
|
||||
copy "%WindowsSDK80Path%Debuggers\x86\dbghelp.dll" .\32bit
|
||||
|
||||
copy ..\x64\release\obs.exe .\64bit\
|
||||
@ -69,4 +70,5 @@ copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\64
|
||||
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\64bit\plugins\graphicscapture
|
||||
copy ..\injectHelper\release\injectHelper.exe .\64bit\plugins\graphicscapture
|
||||
copy ..\x264\libs\64bit\libx264-136.dll .\64bit
|
||||
copy ..\QSVHelper\Release\QSVHelper.exe .\64bit
|
||||
copy "%WindowsSDK80Path%Debuggers\x64\dbghelp.dll" .\64bit
|
||||
|
@ -113,6 +113,7 @@ Section "Open Broadcaster Software" Section1
|
||||
SetOutPath "$PROGRAMFILES32\OBS"
|
||||
File "..\Release\OBS.exe"
|
||||
File "..\x264\libs\32bit\libx264-136.dll"
|
||||
File "..\QSVHelper\Release\QSVHelper.exe"
|
||||
File "..\OBSAPI\Release\OBSApi.dll"
|
||||
File "..\rundir\services.xconfig"
|
||||
File "..\OBSHelp\OBSHelp.chm"
|
||||
@ -142,6 +143,7 @@ Section "Open Broadcaster Software" Section1
|
||||
SetOutPath "$PROGRAMFILES64\OBS"
|
||||
File "..\x64\Release\OBS.exe"
|
||||
File "..\x264\libs\64bit\libx264-136.dll"
|
||||
File "..\QSVHelper\Release\QSVHelper.exe"
|
||||
File "..\OBSAPI\x64\Release\OBSApi.dll"
|
||||
File "..\rundir\services.xconfig"
|
||||
File "..\OBSHelp\OBSHelp.chm"
|
||||
@ -219,6 +221,7 @@ Section Uninstall
|
||||
; Clean up Open Broadcaster Software
|
||||
Delete "$PROGRAMFILES32\OBS\OBS.exe"
|
||||
Delete "$PROGRAMFILES32\OBS\libx264-136.dll"
|
||||
Delete "$PROGRAMFILES32\OBS\QSVHelper.exe"
|
||||
Delete "$PROGRAMFILES32\OBS\OBSApi.dll"
|
||||
Delete "$PROGRAMFILES32\OBS\services.xconfig"
|
||||
Delete "$PROGRAMFILES32\OBS\*.chm"
|
||||
@ -238,6 +241,7 @@ Section Uninstall
|
||||
${if} ${RunningX64}
|
||||
Delete "$PROGRAMFILES64\OBS\OBS.exe"
|
||||
Delete "$PROGRAMFILES64\OBS\libx264-136.dll"
|
||||
Delete "$PROGRAMFILES64\OBS\QSVHelper.exe"
|
||||
Delete "$PROGRAMFILES64\OBS\OBSApi.dll"
|
||||
Delete "$PROGRAMFILES64\OBS\services.xconfig"
|
||||
Delete "$PROGRAMFILES64\OBS\*.chm"
|
||||
|
Loading…
x
Reference in New Issue
Block a user