浏览代码

obs-qsv11: Add native obs-studio QSV encoder

Seung-Woo Kim 10 年之前
父节点
当前提交
3e4bcf06bc
共有 56 个文件被更改,包括 13085 次插入0 次删除
  1. 1 0
      plugins/CMakeLists.txt
  2. 86 0
      plugins/obs-qsv11/CMakeLists.txt
  3. 211 0
      plugins/obs-qsv11/QSV_Encoder.cpp
  4. 149 0
      plugins/obs-qsv11/QSV_Encoder.h
  5. 596 0
      plugins/obs-qsv11/QSV_Encoder_Internal.cpp
  6. 112 0
      plugins/obs-qsv11/QSV_Encoder_Internal.h
  7. 19 0
      plugins/obs-qsv11/bits/linux_defs.h
  8. 16 0
      plugins/obs-qsv11/bits/windows_defs.h
  9. 487 0
      plugins/obs-qsv11/common_directx11.cpp
  10. 39 0
      plugins/obs-qsv11/common_directx11.h
  11. 306 0
      plugins/obs-qsv11/common_utils.cpp
  12. 109 0
      plugins/obs-qsv11/common_utils.h
  13. 104 0
      plugins/obs-qsv11/common_utils_windows.cpp
  14. 11 0
      plugins/obs-qsv11/data/locale/en-US.ini
  15. 76 0
      plugins/obs-qsv11/libmfx/include/mfx_critical_section.h
  16. 213 0
      plugins/obs-qsv11/libmfx/include/mfx_dispatcher.h
  17. 85 0
      plugins/obs-qsv11/libmfx/include/mfx_dispatcher_defs.h
  18. 306 0
      plugins/obs-qsv11/libmfx/include/mfx_dispatcher_log.h
  19. 210 0
      plugins/obs-qsv11/libmfx/include/mfx_dxva2_device.h
  20. 142 0
      plugins/obs-qsv11/libmfx/include/mfx_exposed_functions_list.h
  21. 161 0
      plugins/obs-qsv11/libmfx/include/mfx_library_iterator.h
  22. 59 0
      plugins/obs-qsv11/libmfx/include/mfx_load_dll.h
  23. 93 0
      plugins/obs-qsv11/libmfx/include/mfx_load_plugin.h
  24. 132 0
      plugins/obs-qsv11/libmfx/include/mfx_plugin_hive.h
  25. 220 0
      plugins/obs-qsv11/libmfx/include/mfx_vector.h
  26. 116 0
      plugins/obs-qsv11/libmfx/include/mfx_win_reg_key.h
  27. 81 0
      plugins/obs-qsv11/libmfx/include/mfxaudio_exposed_functions_list.h
  28. 172 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxastructures.h
  29. 113 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio++.h
  30. 70 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio.h
  31. 159 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxcommon.h
  32. 153 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxdefs.h
  33. 80 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxenc.h
  34. 107 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxjpeg.h
  35. 109 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxmvc.h
  36. 78 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxpak.h
  37. 719 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin++.h
  38. 206 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin.h
  39. 60 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxsession.h
  40. 1379 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxstructures.h
  41. 197 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo++.h
  42. 112 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo.h
  43. 32 0
      plugins/obs-qsv11/libmfx/include/msdk/include/mfxvstructures.h
  44. 937 0
      plugins/obs-qsv11/libmfx/src/main.cpp
  45. 88 0
      plugins/obs-qsv11/libmfx/src/mfx_critical_section.cpp
  46. 349 0
      plugins/obs-qsv11/libmfx/src/mfx_dispatcher.cpp
  47. 449 0
      plugins/obs-qsv11/libmfx/src/mfx_dispatcher_log.cpp
  48. 558 0
      plugins/obs-qsv11/libmfx/src/mfx_dxva2_device.cpp
  49. 143 0
      plugins/obs-qsv11/libmfx/src/mfx_function_table.cpp
  50. 475 0
      plugins/obs-qsv11/libmfx/src/mfx_library_iterator.cpp
  51. 241 0
      plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp
  52. 458 0
      plugins/obs-qsv11/libmfx/src/mfx_load_plugin.cpp
  53. 500 0
      plugins/obs-qsv11/libmfx/src/mfx_plugin_hive.cpp
  54. 228 0
      plugins/obs-qsv11/libmfx/src/mfx_win_reg_key.cpp
  55. 86 0
      plugins/obs-qsv11/obs-qsv11-plugin-main.c
  56. 687 0
      plugins/obs-qsv11/obs-qsv11.c

+ 1 - 0
plugins/CMakeLists.txt

@@ -9,6 +9,7 @@ if(WIN32)
 	add_subdirectory(win-capture)
 	add_subdirectory(decklink/win)
 	add_subdirectory(win-mf)
+	add_subdirectory(obs-qsv11)
 elseif(APPLE)
 	add_subdirectory(coreaudio-encoder)
 	add_subdirectory(mac-avcapture)

+ 86 - 0
plugins/obs-qsv11/CMakeLists.txt

@@ -0,0 +1,86 @@
+project(obs-qsv11)
+
+include_directories(libmfx/include/msdk/include)
+include_directories(libmfx/include)
+
+set(obs-qsv11_libmfx_SOURCES
+	libmfx/src/main.cpp
+	libmfx/src/mfx_critical_section.cpp
+	libmfx/src/mfx_dispatcher.cpp
+	libmfx/src/mfx_dispatcher_log.cpp
+	libmfx/src/mfx_dxva2_device.cpp
+	libmfx/src/mfx_function_table.cpp
+	libmfx/src/mfx_library_iterator.cpp
+	libmfx/src/mfx_load_dll.cpp
+	libmfx/src/mfx_load_plugin.cpp
+	libmfx/src/mfx_plugin_hive.cpp
+	libmfx/src/mfx_win_reg_key.cpp
+	)
+
+set(obs-qsv11_libmfx_HEADERS
+	libmfx/include/msdk/include/mfxastructures.h
+	libmfx/include/msdk/include/mfxaudio.h
+	libmfx/include/msdk/include/mfxaudio++.h
+	libmfx/include/msdk/include/mfxcommon.h
+	libmfx/include/msdk/include/mfxdefs.h
+	libmfx/include/msdk/include/mfxjpeg.h
+	libmfx/include/msdk/include/mfxmvc.h
+	libmfx/include/msdk/include/mfxplugin.h
+	libmfx/include/msdk/include/mfxplugin++.h
+	libmfx/include/msdk/include/mfxsession.h
+	libmfx/include/msdk/include/mfxstructures.h
+	libmfx/include/msdk/include/mfxvideo.h
+	libmfx/include/msdk/include/mfxvideo++.h
+	libmfx/include/msdk/include/mfxvstructures.h
+	libmfx/include/mfx_critical_section.h
+	libmfx/include/mfx_dispatcher.h
+	libmfx/include/mfx_dispatcher_defs.h
+	libmfx/include/mfx_dispatcher_log.h
+	libmfx/include/mfx_dxva2_device.h
+	libmfx/include/mfx_exposed_functions_list.h
+	libmfx/include/mfx_library_iterator.h
+	libmfx/include/mfx_load_dll.h
+	libmfx/include/mfx_load_plugin.h
+	libmfx/include/mfx_plugin_hive.h
+	libmfx/include/mfx_vector.h
+	libmfx/include/mfx_win_reg_key.h
+	libmfx/include/mfxaudio_exposed_functions_list.h
+	)
+
+set(obs-qsv11_SOURCES
+	common_directx11.cpp
+	common_utils.cpp
+	common_utils_windows.cpp
+	QSV_Encoder.cpp
+	QSV_Encoder_Internal.cpp
+	obs-qsv11.c
+	obs-qsv11-plugin-main.c)
+
+set(obs-qsv11_HEADERS
+	bits/linux_defs.h
+	bits/windows_defs.h
+	common_directx11.h
+	common_utils.h
+	QSV_Encoder.h
+	QSV_Encoder_Internal.h)
+
+add_library(obs-qsv11 MODULE
+	${obs-qsv11_SOURCES}
+	${obs-qsv11_HEADERS}
+	${obs-qsv11_libmfx_SOURCES}
+	${obs-qsv11_libmfx_HEADERS}
+	)
+target_link_libraries(obs-qsv11
+	libobs
+	d3d11
+	dxgi
+	)
+
+target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D)
+
+source_group("obs-qsv11\\Source Files" FILES ${obs-qsv11_SOURCES})
+source_group("obs-qsv11\\Header Files" FILES ${obs-qsv11_HEADERS})
+source_group("libmfx\\Source Files" FILES ${obs-qsv11_libmfx_SOURCES})
+source_group("libmfx\\Header Files" FILES ${obs-qsv11_libmfx_HEADERS})
+
+install_obs_plugin_with_data(obs-qsv11 data)

+ 211 - 0
plugins/obs-qsv11/QSV_Encoder.cpp

@@ -0,0 +1,211 @@
+/*
+
+This file is provided under a dual BSD/GPLv2 license.  When using or
+redistributing this file, you may do so under either license.
+
+GPL LICENSE SUMMARY
+
+Copyright(c) Oct. 2015 Intel Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+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.
+
+Contact Information:
+
+Seung-Woo Kim, [email protected]
+705 5th Ave S #500, Seattle, WA 98104
+
+BSD LICENSE
+
+Copyright(c) <date> Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Intel Corporation nor the names of its
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// QSV_Encoder.cpp : Defines the exported functions for the DLL application.
+//
+
+#include "QSV_Encoder.h"
+#include "QSV_Encoder_Internal.h"
+#include <string>
+
+QSV_Encoder_Internal *g_pEncoder = NULL;
+mfxIMPL              impl = MFX_IMPL_HARDWARE_ANY;
+mfxVersion           ver = {{0, 1}}; // for backward compatibility
+
+void qsv_encoder_version(unsigned short *major, unsigned short *minor)
+{
+	*major = ver.Major;
+	*minor = ver.Minor;
+}
+
+qsv_t *qsv_encoder_open(qsv_param_t *pParams)
+{
+	QSV_Encoder_Internal *pEncoder = new QSV_Encoder_Internal(impl, ver);
+	mfxStatus sts = pEncoder->Open(pParams);
+	if (sts != MFX_ERR_NONE) {
+		delete pEncoder;
+		return NULL;
+	}
+
+	return (qsv_t *) pEncoder;
+}
+
+int qsv_encoder_headers(qsv_t *pContext, uint8_t **pSPS, uint8_t **pPPS,
+		uint16_t *pnSPS, uint16_t *pnPPS)
+{
+	QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext;
+	pEncoder->GetSPSPPS(pSPS, pPPS, pnSPS, pnPPS);
+
+	return 0;
+}
+
+int qsv_encoder_encode(qsv_t * pContext, uint64_t ts, uint8_t *pDataY,
+		uint8_t *pDataUV, uint32_t strideY, uint32_t strideUV,
+		mfxBitstream **pBS)
+{
+	QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext;
+	mfxStatus sts = MFX_ERR_NONE;
+
+	if (pDataY != NULL && pDataUV != NULL)
+		sts = pEncoder->Encode(ts, pDataY, pDataUV, strideY, strideUV,
+				pBS);
+
+	if (sts == MFX_ERR_NONE)
+		return 0;
+	else if (sts == MFX_ERR_MORE_DATA)
+		return 1;
+	else
+		return -1;
+}
+
+int qsv_encoder_close(qsv_t *pContext)
+{
+	QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext;
+	delete pEncoder;
+
+	return 0;
+}
+
+/*
+int qsv_param_default_preset(qsv_param_t *pParams, const char *preset,
+		const char *tune)
+{
+	return 0;
+}
+
+int qsv_param_parse(qsv_param_t *, const char *name, const char *value)
+{
+	return 0;
+}
+
+int qsv_param_apply_profile(qsv_param_t *, const char *profile)
+{
+	return 0;
+}
+*/
+
+int qsv_encoder_reconfig(qsv_t *pContext, qsv_param_t *pParams)
+{
+	QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext;
+	mfxStatus sts = pEncoder->Reset(pParams);
+
+	if (sts == MFX_ERR_NONE)
+		return 0;
+	else
+		return -1;
+}
+
+enum qsv_cpu_platform qsv_get_cpu_platform()
+{
+	using std::string;
+
+	int cpuInfo[4];
+	__cpuid(cpuInfo, 0);
+
+	string vendor;
+	vendor += string((char*)&cpuInfo[1], 4);
+	vendor += string((char*)&cpuInfo[3], 4);
+	vendor += string((char*)&cpuInfo[2], 4);
+
+	if (vendor != "GenuineIntel")
+		return QSV_CPU_PLATFORM_UNKNOWN;
+
+	__cpuid(cpuInfo, 1);
+	BYTE model = ((cpuInfo[0] >> 4) & 0xF) + ((cpuInfo[0] >> 12) & 0xF0);
+	BYTE family = ((cpuInfo[0] >> 8) & 0xF) + ((cpuInfo[0] >> 20) & 0xFF);
+
+	// See Intel 64 and IA-32 Architectures Software Developer's Manual,
+	// Vol 3C Table 35-1
+	if (family != 6)
+		return QSV_CPU_PLATFORM_UNKNOWN;
+
+	switch (model)
+	{
+	case 0x1C:
+	case 0x26:
+	case 0x27:
+	case 0x35:
+	case 0x36:
+		return QSV_CPU_PLATFORM_BNL;
+
+	case 0x2a:
+	case 0x2d:
+		return QSV_CPU_PLATFORM_SNB;
+
+	case 0x3a:
+	case 0x3e:
+		return QSV_CPU_PLATFORM_IVB;
+
+	case 0x37:
+	case 0x4A:
+	case 0x4D:
+	case 0x5A:
+	case 0x5D:
+		return QSV_CPU_PLATFORM_SLM;
+
+	case 0x4C:
+		return QSV_CPU_PLATFORM_CHT;
+
+	case 0x3c:
+	case 0x3f:
+	case 0x45:
+	case 0x46:
+		return QSV_CPU_PLATFORM_HSW;
+	}
+
+	//assume newer revisions are at least as capable as haswell
+	return QSV_CPU_PLATFORM_INTEL;
+}

+ 149 - 0
plugins/obs-qsv11/QSV_Encoder.h

@@ -0,0 +1,149 @@
+/*
+
+This file is provided under a dual BSD/GPLv2 license.  When using or
+redistributing this file, you may do so under either license.
+
+GPL LICENSE SUMMARY
+
+Copyright(c) Oct. 2015 Intel Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+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.
+
+Contact Information:
+
+Seung-Woo Kim, [email protected]
+705 5th Ave S #500, Seattle, WA 98104
+
+BSD LICENSE
+
+Copyright(c) <date> Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Intel Corporation nor the names of its
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+
+#include <Windows.h>
+#include "mfxstructures.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct qsv_rate_control_info {
+	const char *name;
+	bool haswell_or_greater;
+};
+
+static const struct qsv_rate_control_info qsv_ratecontrols[] = {
+	{"CBR", false},
+	{"VBR", false},
+	{"VCM", true},
+	{"CQP", false},
+	{"AVBR", false},
+	{"ICQ", true},
+	{"LA_ICQ", true},
+	{"LA", true},
+	{0, false}
+};
+static const char * const qsv_profile_names[] = {
+	"high",
+	"main",
+	"baseline",
+	0
+};
+static const char * const qsv_usage_names[] = {
+	"quality",
+	"balanced",
+	"speed",
+	0
+};
+
+typedef struct qsv_t qsv_t;
+
+typedef struct
+{
+	mfxU16 nTargetUsage; /* 1 through 7, 1 being best quality and 7
+				being the best speed */
+	mfxU16 nWidth;       /* source picture width */
+	mfxU16 nHeight;      /* source picture height */
+	mfxU16 nAsyncDepth;
+	mfxU16 nFpsNum;
+	mfxU16 nFpsDen;
+	mfxU16 nTargetBitRate;
+	mfxU16 nMaxBitRate;
+	mfxU16 nCodecProfile;
+	mfxU16 nRateControl;
+	mfxU16 nAccuracy;
+	mfxU16 nConvergence;
+	mfxU16 nQPI;
+	mfxU16 nQPP;
+	mfxU16 nQPB;
+	mfxU16 nLADEPTH;
+	mfxU16 nKeyIntSec;
+	mfxU16 nbFrames;
+	mfxU16 nICQQuality;
+} qsv_param_t;
+
+enum qsv_cpu_platform {
+	QSV_CPU_PLATFORM_UNKNOWN,
+	QSV_CPU_PLATFORM_BNL,
+	QSV_CPU_PLATFORM_SNB,
+	QSV_CPU_PLATFORM_IVB,
+	QSV_CPU_PLATFORM_SLM,
+	QSV_CPU_PLATFORM_CHT,
+	QSV_CPU_PLATFORM_HSW,
+	QSV_CPU_PLATFORM_INTEL
+};
+
+int qsv_encoder_close(qsv_t *);
+int qsv_param_parse(qsv_param_t *, const char *name, const char *value);
+int qsv_param_apply_profile(qsv_param_t *, const char *profile);
+int qsv_param_default_preset(qsv_param_t *, const char *preset,
+		const char *tune);
+int qsv_encoder_reconfig(qsv_t *, qsv_param_t *);
+void qsv_encoder_version(unsigned short *major, unsigned short *minor);
+qsv_t *qsv_encoder_open( qsv_param_t * );
+int qsv_encoder_encode(qsv_t *, uint64_t, uint8_t *, uint8_t *, uint32_t,
+		uint32_t, mfxBitstream **pBS);
+int qsv_encoder_headers(qsv_t *, uint8_t **pSPS, uint8_t **pPPS,
+		uint16_t *pnSPS, uint16_t *pnPPS);
+enum qsv_cpu_platform qsv_get_cpu_platform();
+
+#ifdef __cplusplus
+}
+#endif

+ 596 - 0
plugins/obs-qsv11/QSV_Encoder_Internal.cpp

@@ -0,0 +1,596 @@
+/*
+
+This file is provided under a dual BSD/GPLv2 license.  When using or
+redistributing this file, you may do so under either license.
+
+GPL LICENSE SUMMARY
+
+Copyright(c) Oct. 2015 Intel Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+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.
+
+Contact Information:
+
+Seung-Woo Kim, [email protected]
+705 5th Ave S #500, Seattle, WA 98104
+
+BSD LICENSE
+
+Copyright(c) <date> Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Intel Corporation nor the names of its
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "QSV_Encoder_Internal.h"
+#include "QSV_Encoder.h"
+#include "mfxastructures.h"
+#include "mfxvideo++.h"
+#include <VersionHelpers.h>
+#include <obs-module.h>
+
+#define do_log(level, format, ...) \
+	blog(level, "[qsv encoder: '%s'] " format, \
+			"msdk_impl", ##__VA_ARGS__)
+
+#define warn(format, ...)  do_log(LOG_WARNING, format, ##__VA_ARGS__)
+#define info(format, ...)  do_log(LOG_INFO,    format, ##__VA_ARGS__)
+#define debug(format, ...) do_log(LOG_DEBUG,   format, ##__VA_ARGS__)
+
+QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL& impl, mfxVersion& version) :
+	m_pmfxENC(NULL),
+	m_nSPSBufferSize(100),
+	m_nPPSBufferSize(100),
+	m_nTaskPool(0),
+	m_pTaskPool(NULL),
+	m_nTaskIdx(0),
+	m_nFirstSyncTask(0)
+{
+	mfxIMPL tempImpl;
+	mfxStatus sts;
+
+	m_bIsWindows8OrGreater = IsWindows8OrGreater();
+	m_bUseD3D11 = false;
+
+	if (m_bIsWindows8OrGreater) {
+		tempImpl = impl | MFX_IMPL_VIA_D3D11;
+		sts = m_session.Init(tempImpl, &version);
+		if (sts == MFX_ERR_NONE) {
+			m_session.QueryVersion(&version);
+			m_session.Close();
+
+			// Use D3D11 surface
+			// m_bUseD3D11 = ((version.Major > 1) ||
+			//	(version.Major == 1 && version.Minor >= 8));
+			m_bUseD3D11 = true;
+			if (m_bUseD3D11)
+				blog(LOG_INFO, "\timpl:           D3D11\n"
+				               "\tsurf:           D3D11");
+			else
+				blog(LOG_INFO, "\timpl:           D3D11\n"
+				               "\tsurf:           SysMem");
+
+			m_impl = tempImpl;
+			m_ver = version;
+			return;
+		}
+	}
+
+	// Either windows 7 or D3D11 failed at this point.
+	tempImpl = impl | MFX_IMPL_VIA_D3D9;
+	sts = m_session.Init(tempImpl, &version);
+	if (sts == MFX_ERR_NONE) {
+		m_session.QueryVersion(&version);
+		m_session.Close();
+
+		blog(LOG_INFO, "\timpl:           D3D09\n"
+		               "\tsurf:           SysMem");
+
+		m_impl = tempImpl;
+		m_ver = version;
+	}
+
+}
+
+QSV_Encoder_Internal::~QSV_Encoder_Internal()
+{
+	ClearData();
+}
+
+mfxStatus QSV_Encoder_Internal::Open(qsv_param_t * pParams)
+{
+	mfxStatus sts = MFX_ERR_NONE;
+
+	if (m_bUseD3D11)
+		// Use D3D11 surface
+		sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator);
+	else
+		// Use system memory
+		sts = Initialize(m_impl, m_ver, &m_session, NULL);
+
+	if (sts == MFX_ERR_NONE)
+		m_pmfxENC = new MFXVideoENCODE(m_session);
+
+	InitParams(pParams);
+
+	sts = m_pmfxENC->Query(&m_mfxEncParams, &m_mfxEncParams);
+	MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	sts = AllocateSurfaces();
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	sts = m_pmfxENC->Init(&m_mfxEncParams);
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	sts = GetVideoParam();
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	sts = InitBitstream();
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	return sts;
+}
+
+
+bool QSV_Encoder_Internal::InitParams(qsv_param_t * pParams)
+{
+	memset(&m_mfxEncParams, 0, sizeof(m_mfxEncParams));
+
+	m_mfxEncParams.mfx.CodecId = MFX_CODEC_AVC;
+	m_mfxEncParams.mfx.GopOptFlag = MFX_GOP_STRICT;
+	m_mfxEncParams.mfx.NumSlice = 1;
+	m_mfxEncParams.mfx.TargetUsage = pParams->nTargetUsage;
+	m_mfxEncParams.mfx.CodecProfile = pParams->nCodecProfile;
+	m_mfxEncParams.mfx.FrameInfo.FrameRateExtN = pParams->nFpsNum;
+	m_mfxEncParams.mfx.FrameInfo.FrameRateExtD = pParams->nFpsDen;
+	m_mfxEncParams.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
+	m_mfxEncParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
+	m_mfxEncParams.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
+	m_mfxEncParams.mfx.FrameInfo.CropX = 0;
+	m_mfxEncParams.mfx.FrameInfo.CropY = 0;
+	m_mfxEncParams.mfx.FrameInfo.CropW = pParams->nWidth;
+	m_mfxEncParams.mfx.FrameInfo.CropH = pParams->nHeight;
+
+	m_mfxEncParams.mfx.RateControlMethod = pParams->nRateControl;
+
+	switch (pParams->nRateControl) {
+	case MFX_RATECONTROL_CBR:
+		m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate;
+		break;
+	case MFX_RATECONTROL_VBR:
+	case MFX_RATECONTROL_VCM:
+		m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate;
+		m_mfxEncParams.mfx.MaxKbps = pParams->nMaxBitRate;
+		break;
+	case MFX_RATECONTROL_CQP:
+		m_mfxEncParams.mfx.QPI = pParams->nQPI;
+		m_mfxEncParams.mfx.QPB = pParams->nQPB;
+		m_mfxEncParams.mfx.QPP = pParams->nQPP;
+		break;
+	case MFX_RATECONTROL_AVBR:
+		m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate;
+		m_mfxEncParams.mfx.Accuracy = pParams->nAccuracy;
+		m_mfxEncParams.mfx.Convergence = pParams->nConvergence;
+		break;
+	case MFX_RATECONTROL_ICQ:
+		m_mfxEncParams.mfx.ICQQuality = pParams->nICQQuality;
+		break;
+	case MFX_RATECONTROL_LA:
+		m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate;
+		break;
+	case MFX_RATECONTROL_LA_ICQ:
+		m_mfxEncParams.mfx.ICQQuality = pParams->nICQQuality;
+		break;
+	default:
+		break;
+	}
+
+	m_mfxEncParams.AsyncDepth = pParams->nAsyncDepth;
+	m_mfxEncParams.mfx.GopPicSize = (mfxU16)(pParams->nKeyIntSec *
+			pParams->nFpsNum / (float)pParams->nFpsDen);
+
+	static mfxExtBuffer* extendedBuffers[2];
+	int iBuffers = 0;
+	if (pParams->nAsyncDepth == 1) {
+		m_mfxEncParams.mfx.NumRefFrame = 1;
+		// low latency, I and P frames only
+		m_mfxEncParams.mfx.GopRefDist = 1;
+		memset(&m_co, 0, sizeof(mfxExtCodingOption));
+		m_co.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
+		m_co.Header.BufferSz = sizeof(mfxExtCodingOption);
+		m_co.MaxDecFrameBuffering = 1;
+		extendedBuffers[iBuffers++] = (mfxExtBuffer*)&m_co;
+	}
+	else
+		m_mfxEncParams.mfx.GopRefDist = pParams->nbFrames + 1;
+
+	if (pParams->nRateControl == MFX_RATECONTROL_LA_ICQ ||
+	    pParams->nRateControl == MFX_RATECONTROL_LA) {
+
+		memset(&m_co2, 0, sizeof(mfxExtCodingOption2));
+		m_co2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
+		m_co2.Header.BufferSz = sizeof(m_co2);
+		m_co2.LookAheadDepth = pParams->nLADEPTH;
+		extendedBuffers[iBuffers++] = (mfxExtBuffer*)& m_co2;
+	}
+
+	if (iBuffers > 0) {
+		m_mfxEncParams.ExtParam = extendedBuffers;
+		m_mfxEncParams.NumExtParam = (mfxU16)iBuffers;
+	}
+
+	// Width must be a multiple of 16
+	// Height must be a multiple of 16 in case of frame picture and a
+	// multiple of 32 in case of field picture
+	m_mfxEncParams.mfx.FrameInfo.Width = MSDK_ALIGN16(pParams->nWidth);
+	m_mfxEncParams.mfx.FrameInfo.Height = MSDK_ALIGN16(pParams->nHeight);
+
+	if (m_bUseD3D11)
+		m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
+	else
+		m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
+
+	return true;
+}
+
+mfxStatus QSV_Encoder_Internal::AllocateSurfaces()
+{
+	// Query number of required surfaces for encoder
+	mfxFrameAllocRequest EncRequest;
+	memset(&EncRequest, 0, sizeof(EncRequest));
+	mfxStatus sts = m_pmfxENC->QueryIOSurf(&m_mfxEncParams, &EncRequest);
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	EncRequest.Type |= WILL_WRITE;
+
+	// SNB hack. On some SNB, it seems to require more surfaces
+	EncRequest.NumFrameSuggested += m_mfxEncParams.AsyncDepth;
+
+	// Allocate required surfaces
+	if (m_bUseD3D11) {
+		sts = m_mfxAllocator.Alloc(m_mfxAllocator.pthis, &EncRequest,
+				&m_mfxResponse);
+		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+		m_nSurfNum = m_mfxResponse.NumFrameActual;
+
+		m_pmfxSurfaces = new mfxFrameSurface1 *[m_nSurfNum];
+		MSDK_CHECK_POINTER(m_pmfxSurfaces, MFX_ERR_MEMORY_ALLOC);
+
+		for (int i = 0; i < m_nSurfNum; i++) {
+			m_pmfxSurfaces[i] = new mfxFrameSurface1;
+			memset(m_pmfxSurfaces[i], 0, sizeof(mfxFrameSurface1));
+			memcpy(&(m_pmfxSurfaces[i]->Info),
+					&(m_mfxEncParams.mfx.FrameInfo),
+					sizeof(mfxFrameInfo));
+			m_pmfxSurfaces[i]->Data.MemId = m_mfxResponse.mids[i];
+		}
+	}
+	else {
+		mfxU16 width = (mfxU16)MSDK_ALIGN32(EncRequest.Info.Width);
+		mfxU16 height = (mfxU16)MSDK_ALIGN32(EncRequest.Info.Height);
+		mfxU8  bitsPerPixel = 12;
+		mfxU32 surfaceSize = width * height * bitsPerPixel / 8;
+		m_nSurfNum = EncRequest.NumFrameSuggested;
+
+		m_pmfxSurfaces = new mfxFrameSurface1 *[m_nSurfNum];
+		for (int i = 0; i < m_nSurfNum; i++) {
+			m_pmfxSurfaces[i] = new mfxFrameSurface1;
+			memset(m_pmfxSurfaces[i], 0, sizeof(mfxFrameSurface1));
+			memcpy(&(m_pmfxSurfaces[i]->Info),
+					&(m_mfxEncParams.mfx.FrameInfo),
+					sizeof(mfxFrameInfo));
+
+			mfxU8* pSurface = (mfxU8*) new mfxU8[surfaceSize];
+			m_pmfxSurfaces[i]->Data.Y = pSurface;
+			m_pmfxSurfaces[i]->Data.U = pSurface + width * height;
+			m_pmfxSurfaces[i]->Data.V = pSurface + width * height + 1;
+			m_pmfxSurfaces[i]->Data.Pitch = width;
+		}
+	}
+
+	blog(LOG_INFO, "\tm_nSurfNum:     %d", m_nSurfNum);
+
+	return sts;
+}
+
+mfxStatus QSV_Encoder_Internal::GetVideoParam()
+{
+	memset(&m_parameter, 0, sizeof(m_parameter));
+	mfxExtCodingOptionSPSPPS opt;
+	memset(&m_parameter, 0, sizeof(m_parameter));
+	opt.Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS;
+	opt.Header.BufferSz = sizeof(mfxExtCodingOptionSPSPPS);
+
+	static mfxExtBuffer* extendedBuffers[1];
+	extendedBuffers[0] = (mfxExtBuffer*)& opt;
+	m_parameter.ExtParam = extendedBuffers;
+	m_parameter.NumExtParam = 1;
+
+	opt.SPSBuffer = m_SPSBuffer;
+	opt.PPSBuffer = m_PPSBuffer;
+	opt.SPSBufSize = 100; //  m_nSPSBufferSize;
+	opt.PPSBufSize = 100; //  m_nPPSBufferSize;
+
+	mfxStatus sts = m_pmfxENC->GetVideoParam(&m_parameter);
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	m_nSPSBufferSize = opt.SPSBufSize;
+	m_nPPSBufferSize = opt.PPSBufSize;
+
+	return sts;
+}
+
+void QSV_Encoder_Internal::GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf,
+		mfxU16 *pnSPSBuf, mfxU16 *pnPPSBuf)
+{
+	*pSPSBuf = m_SPSBuffer;
+	*pPPSBuf = m_PPSBuffer;
+	*pnSPSBuf = m_nSPSBufferSize;
+	*pnPPSBuf = m_nPPSBufferSize;
+}
+
+mfxStatus QSV_Encoder_Internal::InitBitstream()
+{
+	m_nTaskPool = m_parameter.AsyncDepth;
+	m_nFirstSyncTask = 0;
+
+	m_pTaskPool = new Task[m_nTaskPool];
+	memset(m_pTaskPool, 0, sizeof(Task) * m_nTaskPool);
+
+	for (int i = 0; i < m_nTaskPool; i++) {
+		m_pTaskPool[i].mfxBS.MaxLength =
+			m_parameter.mfx.BufferSizeInKB * 1000;
+		m_pTaskPool[i].mfxBS.Data =
+			new mfxU8[m_pTaskPool[i].mfxBS.MaxLength];
+		m_pTaskPool[i].mfxBS.DataOffset = 0;
+		m_pTaskPool[i].mfxBS.DataLength = 0;
+
+		MSDK_CHECK_POINTER(m_pTaskPool[i].mfxBS.Data,
+				MFX_ERR_MEMORY_ALLOC);
+	}
+
+	memset(&m_outBitstream, 0, sizeof(mfxBitstream));
+	m_outBitstream.MaxLength = m_parameter.mfx.BufferSizeInKB * 1000;
+	m_outBitstream.Data = new mfxU8[m_outBitstream.MaxLength];
+	m_outBitstream.DataOffset = 0;
+	m_outBitstream.DataLength = 0;
+
+	blog(LOG_INFO, "\tm_nTaskPool:    %d", m_nTaskPool);
+
+	return MFX_ERR_NONE;
+}
+
+mfxStatus QSV_Encoder_Internal::LoadNV12(mfxFrameSurface1 *pSurface,
+		uint8_t *pDataY, uint8_t *pDataUV, uint32_t strideY,
+		uint32_t strideUV)
+{
+	mfxU16 w, h, i, pitch;
+	mfxU8* ptr;
+	mfxFrameInfo* pInfo = &pSurface->Info;
+	mfxFrameData* pData = &pSurface->Data;
+
+	if (pInfo->CropH > 0 && pInfo->CropW > 0)
+	{
+		w = pInfo->CropW;
+		h = pInfo->CropH;
+	}
+	else
+	{
+		w = pInfo->Width;
+		h = pInfo->Height;
+	}
+
+	pitch = pData->Pitch;
+	ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
+
+	// load Y plane
+	for (i = 0; i < h; i++)
+		memcpy(ptr + i * pitch, pDataY + i * strideY, w);
+
+	// load UV plane
+	h /= 2;
+	ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
+
+	for (i = 0; i < h; i++)
+		memcpy(ptr + i * pitch, pDataUV + i * strideUV, w);
+
+	return MFX_ERR_NONE;
+}
+
+int QSV_Encoder_Internal::GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize)
+{
+	if (pTaskPool)
+		for (int i = 0; i < nPoolSize; i++)
+			if (!pTaskPool[i].syncp)
+				return i;
+	return MFX_ERR_NOT_FOUND;
+}
+
+mfxStatus QSV_Encoder_Internal::Encode(uint64_t ts, uint8_t *pDataY,
+		uint8_t *pDataUV, uint32_t strideY, uint32_t strideUV,
+		mfxBitstream **pBS)
+{
+	mfxStatus sts = MFX_ERR_NONE;
+	*pBS = NULL;
+	int nTaskIdx = GetFreeTaskIndex(m_pTaskPool, m_nTaskPool);
+
+#if 0
+	info("MSDK Encode:\n"
+		"\tTaskIndex: %d",
+		nTaskIdx);
+#endif
+
+	int nSurfIdx = GetFreeSurfaceIndex(m_pmfxSurfaces, m_nSurfNum);
+#if 0
+	info("MSDK Encode:\n"
+		"\tnSurfIdx: %d",
+		nSurfIdx);
+#endif
+
+	while (MFX_ERR_NOT_FOUND == nTaskIdx || MFX_ERR_NOT_FOUND == nSurfIdx) {
+		// No more free tasks or surfaces, need to sync
+		sts = m_session.SyncOperation(m_pTaskPool[m_nFirstSyncTask].syncp,
+				60000);
+		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+		mfxU8 *pTemp = m_outBitstream.Data;
+		memcpy(&m_outBitstream, &m_pTaskPool[m_nFirstSyncTask].mfxBS,
+				sizeof(mfxBitstream));
+
+		m_pTaskPool[m_nFirstSyncTask].mfxBS.Data = pTemp;
+		m_pTaskPool[m_nFirstSyncTask].mfxBS.DataLength = 0;
+		m_pTaskPool[m_nFirstSyncTask].mfxBS.DataOffset = 0;
+		m_pTaskPool[m_nFirstSyncTask].syncp = NULL;
+		nTaskIdx = m_nFirstSyncTask;
+		m_nFirstSyncTask = (m_nFirstSyncTask + 1) % m_nTaskPool;
+		*pBS = &m_outBitstream;
+
+#if 0
+		info("MSDK Encode:\n"
+			"\tnew FirstSyncTask: %d\n"
+			"\tTaskIndex:         %d",
+			m_nFirstSyncTask,
+			nTaskIdx);
+#endif
+
+		nSurfIdx = GetFreeSurfaceIndex(m_pmfxSurfaces, m_nSurfNum);
+#if 0
+		info("MSDK Encode:\n"
+			"\tnSurfIdx: %d",
+			nSurfIdx);
+#endif
+	}
+
+	mfxFrameSurface1 *pSurface = m_pmfxSurfaces[nSurfIdx];
+	if (m_bUseD3D11)
+		sts = m_mfxAllocator.Lock(m_mfxAllocator.pthis,
+				pSurface->Data.MemId, &(pSurface->Data));
+
+	sts = LoadNV12(pSurface, pDataY, pDataUV, strideY, strideUV);
+	pSurface->Data.TimeStamp = ts;
+
+	if (m_bUseD3D11)
+		sts = m_mfxAllocator.Unlock(m_mfxAllocator.pthis,
+				pSurface->Data.MemId, &(pSurface->Data));
+
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	for (;;) {
+		// Encode a frame asychronously (returns immediately)
+		sts = m_pmfxENC->EncodeFrameAsync(NULL, pSurface,
+				&m_pTaskPool[nTaskIdx].mfxBS,
+				&m_pTaskPool[nTaskIdx].syncp);
+
+		if (MFX_ERR_NONE < sts && !m_pTaskPool[nTaskIdx].syncp) {
+			// Repeat the call if warning and no output
+			if (MFX_WRN_DEVICE_BUSY == sts)
+				MSDK_SLEEP(1);  // Wait if device is busy, then repeat the same call
+		} else if (MFX_ERR_NONE < sts && m_pTaskPool[nTaskIdx].syncp) {
+			sts = MFX_ERR_NONE;     // Ignore warnings if output is available
+			break;
+		} else if (MFX_ERR_NOT_ENOUGH_BUFFER == sts) {
+			// Allocate more bitstream buffer memory here if needed...
+			break;
+		} else
+			break;
+	}
+
+	return sts;
+}
+
+mfxStatus QSV_Encoder_Internal::Drain()
+{
+	mfxStatus sts = MFX_ERR_NONE;
+
+	while (m_pTaskPool[m_nFirstSyncTask].syncp) {
+		sts = m_session.SyncOperation(m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
+		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+		m_pTaskPool[m_nFirstSyncTask].syncp = NULL;
+		m_nFirstSyncTask = (m_nFirstSyncTask + 1) % m_nTaskPool;
+	}
+
+	return sts;
+}
+
+mfxStatus QSV_Encoder_Internal::ClearData()
+{
+	mfxStatus sts = MFX_ERR_NONE;
+	sts = Drain();
+
+	sts = m_pmfxENC->Close();
+
+	if (m_bUseD3D11)
+		m_mfxAllocator.Free(m_mfxAllocator.pthis, &m_mfxResponse);
+
+	for (int i = 0; i < m_nSurfNum; i++) {
+		if (!m_bUseD3D11)
+			delete m_pmfxSurfaces[i]->Data.Y;
+
+		delete m_pmfxSurfaces[i];
+	}
+	MSDK_SAFE_DELETE_ARRAY(m_pmfxSurfaces);
+
+	for (int i = 0; i < m_nTaskPool; i++)
+		delete m_pTaskPool[i].mfxBS.Data;
+	MSDK_SAFE_DELETE_ARRAY(m_pTaskPool);
+
+	delete m_outBitstream.Data;
+
+	if (m_pmfxENC != NULL) {
+		delete m_pmfxENC;
+		m_pmfxENC = NULL;
+	}
+
+	if (m_bUseD3D11)
+		Release();
+
+	m_session.Close();
+
+	return sts;
+}
+
+mfxStatus QSV_Encoder_Internal::Reset(qsv_param_t *pParams)
+{
+	mfxStatus sts = ClearData();
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	sts = Open(pParams);
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+	return sts;
+}

+ 112 - 0
plugins/obs-qsv11/QSV_Encoder_Internal.h

@@ -0,0 +1,112 @@
+/*
+
+This file is provided under a dual BSD/GPLv2 license.  When using or
+redistributing this file, you may do so under either license.
+
+GPL LICENSE SUMMARY
+
+Copyright(c) Oct. 2015 Intel Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+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.
+
+Contact Information:
+
+Seung-Woo Kim, [email protected]
+705 5th Ave S #500, Seattle, WA 98104
+
+BSD LICENSE
+
+Copyright(c) <date> Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Intel Corporation nor the names of its
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#pragma once
+#include "mfxastructures.h"
+#include "mfxvideo++.h"
+#include "QSV_Encoder.h"
+#include "common_utils.h"
+
+class QSV_Encoder_Internal
+{
+public:
+	QSV_Encoder_Internal(mfxIMPL& impl, mfxVersion& version);
+	~QSV_Encoder_Internal();
+
+	mfxStatus    Open(qsv_param_t * pParams);
+	void         GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf,
+			mfxU16 *pnSPSBuf, mfxU16 *pnPPSBuf);
+	mfxStatus    Encode(uint64_t ts, uint8_t *pDataY, uint8_t *pDataUV,
+			uint32_t strideY, uint32_t strideUV, mfxBitstream
+			**pBS);
+	mfxStatus    ClearData();
+	mfxStatus    Reset(qsv_param_t *pParams);
+
+protected:
+	bool         InitParams(qsv_param_t * pParams);
+	mfxStatus    AllocateSurfaces();
+	mfxStatus    GetVideoParam();
+	mfxStatus    InitBitstream();
+	mfxStatus    LoadNV12(mfxFrameSurface1 *pSurface, uint8_t *pDataY,
+			uint8_t *pDataUV, uint32_t strideY, uint32_t strideUV);
+	mfxStatus    Drain();
+	int          GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize);
+
+private:
+	mfxIMPL                        m_impl;
+	mfxVersion                     m_ver;
+	MFXVideoSession                m_session;
+	mfxFrameAllocator              m_mfxAllocator;
+	mfxVideoParam                  m_mfxEncParams;
+	mfxFrameAllocResponse          m_mfxResponse;
+	mfxFrameSurface1**             m_pmfxSurfaces;
+	mfxU16                         m_nSurfNum;
+	MFXVideoENCODE*                m_pmfxENC;
+	mfxU8                          m_SPSBuffer[100];
+	mfxU8                          m_PPSBuffer[100];
+	mfxU16                         m_nSPSBufferSize;
+	mfxU16                         m_nPPSBufferSize;
+	mfxVideoParam                  m_parameter;
+	mfxExtCodingOption2            m_co2;
+	mfxExtCodingOption             m_co;
+	mfxU16                         m_nTaskPool;
+	Task*                          m_pTaskPool;
+	int                            m_nTaskIdx;
+	int                            m_nFirstSyncTask;
+	mfxBitstream                   m_outBitstream;
+	bool                           m_bIsWindows8OrGreater;
+	bool                           m_bUseD3D11;
+};
+

+ 19 - 0
plugins/obs-qsv11/bits/linux_defs.h

@@ -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) 2005-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define MSDK_FOPEN(FH, FN, M)           { FH=fopen(FN,M); }
+#define MSDK_SLEEP(X)                   { usleep(1000*(X)); }
+
+typedef timespec mfxTime;

+ 16 - 0
plugins/obs-qsv11/bits/windows_defs.h

@@ -0,0 +1,16 @@
+/*****************************************************************************
+
+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-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#include <windows.h>
+
+#define MSDK_FOPEN(FH, FN, M)           { fopen_s(&FH, FN, M); }
+#define MSDK_SLEEP(X)                   { Sleep(X); }
+
+typedef LARGE_INTEGER mfxTime;

+ 487 - 0
plugins/obs-qsv11/common_directx11.cpp

@@ -0,0 +1,487 @@
+/*****************************************************************************
+
+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-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#include "common_directx11.h"
+
+#include<map>
+
+ID3D11Device*							g_pD3D11Device;
+ID3D11DeviceContext*					g_pD3D11Ctx;
+IDXGIFactory2*							g_pDXGIFactory;
+IDXGIAdapter*                           g_pAdapter;
+
+std::map<mfxMemId*, mfxHDL>             allocResponses;
+std::map<mfxHDL, mfxFrameAllocResponse> allocDecodeResponses;
+std::map<mfxHDL, int>                   allocDecodeRefCount;
+
+typedef struct {
+    mfxMemId    memId;
+    mfxMemId    memIdStage;
+    mfxU16      rw;
+} CustomMemId;
+
+const struct {
+    mfxIMPL impl;       // actual implementation
+    mfxU32  adapterID;  // device adapter number
+} implTypes[] = {
+    {MFX_IMPL_HARDWARE, 0},
+    {MFX_IMPL_HARDWARE2, 1},
+    {MFX_IMPL_HARDWARE3, 2},
+    {MFX_IMPL_HARDWARE4, 3}
+};
+
+// =================================================================
+// DirectX functionality required to manage DX11 device and surfaces
+//
+
+IDXGIAdapter* GetIntelDeviceAdapterHandle(mfxSession session)
+{
+    mfxU32  adapterNum = 0;
+    mfxIMPL impl;
+
+    MFXQueryIMPL(session, &impl);
+
+    mfxIMPL baseImpl = MFX_IMPL_BASETYPE(impl); // Extract Media SDK base implementation type
+
+    // get corresponding adapter number
+    for (mfxU8 i = 0; i < sizeof(implTypes)/sizeof(implTypes[0]); i++) {
+        if (implTypes[i].impl == baseImpl) {
+            adapterNum = implTypes[i].adapterID;
+            break;
+        }
+    }
+
+    HRESULT hres = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&g_pDXGIFactory) );
+    if (FAILED(hres)) return NULL;
+
+	IDXGIAdapter* adapter;
+    hres = g_pDXGIFactory->EnumAdapters(adapterNum, &adapter);
+    if (FAILED(hres)) return NULL;
+
+    return adapter;
+}
+
+// Create HW device context
+mfxStatus CreateHWDevice(mfxSession session, mfxHDL* deviceHandle, HWND hWnd, bool bCreateSharedHandles)
+{
+    //Note: not using bCreateSharedHandles for DX11 -- for API consistency only
+    hWnd; // Window handle not required by DX11 since we do not showcase rendering.
+    bCreateSharedHandles; // For rendering, not used here. Just for consistencies sake.
+
+    HRESULT hres = S_OK;
+
+    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;
+
+    g_pAdapter = GetIntelDeviceAdapterHandle(session);
+    if (NULL == g_pAdapter)
+        return MFX_ERR_DEVICE_FAILED;
+
+    UINT dxFlags = 0;
+    //UINT dxFlags = D3D11_CREATE_DEVICE_DEBUG;
+
+    hres =  D3D11CreateDevice(  g_pAdapter,
+                                D3D_DRIVER_TYPE_UNKNOWN,
+                                NULL,
+                                dxFlags,
+                                FeatureLevels,
+                                (sizeof(FeatureLevels) / sizeof(FeatureLevels[0])),
+                                D3D11_SDK_VERSION,
+                                &g_pD3D11Device,
+                                &pFeatureLevelsOut,
+                                &g_pD3D11Ctx);
+    if (FAILED(hres))
+        return MFX_ERR_DEVICE_FAILED;
+
+    // turn on multithreading for the DX11 context
+    CComQIPtr<ID3D10Multithread> p_mt(g_pD3D11Ctx);
+    if (p_mt)
+        p_mt->SetMultithreadProtected(true);
+    else
+        return MFX_ERR_DEVICE_FAILED;
+
+    *deviceHandle = (mfxHDL)g_pD3D11Device;
+
+    return MFX_ERR_NONE;
+}
+
+
+void SetHWDeviceContext(CComPtr<ID3D11DeviceContext> devCtx)
+{
+    g_pD3D11Ctx = devCtx;
+    devCtx->GetDevice(&g_pD3D11Device);
+}
+
+// Free HW device context
+void CleanupHWDevice()
+{
+	if (g_pAdapter)
+	{
+		g_pAdapter->Release();
+		g_pAdapter = NULL;
+	}
+	if (g_pD3D11Device)
+	{
+		g_pD3D11Device->Release();
+		g_pD3D11Device = NULL;
+	}
+	if (g_pD3D11Ctx)
+	{
+		g_pD3D11Ctx->Release();
+		g_pD3D11Ctx = NULL;
+	}
+	if (g_pDXGIFactory)
+	{
+		g_pDXGIFactory->Release();
+		g_pDXGIFactory = NULL;
+	}
+}
+
+CComPtr<ID3D11DeviceContext> GetHWDeviceContext()
+{
+    return g_pD3D11Ctx;
+}
+
+/* (Hugh) Functions currently unused */
+#if 0
+void ClearYUVSurfaceD3D(mfxMemId memId)
+{
+    // TBD
+}
+
+void ClearRGBSurfaceD3D(mfxMemId memId)
+{
+    // TBD
+}
+#endif
+
+//
+// Intel Media SDK memory allocator entrypoints....
+//
+mfxStatus _simple_alloc(mfxFrameAllocRequest* request, mfxFrameAllocResponse* response)
+{
+    HRESULT hRes;
+
+    // Determine surface format
+    DXGI_FORMAT format;
+    if (MFX_FOURCC_NV12 == request->Info.FourCC)
+        format = DXGI_FORMAT_NV12;
+    else if (MFX_FOURCC_RGB4 == request->Info.FourCC)
+        format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    else if (MFX_FOURCC_YUY2== request->Info.FourCC)
+        format = DXGI_FORMAT_YUY2;
+    else if (MFX_FOURCC_P8 == request->Info.FourCC ) //|| MFX_FOURCC_P8_TEXTURE == request->Info.FourCC
+        format = DXGI_FORMAT_P8;
+    else
+        format = DXGI_FORMAT_UNKNOWN;
+
+    if (DXGI_FORMAT_UNKNOWN == format)
+        return MFX_ERR_UNSUPPORTED;
+
+
+    // Allocate custom container to keep texture and stage buffers for each surface
+    // Container also stores the intended read and/or write operation.
+    CustomMemId** mids = (CustomMemId**)calloc(request->NumFrameSuggested, sizeof(CustomMemId*));
+    if (!mids) return MFX_ERR_MEMORY_ALLOC;
+
+    for (int i=0; i<request->NumFrameSuggested; i++) {
+        mids[i] = (CustomMemId*)calloc(1, sizeof(CustomMemId));
+        if (!mids[i]) {
+            return MFX_ERR_MEMORY_ALLOC;
+        }
+        mids[i]->rw = request->Type & 0xF000; // Set intended read/write operation
+    }
+
+    request->Type = request->Type & 0x0FFF;
+
+    // because P8 data (bitstream) for h264 encoder should be allocated by CreateBuffer()
+    // but P8 data (MBData) for MPEG2 encoder should be allocated by CreateTexture2D()
+    if (request->Info.FourCC == MFX_FOURCC_P8) {
+        D3D11_BUFFER_DESC desc = { 0 };
+
+        if (!request->NumFrameSuggested) return MFX_ERR_MEMORY_ALLOC;
+
+        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 = g_pD3D11Device->CreateBuffer(&desc, 0, &buffer);
+        if (FAILED(hRes))
+            return MFX_ERR_MEMORY_ALLOC;
+
+        mids[0]->memId = reinterpret_cast<ID3D11Texture2D*>(buffer);
+    } else {
+        D3D11_TEXTURE2D_DESC desc = {0};
+
+        desc.Width              = request->Info.Width;
+        desc.Height             = request->Info.Height;
+        desc.MipLevels          = 1;
+        desc.ArraySize          = 1; // number of subresources is 1 in this case
+        desc.Format             = format;
+        desc.SampleDesc.Count   = 1;
+        desc.Usage              = D3D11_USAGE_DEFAULT;
+        desc.BindFlags          = D3D11_BIND_DECODER;
+        desc.MiscFlags          = 0;
+        //desc.MiscFlags            = D3D11_RESOURCE_MISC_SHARED;
+
+        if ( (MFX_MEMTYPE_FROM_VPPIN & request->Type) &&
+             (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;
+
+        // Create surface textures
+        for (size_t i = 0; i < request->NumFrameSuggested / desc.ArraySize; i++) {
+            hRes = g_pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D);
+
+            if (FAILED(hRes))
+                return MFX_ERR_MEMORY_ALLOC;
+
+            mids[i]->memId = pTexture2D;
+        }
+
+        desc.ArraySize      = 1;
+        desc.Usage          = D3D11_USAGE_STAGING;
+        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;// | D3D11_CPU_ACCESS_WRITE;
+        desc.BindFlags      = 0;
+        desc.MiscFlags      = 0;
+        //desc.MiscFlags        = D3D11_RESOURCE_MISC_SHARED;
+
+        // Create surface staging textures
+        for (size_t i = 0; i < request->NumFrameSuggested; i++) {
+            hRes = g_pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D);
+
+            if (FAILED(hRes))
+                return MFX_ERR_MEMORY_ALLOC;
+
+            mids[i]->memIdStage = pTexture2D;
+        }
+    }
+
+
+    response->mids = (mfxMemId*)mids;
+    response->NumFrameActual = request->NumFrameSuggested;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus simple_alloc(mfxHDL pthis, mfxFrameAllocRequest* request, mfxFrameAllocResponse* response)
+{
+    mfxStatus sts = MFX_ERR_NONE;
+
+    if (request->Type & MFX_MEMTYPE_SYSTEM_MEMORY)
+        return MFX_ERR_UNSUPPORTED;
+
+    if (allocDecodeResponses.find(pthis) != allocDecodeResponses.end() &&
+        MFX_MEMTYPE_EXTERNAL_FRAME & request->Type &&
+        MFX_MEMTYPE_FROM_DECODE & request->Type) {
+        // Memory for this request was already allocated during manual allocation stage. Return saved response
+        //   When decode acceleration device (DXVA) is created it requires a list of d3d surfaces to be passed.
+        //   Therefore Media SDK will ask for the surface info/mids again at Init() stage, thus requiring us to return the saved response
+        //   (No such restriction applies to Encode or VPP)
+        *response = allocDecodeResponses[pthis];
+        allocDecodeRefCount[pthis]++;
+    } else {
+        sts = _simple_alloc(request, response);
+
+        if (MFX_ERR_NONE == sts) {
+            if ( MFX_MEMTYPE_EXTERNAL_FRAME & request->Type &&
+                 MFX_MEMTYPE_FROM_DECODE & request->Type) {
+                // Decode alloc response handling
+                allocDecodeResponses[pthis] = *response;
+                allocDecodeRefCount[pthis]++;
+            } else {
+                // Encode and VPP alloc response handling
+                allocResponses[response->mids] = pthis;
+            }
+        }
+    }
+
+    return sts;
+}
+
+mfxStatus simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr)
+{
+    pthis; // To suppress warning for this unused parameter
+
+    HRESULT hRes = S_OK;
+
+    D3D11_TEXTURE2D_DESC        desc = {0};
+    D3D11_MAPPED_SUBRESOURCE    lockedRect = {0};
+
+    CustomMemId*        memId       = (CustomMemId*)mid;
+    ID3D11Texture2D*    pSurface    = (ID3D11Texture2D*)memId->memId;
+    ID3D11Texture2D*    pStage      = (ID3D11Texture2D*)memId->memIdStage;
+
+    D3D11_MAP   mapType  = D3D11_MAP_READ;
+    UINT        mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT;
+
+    if (NULL == pStage) {
+        hRes = g_pD3D11Ctx->Map(pSurface, 0, mapType, mapFlags, &lockedRect);
+        desc.Format = DXGI_FORMAT_P8;
+    } else {
+        pSurface->GetDesc(&desc);
+
+        // copy data only in case of user wants o read from stored surface
+        if (memId->rw & WILL_READ)
+            g_pD3D11Ctx->CopySubresourceRegion(pStage, 0, 0, 0, 0, pSurface, 0, NULL);
+
+        do {
+            hRes = g_pD3D11Ctx->Map(pStage, 0, mapType, mapFlags, &lockedRect);
+            if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes)
+                return MFX_ERR_LOCK_MEMORY;
+        } 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_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;
+    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;
+    default:
+        return MFX_ERR_LOCK_MEMORY;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus simple_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr)
+{
+    pthis; // To suppress warning for this unused parameter
+
+    CustomMemId*        memId       = (CustomMemId*)mid;
+    ID3D11Texture2D*    pSurface    = (ID3D11Texture2D*)memId->memId;
+    ID3D11Texture2D*    pStage      = (ID3D11Texture2D*)memId->memIdStage;
+
+    if (NULL == pStage) {
+        g_pD3D11Ctx->Unmap(pSurface, 0);
+    } else {
+        g_pD3D11Ctx->Unmap(pStage, 0);
+        // copy data only in case of user wants to write to stored surface
+        if (memId->rw & WILL_WRITE)
+            g_pD3D11Ctx->CopySubresourceRegion(pSurface, 0, 0, 0, 0, pStage, 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 simple_gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL* handle)
+{
+    pthis; // To suppress warning for this unused parameter
+
+    if (NULL == handle)
+        return MFX_ERR_INVALID_HANDLE;
+
+    mfxHDLPair*     pPair = (mfxHDLPair*)handle;
+    CustomMemId*    memId = (CustomMemId*)mid;
+
+    pPair->first  = memId->memId; // surface texture
+    pPair->second = 0;
+
+    return MFX_ERR_NONE;
+}
+
+
+mfxStatus _simple_free(mfxFrameAllocResponse* response)
+{
+    if (response->mids) {
+        for (mfxU32 i = 0; i < response->NumFrameActual; i++) {
+            if (response->mids[i]) {
+                CustomMemId*        mid         = (CustomMemId*)response->mids[i];
+                ID3D11Texture2D*    pSurface    = (ID3D11Texture2D*)mid->memId;
+                ID3D11Texture2D*    pStage      = (ID3D11Texture2D*)mid->memIdStage;
+
+                if (pSurface)
+                    pSurface->Release();
+                if (pStage)
+                    pStage->Release();
+
+                free(mid);
+            }
+        }
+        free(response->mids);
+        response->mids = NULL;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus simple_free(mfxHDL pthis, mfxFrameAllocResponse* response)
+{
+    if (NULL == response)
+        return MFX_ERR_NULL_PTR;
+
+    if (allocResponses.find(response->mids) == allocResponses.end()) {
+        // Decode free response handling
+        if (--allocDecodeRefCount[pthis] == 0) {
+            _simple_free(response);
+            allocDecodeResponses.erase(pthis);
+            allocDecodeRefCount.erase(pthis);
+        }
+    } else {
+        // Encode and VPP free response handling
+        allocResponses.erase(response->mids);
+        _simple_free(response);
+    }
+
+    return MFX_ERR_NONE;
+}

+ 39 - 0
plugins/obs-qsv11/common_directx11.h

@@ -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) 2005-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#pragma once
+
+#include "common_utils.h"
+
+#include <windows.h>
+#include <d3d11.h>
+#include <dxgi1_2.h>
+#include <atlbase.h>
+
+#define DEVICE_MGR_TYPE MFX_HANDLE_D3D11_DEVICE
+
+// =================================================================
+// DirectX functionality required to manage D3D surfaces
+//
+
+// Create DirectX 11 device context
+// - Required when using D3D surfaces.
+// - D3D Device created and handed to Intel Media SDK
+// - Intel graphics device adapter will be determined automatically (does not have to be primary),
+//   but with the following caveats:
+//     - Device must be active (but monitor does NOT have to be attached)
+//     - Device must be enabled in BIOS. Required for the case when used together with a discrete graphics card
+//     - For switchable graphics solutions (mobile) make sure that Intel device is the active device
+mfxStatus CreateHWDevice(mfxSession session, mfxHDL* deviceHandle, HWND hWnd, bool bCreateSharedHandles);
+void CleanupHWDevice();
+void SetHWDeviceContext(CComPtr<ID3D11DeviceContext> devCtx);
+CComPtr<ID3D11DeviceContext> GetHWDeviceContext();
+void ClearYUVSurfaceD3D(mfxMemId memId);
+void ClearRGBSurfaceD3D(mfxMemId memId);

+ 306 - 0
plugins/obs-qsv11/common_utils.cpp

@@ -0,0 +1,306 @@
+/*****************************************************************************
+
+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-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#include "common_utils.h"
+
+// =================================================================
+// Utility functions, not directly tied to Intel Media SDK functionality
+//
+
+
+void PrintErrString(int err,const char* filestr,int line)
+{
+    switch (err) {
+    case   0:
+        printf("\n No error.\n");
+        break;
+    case  -1:
+        printf("\n Unknown error: %s %d\n",filestr,line);
+        break;
+    case  -2:
+        printf("\n Null pointer.  Check filename/path + permissions? %s %d\n",filestr,line);
+        break;
+    case  -3:
+        printf("\n Unsupported feature/library load error. %s %d\n",filestr,line);
+        break;
+    case  -4:
+        printf("\n Could not allocate memory. %s %d\n",filestr,line);
+        break;
+    case  -5:
+        printf("\n Insufficient IO buffers. %s %d\n",filestr,line);
+        break;
+    case  -6:
+        printf("\n Invalid handle. %s %d\n",filestr,line);
+        break;
+    case  -7:
+        printf("\n Memory lock failure. %s %d\n",filestr,line);
+        break;
+    case  -8:
+        printf("\n Function called before initialization. %s %d\n",filestr,line);
+        break;
+    case  -9:
+        printf("\n Specified object not found. %s %d\n",filestr,line);
+        break;
+    case -10:
+        printf("\n More input data expected. %s %d\n",filestr,line);
+        break;
+    case -11:
+        printf("\n More output surfaces expected. %s %d\n",filestr,line);
+        break;
+    case -12:
+        printf("\n Operation aborted. %s %d\n",filestr,line);
+        break;
+    case -13:
+        printf("\n HW device lost. %s %d\n",filestr,line);
+        break;
+    case -14:
+        printf("\n Incompatible video parameters. %s %d\n",filestr,line);
+        break;
+    case -15:
+        printf("\n Invalid video parameters. %s %d\n",filestr,line);
+        break;
+    case -16:
+        printf("\n Undefined behavior. %s %d\n",filestr,line);
+        break;
+    case -17:
+        printf("\n Device operation failure. %s %d\n",filestr,line);
+        break;
+    case -18:
+        printf("\n More bitstream data expected. %s %d\n",filestr,line);
+        break;
+    case -19:
+        printf("\n Incompatible audio parameters. %s %d\n",filestr,line);
+        break;
+    case -20:
+        printf("\n Invalid audio parameters. %s %d\n",filestr,line);
+        break;
+    default:
+        printf("\nError code %d,\t%s\t%d\n\n", err, filestr, line);
+    }
+}
+
+mfxStatus ReadPlaneData(mfxU16 w, mfxU16 h, mfxU8* buf, mfxU8* ptr,
+                        mfxU16 pitch, mfxU16 offset, FILE* fSource)
+{
+    mfxU32 nBytesRead;
+    for (mfxU16 i = 0; i < h; i++) {
+        nBytesRead = (mfxU32) fread(buf, 1, w, fSource);
+        if (w != nBytesRead)
+            return MFX_ERR_MORE_DATA;
+        for (mfxU16 j = 0; j < w; j++)
+            ptr[i * pitch + j * 2 + offset] = buf[j];
+    }
+    return MFX_ERR_NONE;
+}
+
+mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource)
+{
+    if (!fSource) {
+        // Simulate instantaneous access to 1000 "empty" frames.
+        static int frameCount = 0;
+        if (1000 == frameCount++)
+            return MFX_ERR_MORE_DATA;
+        else
+            return MFX_ERR_NONE;
+    }
+
+    mfxStatus sts = MFX_ERR_NONE;
+    mfxU32 nBytesRead;
+    mfxU16 w, h, i, pitch;
+    mfxU8* ptr;
+    mfxFrameInfo* pInfo = &pSurface->Info;
+    mfxFrameData* pData = &pSurface->Data;
+
+    if (pInfo->CropH > 0 && pInfo->CropW > 0) {
+        w = pInfo->CropW;
+        h = pInfo->CropH;
+    } else {
+        w = pInfo->Width;
+        h = pInfo->Height;
+    }
+
+    pitch = pData->Pitch;
+    ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
+
+    // read luminance plane
+    for (i = 0; i < h; i++) {
+        nBytesRead = (mfxU32) fread(ptr + i * pitch, 1, w, fSource);
+        if (w != nBytesRead)
+            return MFX_ERR_MORE_DATA;
+    }
+
+    mfxU8 buf[2048];        // maximum supported chroma width for nv12
+    w /= 2;
+    h /= 2;
+    ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
+    if (w > 2048)
+        return MFX_ERR_UNSUPPORTED;
+
+    // load U
+    sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, fSource);
+    if (MFX_ERR_NONE != sts)
+        return sts;
+    // load V
+    ReadPlaneData(w, h, buf, ptr, pitch, 1, fSource);
+    if (MFX_ERR_NONE != sts)
+        return sts;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus LoadRawRGBFrame(mfxFrameSurface1* pSurface, FILE* fSource)
+{
+    if (!fSource) {
+        // Simulate instantaneous access to 1000 "empty" frames.
+        static int frameCount = 0;
+        if (1000 == frameCount++)
+            return MFX_ERR_MORE_DATA;
+        else
+            return MFX_ERR_NONE;
+    }
+
+    size_t nBytesRead;
+    mfxU16 w, h;
+    mfxFrameInfo* pInfo = &pSurface->Info;
+
+    if (pInfo->CropH > 0 && pInfo->CropW > 0) {
+        w = pInfo->CropW;
+        h = pInfo->CropH;
+    } else {
+        w = pInfo->Width;
+        h = pInfo->Height;
+    }
+
+    for (mfxU16 i = 0; i < h; i++) {
+        nBytesRead = fread(pSurface->Data.B + i * pSurface->Data.Pitch,
+                           1, w * 4, fSource);
+        if ((size_t)(w * 4) != nBytesRead)
+            return MFX_ERR_MORE_DATA;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus WriteBitStreamFrame(mfxBitstream* pMfxBitstream, FILE* fSink)
+{
+    mfxU32 nBytesWritten =
+        (mfxU32) fwrite(pMfxBitstream->Data + pMfxBitstream->DataOffset, 1,
+                        pMfxBitstream->DataLength, fSink);
+    if (nBytesWritten != pMfxBitstream->DataLength)
+        return MFX_ERR_UNDEFINED_BEHAVIOR;
+
+    pMfxBitstream->DataLength = 0;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus ReadBitStreamData(mfxBitstream* pBS, FILE* fSource)
+{
+    memmove(pBS->Data, pBS->Data + pBS->DataOffset, pBS->DataLength);
+    pBS->DataOffset = 0;
+
+    mfxU32 nBytesRead = (mfxU32) fread(pBS->Data + pBS->DataLength, 1,
+                                       pBS->MaxLength - pBS->DataLength,
+                                       fSource);
+
+    if (0 == nBytesRead)
+        return MFX_ERR_MORE_DATA;
+
+    pBS->DataLength += nBytesRead;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus WriteSection(mfxU8* plane, mfxU16 factor, mfxU16 chunksize,
+                       mfxFrameInfo* pInfo, mfxFrameData* pData, mfxU32 i,
+                       mfxU32 j, FILE* fSink)
+{
+    if (chunksize !=
+        fwrite(plane +
+               (pInfo->CropY * pData->Pitch / factor + pInfo->CropX) +
+               i * pData->Pitch + j, 1, chunksize, fSink))
+        return MFX_ERR_UNDEFINED_BEHAVIOR;
+    return MFX_ERR_NONE;
+}
+
+mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink)
+{
+    mfxFrameInfo* pInfo = &pSurface->Info;
+    mfxFrameData* pData = &pSurface->Data;
+    mfxU32 i, j, h, w;
+    mfxStatus sts = MFX_ERR_NONE;
+
+    for (i = 0; i < pInfo->CropH; i++)
+        sts =
+            WriteSection(pData->Y, 1, pInfo->CropW, pInfo, pData, i, 0,
+                         fSink);
+
+    h = pInfo->CropH / 2;
+    w = pInfo->CropW;
+    for (i = 0; i < h; i++)
+        for (j = 0; j < w; j += 2)
+            sts =
+                WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
+                             fSink);
+    for (i = 0; i < h; i++)
+        for (j = 1; j < w; j += 2)
+            sts =
+                WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
+                             fSink);
+
+    return sts;
+}
+
+int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize)
+{
+    if (pTaskPool)
+        for (int i = 0; i < nPoolSize; i++)
+            if (!pTaskPool[i].syncp)
+                return i;
+    return MFX_ERR_NOT_FOUND;
+}
+
+void ClearYUVSurfaceSysMem(mfxFrameSurface1* pSfc, mfxU16 width, mfxU16 height)
+{
+    // In case simulating direct access to frames we initialize the allocated surfaces with default pattern
+    memset(pSfc->Data.Y, 100, width * height);  // Y plane
+    memset(pSfc->Data.U, 50, (width * height)/2);  // UV plane
+}
+
+
+// Get free raw frame surface
+int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize)
+{
+    if (pSurfacesPool)
+        for (mfxU16 i = 0; i < nPoolSize; i++)
+            if (0 == pSurfacesPool[i]->Data.Locked)
+                return i;
+    return MFX_ERR_NOT_FOUND;
+}
+
+char mfxFrameTypeString(mfxU16 FrameType)
+{
+    mfxU8 FrameTmp = FrameType & 0xF;
+    char FrameTypeOut;
+    switch (FrameTmp) {
+    case MFX_FRAMETYPE_I:
+        FrameTypeOut = 'I';
+        break;
+    case MFX_FRAMETYPE_P:
+        FrameTypeOut = 'P';
+        break;
+    case MFX_FRAMETYPE_B:
+        FrameTypeOut = 'B';
+        break;
+    default:
+        FrameTypeOut = '*';
+    }
+    return FrameTypeOut;
+}

+ 109 - 0
plugins/obs-qsv11/common_utils.h

@@ -0,0 +1,109 @@
+/*****************************************************************************
+
+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-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#pragma once
+
+#include <stdio.h>
+
+#include "mfxvideo++.h"
+
+// =================================================================
+// OS-specific definitions of types, macro, etc...
+// The following should be defined:
+//  - mfxTime
+//  - MSDK_FOPEN
+//  - MSDK_SLEEP
+#if defined(_WIN32) || defined(_WIN64)
+#include "bits/windows_defs.h"
+#elif defined(__linux__)
+#include "bits/linux_defs.h"
+#endif
+
+// =================================================================
+// Helper macro definitions...
+#define MSDK_PRINT_RET_MSG(ERR)         {PrintErrString(ERR, __FILE__, __LINE__);}
+#define MSDK_CHECK_RESULT(P, X, ERR)    {if ((X) > (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}}
+#define MSDK_CHECK_POINTER(P, ERR)      {if (!(P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}}
+#define MSDK_CHECK_ERROR(P, X, ERR)     {if ((X) == (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}}
+#define MSDK_IGNORE_MFX_STS(P, X)       {if ((X) == (P)) {P = MFX_ERR_NONE;}}
+#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_ALIGN32(X)                 (((mfxU32)((X)+31)) & (~ (mfxU32)31))
+#define MSDK_ALIGN16(value)             (((value + 15) >> 4) << 4)
+#define MSDK_SAFE_RELEASE(X)            {if (X) { X->Release(); X = NULL; }}
+#define MSDK_MAX(A, B)                  (((A) > (B)) ? (A) : (B))
+
+// Usage of the following two macros are only required for certain Windows DirectX11 use cases
+#define WILL_READ  0x1000
+#define WILL_WRITE 0x2000
+
+// =================================================================
+// Intel Media SDK memory allocator entrypoints....
+// Implementation of this functions is OS/Memory type specific.
+mfxStatus simple_alloc(mfxHDL pthis, mfxFrameAllocRequest* request, mfxFrameAllocResponse* response);
+mfxStatus simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr);
+mfxStatus simple_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr);
+mfxStatus simple_gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL* handle);
+mfxStatus simple_free(mfxHDL pthis, mfxFrameAllocResponse* response);
+
+
+
+// =================================================================
+// Utility functions, not directly tied to Media SDK functionality
+//
+
+void PrintErrString(int err,const char* filestr,int line);
+
+// LoadRawFrame: Reads raw frame from YUV file (YV12) into NV12 surface
+// - YV12 is a more common format for for YUV files than NV12 (therefore the conversion during read and write)
+// - For the simulation case (fSource = NULL), the surface is filled with default image data
+// LoadRawRGBFrame: Reads raw RGB32 frames from file into RGB32 surface
+// - For the simulation case (fSource = NULL), the surface is filled with default image data
+
+mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource);
+mfxStatus LoadRawRGBFrame(mfxFrameSurface1* pSurface, FILE* fSource);
+
+// Write raw YUV (NV12) surface to YUV (YV12) file
+mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink);
+
+// Write bit stream data for frame to file
+mfxStatus WriteBitStreamFrame(mfxBitstream* pMfxBitstream, FILE* fSink);
+// Read bit stream data from file. Stream is read as large chunks (= many frames)
+mfxStatus ReadBitStreamData(mfxBitstream* pBS, FILE* fSource);
+
+void ClearYUVSurfaceSysMem(mfxFrameSurface1* pSfc, mfxU16 width, mfxU16 height);
+void ClearYUVSurfaceVMem(mfxMemId memId);
+void ClearRGBSurfaceVMem(mfxMemId memId);
+
+// Get free raw frame surface
+int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize);
+
+// For use with asynchronous task management
+typedef struct {
+    mfxBitstream mfxBS;
+    mfxSyncPoint syncp;
+} Task;
+
+// Get free task
+int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize);
+
+// Initialize Intel Media SDK Session, device/display and memory manager
+mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles = false);
+
+// Release resources (device/display)
+void Release();
+
+// Convert frame type to string
+char mfxFrameTypeString(mfxU16 FrameType);
+
+void mfxGetTime(mfxTime* timestamp);
+
+//void mfxInitTime();  might need this for Windows
+double TimeDiffMsec(mfxTime tfinish, mfxTime tstart);

+ 104 - 0
plugins/obs-qsv11/common_utils_windows.cpp

@@ -0,0 +1,104 @@
+/*****************************************************************************
+
+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-2014 Intel Corporation. All Rights Reserved.
+
+*****************************************************************************/
+
+#include "common_utils.h"
+
+// ATTENTION: If D3D surfaces are used, DX9_D3D or DX11_D3D must be set in project settings or hardcoded here
+
+#ifdef DX9_D3D
+#include "common_directx.h"
+#elif DX11_D3D
+#include "common_directx11.h"
+#endif
+
+/* =======================================================
+ * Windows implementation of OS-specific utility functions
+ */
+
+mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles)
+{
+    bCreateSharedHandles; // (Hugh) Currently unused
+    pmfxAllocator; // (Hugh) Currently unused
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    // If mfxFrameAllocator is provided it means we need to setup DirectX device and memory allocator
+    if (pmfxAllocator) {
+		// Initialize Intel Media SDK Session
+		sts = pSession->Init(impl, &ver);
+		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+        // Create DirectX device context
+        mfxHDL deviceHandle;
+        sts = CreateHWDevice(*pSession, &deviceHandle, NULL, bCreateSharedHandles);
+        MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+        // Provide device manager to Media SDK
+        sts = pSession->SetHandle(DEVICE_MGR_TYPE, deviceHandle);
+        MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
+        pmfxAllocator->pthis  = *pSession; // We use Media SDK session ID as the allocation identifier
+        pmfxAllocator->Alloc  = simple_alloc;
+        pmfxAllocator->Free   = simple_free;
+        pmfxAllocator->Lock   = simple_lock;
+        pmfxAllocator->Unlock = simple_unlock;
+        pmfxAllocator->GetHDL = simple_gethdl;
+
+        // Since we are using video memory we must provide Media SDK with an external allocator
+        sts = pSession->SetFrameAllocator(pmfxAllocator);
+        MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+    }
+	else
+	{
+		// Initialize Intel Media SDK Session
+		sts = pSession->Init(impl, &ver);
+		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+	}
+    return sts;
+}
+
+void Release()
+{
+#if defined(DX9_D3D) || defined(DX11_D3D)
+    CleanupHWDevice();
+#endif
+}
+
+void mfxGetTime(mfxTime* timestamp)
+{
+    QueryPerformanceCounter(timestamp);
+}
+
+double TimeDiffMsec(mfxTime tfinish, mfxTime tstart)
+{
+    static LARGE_INTEGER tFreq = { 0 };
+
+    if (!tFreq.QuadPart) QueryPerformanceFrequency(&tFreq);
+
+    double freq = (double)tFreq.QuadPart;
+    return 1000.0 * ((double)tfinish.QuadPart - (double)tstart.QuadPart) / freq;
+}
+
+/* (Hugh) Functions currently unused */
+#if 0
+void ClearYUVSurfaceVMem(mfxMemId memId)
+{
+#if defined(DX9_D3D) || defined(DX11_D3D)
+    ClearYUVSurfaceD3D(memId);
+#endif
+}
+
+void ClearRGBSurfaceVMem(mfxMemId memId)
+{
+#if defined(DX9_D3D) || defined(DX11_D3D)
+    ClearRGBSurfaceD3D(memId);
+#endif
+}
+#endif

+ 11 - 0
plugins/obs-qsv11/data/locale/en-US.ini

@@ -0,0 +1,11 @@
+TargetUsage="Target Usage"
+Bitrate="Bitrate"
+MaxBitrate="Max Bitrate"
+RateControl="Rate Control"
+KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)"
+Profile="Profile"
+AsyncDepth="Async Depth"
+Accuracy="Accuracy"
+Convergence="Convergence"
+ICQQuality="ICQ Quality"
+LookAheadDepth="Lookahead Depth"

+ 76 - 0
plugins/obs-qsv11/libmfx/include/mfx_critical_section.h

@@ -0,0 +1,76 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_critical_section.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_CRITICAL_SECTION_H)
+#define __MFX_CRITICAL_SECTION_H
+
+#include <mfxdefs.h>
+
+namespace MFX
+{
+
+// Just set "critical section" instance to zero for initialization.
+typedef volatile mfxL32 mfxCriticalSection;
+
+// Enter the global critical section.
+void mfxEnterCriticalSection(mfxCriticalSection *pCSection);
+
+// Leave the global critical section.
+void mfxLeaveCriticalSection(mfxCriticalSection *pCSection);
+
+class MFXAutomaticCriticalSection
+{
+public:
+    // Constructor
+    explicit MFXAutomaticCriticalSection(mfxCriticalSection *pCSection)
+    {
+        m_pCSection = pCSection;
+        mfxEnterCriticalSection(m_pCSection);
+    }
+
+    // Destructor
+    ~MFXAutomaticCriticalSection()
+    {
+        mfxLeaveCriticalSection(m_pCSection);
+    }
+
+protected:
+    // Pointer to a critical section
+    mfxCriticalSection *m_pCSection;
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    MFXAutomaticCriticalSection(const MFXAutomaticCriticalSection &);
+    void operator=(const MFXAutomaticCriticalSection &);
+};
+
+} // namespace MFX
+
+#endif // __MFX_CRITICAL_SECTION_H

+ 213 - 0
plugins/obs-qsv11/libmfx/include/mfx_dispatcher.h

@@ -0,0 +1,213 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dispatcher.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_DISPATCHER_H)
+#define __MFX_DISPATCHER_H
+
+#include <mfxvideo.h>
+#include <mfxaudio.h>
+#include <mfxplugin.h>
+#include <stddef.h>
+#include "mfx_dispatcher_defs.h"
+#include "mfx_load_plugin.h"
+#include "mfxenc.h"
+#include "mfxpak.h"
+
+
+mfxStatus MFXQueryVersion(mfxSession session, mfxVersion *version);
+
+enum
+{
+    // to avoid code changing versions are just inherited
+    // from the API header file.
+    DEFAULT_API_VERSION_MAJOR   = MFX_VERSION_MAJOR,
+    DEFAULT_API_VERSION_MINOR   = MFX_VERSION_MINOR
+};
+
+//
+// declare functions' integer identifiers.
+//
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    e##func_name,
+
+enum eFunc
+{
+    eMFXInit,
+    eMFXClose,
+    eMFXQueryIMPL,
+    eMFXQueryVersion,
+    eMFXJoinSession,
+    eMFXDisjoinSession,
+    eMFXCloneSession,
+    eMFXSetPriority,
+    eMFXGetPriority,
+    eMFXInitEx,
+#include "mfx_exposed_functions_list.h"
+    eVideoFuncTotal
+};
+
+enum eAudioFunc
+{
+    eFakeAudioEnum = eMFXGetPriority,
+#include "mfxaudio_exposed_functions_list.h"
+    eAudioFuncTotal
+};
+
+// declare max buffer length for regsitry key name
+enum
+{
+    MFX_MAX_REGISTRY_KEY_NAME = 256
+};
+
+// declare the maximum DLL path
+enum
+{
+    MFX_MAX_DLL_PATH = 1024
+};
+
+// declare library's implementation types
+enum eMfxImplType
+{
+    MFX_LIB_HARDWARE            = 0,
+    MFX_LIB_SOFTWARE            = 1,
+    MFX_LIB_PSEUDO              = 2,
+
+    MFX_LIB_IMPL_TYPES
+};
+
+// declare dispatcher's version
+enum
+{
+    MFX_DISPATCHER_VERSION_MAJOR = 1,
+    MFX_DISPATCHER_VERSION_MINOR = 2
+};
+
+// declare a dispatcher's handle
+struct MFX_DISP_HANDLE
+{
+    // Default constructor
+    MFX_DISP_HANDLE(const mfxVersion requiredVersion);
+    // Destructor
+    ~MFX_DISP_HANDLE(void);
+
+    // Load the library's module
+    mfxStatus LoadSelectedDLL(const msdk_disp_char *pPath, eMfxImplType implType, mfxIMPL impl, mfxIMPL implInterface, mfxInitParam &par);
+    // Unload the library's module
+    mfxStatus UnLoadSelectedDLL(void);
+
+    // Close the handle
+    mfxStatus Close(void);
+
+    // NOTE: changing order of struct's members can make different version of
+    // dispatchers incompatible. Think of different modules (e.g. MFT filters)
+    // within a single application.
+
+    // Library's implementation type (hardware or software)
+    eMfxImplType implType;
+    // Current library's implementation (exact implementation)
+    mfxIMPL impl;
+    // Current library's VIA interface
+    mfxIMPL implInterface;
+    // Dispatcher's version. If version is 1.1 or lower, then old dispatcher's
+    // architecture is used. Otherwise it means current dispatcher's version.
+    mfxVersion dispVersion;
+    // A real handle passed to a called function
+    mfxSession session;
+    // Required API version of session initialized
+    const mfxVersion apiVersion;
+    // Actual library API version
+    mfxVersion actualApiVersion;
+    // Status of loaded dll
+    mfxStatus loadStatus;
+    // Resgistry subkey name for windows version
+    msdk_disp_char subkeyName[MFX_MAX_REGISTRY_KEY_NAME];
+    // Storage ID for windows version
+    int storageID;
+
+    // Library's module handle
+    mfxModuleHandle hModule;
+
+    MFX::MFXPluginStorage pluginHive;
+    MFX::MFXPluginFactory pluginFactory;
+
+    // function call table
+    mfxFunctionPointer callTable[eVideoFuncTotal];
+    mfxFunctionPointer callAudioTable[eAudioFuncTotal];
+
+private:
+    // Declare assignment operator and copy constructor to prevent occasional assignment
+    MFX_DISP_HANDLE(const MFX_DISP_HANDLE &);
+    MFX_DISP_HANDLE & operator = (const MFX_DISP_HANDLE &);    
+
+};
+
+// declare comparison operator
+inline
+bool operator == (const mfxVersion &one, const mfxVersion &two)
+{
+    return (one.Version == two.Version);
+
+} // bool operator == (const mfxVersion &one, const mfxVersion &two)
+
+inline
+bool operator < (const mfxVersion &one, const mfxVersion &two)
+{
+    return (one.Major == two.Major) && (one.Minor < two.Minor);
+
+} // bool operator < (const mfxVersion &one, const mfxVersion &two)
+
+inline
+bool operator <= (const mfxVersion &one, const mfxVersion &two)
+{
+    return (one == two) || (one < two);
+} // bool operator <= (const mfxVersion &one, const mfxVersion &two)
+
+
+//
+// declare a table with functions descriptions
+//
+
+typedef
+struct FUNCTION_DESCRIPTION
+{
+    // Literal function's name
+    const char *pName;
+    // API version when function appeared first time
+    mfxVersion apiVersion;
+} FUNCTION_DESCRIPTION;
+
+extern const
+FUNCTION_DESCRIPTION APIFunc[eVideoFuncTotal];
+
+extern const
+FUNCTION_DESCRIPTION APIAudioFunc[eAudioFuncTotal];
+#endif // __MFX_DISPATCHER_H

+ 85 - 0
plugins/obs-qsv11/libmfx/include/mfx_dispatcher_defs.h

@@ -0,0 +1,85 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dispatcher_defs.h
+
+\* ****************************************************************************** */
+
+#pragma once
+#include "mfxdefs.h"
+#include <cstring>
+
+#if defined(MFX_DISPATCHER_LOG)
+#include <string>
+#include <string.h>
+#endif
+
+#if defined(_WIN32) || defined(_WIN64)
+typedef wchar_t  msdk_disp_char;
+#define MSDK2WIDE(x) x
+
+#if _MSC_VER >= 1400
+    #define msdk_disp_char_cpy_s(to, to_size, from) wcscpy_s(to,to_size, from)
+#else
+    #define msdk_disp_char_cpy_s(to, to_size, from) wcscpy(to, from)
+#endif
+
+#else
+typedef char msdk_disp_char;
+//#define msdk_disp_char_cpy_s(to, to_size, from) strcpy(to, from)
+
+inline void msdk_disp_char_cpy_s(char * to, size_t to_size, const char * from)
+{
+    size_t source_len = strlen(from);
+    size_t num_chars = (to_size - 1) < source_len ? (to_size - 1) : source_len;
+    strncpy(to, from, num_chars);
+    to[num_chars] = 0;
+}
+
+#if defined(MFX_DISPATCHER_LOG)
+#define MSDK2WIDE(x) getWideString(x).c_str()
+
+inline std::wstring getWideString(const char * string)
+{
+    size_t len = strlen(string);
+    return std::wstring(string, string + len);
+}
+#else
+    #define MSDK2WIDE(x) x  
+#endif
+
+#endif
+
+#ifdef __GNUC__
+#define  sscanf_s  sscanf
+#define  swscanf_s swscanf
+#endif
+
+
+// declare library module's handle
+typedef void * mfxModuleHandle;
+
+typedef void (MFX_CDECL * mfxFunctionPointer)(void);

+ 306 - 0
plugins/obs-qsv11/libmfx/include/mfx_dispatcher_log.h

@@ -0,0 +1,306 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dispatcher_log.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_DISPATCHER_LOG_H)
+#define __MFX_DISPATCHER_LOG_H
+
+//////////////////////////////////////////////////////////////////////////
+//dispatcher log (DL) level
+#define DL_INFO                               1
+#define DL_WRN                                2
+#define DL_ERROR                              4
+#define DL_LOADED_LIBRARY                     8
+//////////////////////////////////////////////////////////////////////////
+//opcodes used only in events
+enum
+{
+    DL_EVENT_START  = 1,
+    DL_EVENT_STOP,
+    DL_EVENT_MSG
+};
+//////////////////////////////////////////////////////////////////////////
+#define DL_SINK_NULL         0
+#define DL_SINK_PRINTF       1
+#define DL_SINK_IMsgHandler  2
+
+#define MFXFOURCCTYPE() "%c%c%c%c"
+#define ZERO_OR_SPACE(value) ((0==(value)) ? '0' : (value))
+#define MFXU32TOFOURCC(mfxu32)\
+    ZERO_OR_SPACE((char)(mfxu32 & 0xFF)), \
+    ZERO_OR_SPACE((char)((mfxu32 >> 8) & 0xFF)),\
+    ZERO_OR_SPACE((char)((mfxu32 >> 16) & 0xFF)),\
+    ZERO_OR_SPACE((char)((mfxu32 >> 24) & 0xFF))
+
+#define MFXGUIDTYPE() "%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X"
+
+#define MFXGUIDTOHEX(guid)\
+    (guid)->Data[0],\
+    (guid)->Data[1],\
+    (guid)->Data[2],\
+    (guid)->Data[3],\
+    (guid)->Data[4],\
+    (guid)->Data[5],\
+    (guid)->Data[6],\
+    (guid)->Data[7],\
+    (guid)->Data[8],\
+    (guid)->Data[9],\
+    (guid)->Data[10],\
+    (guid)->Data[11],\
+    (guid)->Data[12],\
+    (guid)->Data[13],\
+    (guid)->Data[14],\
+    (guid)->Data[15]
+
+#if defined(MFX_DISPATCHER_LOG)
+
+//---------------------------setup section------------------------
+//using of formating instead of variadic macro with NULL end, 
+//leads to more flexibility in format, however constructing string 
+//with vsprintf_s is a time wasting
+#define DISPATCHER_LOG_USE_FORMATING 1
+
+//creates unique object, event guid registration, factories on heap
+//heap reduce stack allocation and reduce reservation time at startup
+//is a vital if mediasdk wont use
+#define DISPATCHER_LOG_HEAP_SINGLETONES
+
+#if defined(_WIN32) || defined(_WIN64)
+// guid for all dispatcher events
+#define DISPATCHER_LOG_EVENT_GUID L"{EB0538CC-4FEE-484d-ACEE-1182E9F37A57}"
+
+//puts a sink into listeners list
+//#define DISPATCHER_LOG_REGISTER_EVENT_PROVIDER
+
+//puts a sink into listeners list
+//#define DISPATCHER_LOG_REGISTER_FILE_WRITER
+#define DISPACTHER_LOG_FW_PATH "c:\\dispatcher.log"
+
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+#include <stdio.h>
+#include <stdarg.h>
+
+//callback interface for intercept logging messages
+class IMsgHandler
+{
+public:
+    virtual ~IMsgHandler(){}
+    virtual void Write(int level, int opcode, const char * msg, va_list argptr) = 0;
+};
+
+#if defined(_WIN32) || defined(_WIN64)
+#if  DISPATCHER_LOG_USE_FORMATING
+
+    #define DISPATCHER_LOG(lvl, opcode, str)\
+    {\
+        DispatcherLogBracketsHelper wrt(lvl,opcode);\
+        wrt.Write str;\
+    }
+#else
+    #define DISPATCHER_LOG_VA_ARGS(...) wrt.Write(__VA_ARGS__, NULL)
+    //WARNING: don't use types that occupy more that 4 bytes in memory 
+    //WARNING: don't use %s in format specifier
+    #define DISPATCHER_LOG(lvl, opcode, str) \
+    {\
+        DispatcherLogBracketsHelper wrt(lvl, opcode);\
+        DISPATCHER_LOG_VA_ARGS str;\
+    }
+#endif//DISPATCHER_LOG_USE_FORMATING
+
+#define DISPATCHER_LOG_OPERATION(operation) operation
+#else
+#define DISPATCHER_LOG(lvl, opcode, str)
+#define DISPATCHER_LOG_OPERATION(operation)
+#endif
+
+#define __name_from_line( name, line ) name ## line
+#define _name_from_line( name , line) __name_from_line( name, line ) 
+#define name_from_line( name ) _name_from_line( name, __LINE__) 
+
+
+#define DISPATCHER_LOG_AUTO(lvl, msg)\
+    DispatchLogBlockHelper name_from_line(__auto_log_)(lvl); name_from_line(__auto_log_).Write msg;
+
+#include <memory>
+#include <map>
+#include <list>
+#include <string>
+
+template <class T> 
+class DSSingleTone
+{
+public:
+    template <class TParam1>
+    inline static T & get(TParam1 par1)
+    {
+        T * pstored;
+        if (NULL == (pstored = store_or_load()))
+        {
+            return *store_or_load(new T(par1));
+        }
+        return *pstored;    
+    }
+
+    inline static T & get()
+    {
+        T * pstored;
+        if (NULL == (pstored = store_or_load()))
+        {
+            return *store_or_load(new T());
+        }
+        return *pstored;
+    }
+private:
+    //if obj == NULL, then it load 
+    //if obj != NULL then it store obj
+    inline static T * store_or_load(T * obj = NULL)
+    {
+        static std::auto_ptr<T> instance;
+        if (NULL != obj)
+        {
+            instance.reset(obj);
+        }
+        return instance.get();
+    }
+};
+
+class DispatchLog 
+    : public DSSingleTone<DispatchLog>
+{
+    friend class DSSingleTone<DispatchLog>;
+    std::list<IMsgHandler*>m_Recepients;
+    int m_DispatcherLogSink;
+
+public:
+    //sets current sink
+    void   SetSink(int nsink, IMsgHandler *pHandler);
+    void   AttachSink(int nsink, IMsgHandler *pHandler);
+    void   DetachSink(int nsink, IMsgHandler *pHandler);
+    void   ExchangeSink(int nsink, IMsgHandler *pOld, IMsgHandler *pNew);
+    void   DetachAllSinks();
+    void   Write(int level, int opcode, const char * msg, va_list argptr);
+    
+protected:
+    DispatchLog();
+};
+
+//allows to push arguments on the stack without declaring them as function parameters
+struct  DispatcherLogBracketsHelper
+{
+    int  m_level;
+    int  m_opcode;
+    DispatcherLogBracketsHelper(int level, int opcode)
+        :m_level(level)
+        ,m_opcode(opcode)
+    {
+    }
+    void Write(const char * str, ...);
+} ;
+
+//auto log on ctor dtor
+struct DispatchLogBlockHelper
+{
+    int  m_level;
+    void Write(const char * str, ...);
+    DispatchLogBlockHelper (int level)
+        : m_level(level)
+    {
+    }
+    ~DispatchLogBlockHelper();
+};
+
+//----utility sinks-----
+#if defined(_WIN32) || defined(_WIN64)
+#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+class ETWHandlerFactory
+    : public DSSingleTone<ETWHandlerFactory>
+{
+    friend class DSSingleTone<ETWHandlerFactory>;
+    typedef std::map<std::wstring, IMsgHandler*> _storage_type;
+    _storage_type m_storage;
+
+public:
+    ~ETWHandlerFactory();
+    IMsgHandler *GetSink(const wchar_t* sguid = DISPATCHER_LOG_EVENT_GUID);
+
+protected:
+    ETWHandlerFactory(){}
+};
+#endif
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+#if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER)
+class FileSink 
+    : public DSSingleTone<FileSink>
+    , public IMsgHandler
+{
+    friend class DSSingleTone<FileSink>;
+public:
+    virtual void Write(int level, int opcode, const char * msg, va_list argptr);
+    ~FileSink()
+    {
+        if (NULL != m_hdl)
+            fclose(m_hdl);
+    }
+private:
+    FILE * m_hdl;
+    FileSink(const std::string & log_file)
+    {
+#if defined(_WIN32) || defined(_WIN64)
+        fopen_s(&m_hdl, log_file.c_str(), "a");
+#else
+        m_hdl = fopen(log_file.c_str(), "a");
+#endif
+    }
+    
+};
+#endif
+
+//-----utility functions
+//since they are not called outside of macro we can define them here
+std::string DispatcherLog_GetMFXImplString(int impl);
+const char *DispatcherLog_GetMFXStatusString(int sts);
+
+#else // !defined(MFX_DISPATCHER_LOG)
+
+    #define DISPATCHER_LOG(level, opcode, message)
+    #define DISPATCHER_LOG_AUTO(level, message)
+    #define DISPATCHER_LOG_OPERATION(operation) 
+
+#endif// !defined(MFX_DISPATCHER_LOG)
+
+
+#define DISPATCHER_LOG_INFO(msg)    DISPATCHER_LOG(DL_INFO, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_WRN(msg)     DISPATCHER_LOG(DL_WRN, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_ERROR(msg)   DISPATCHER_LOG(DL_ERROR, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_LIBRARY(msg) DISPATCHER_LOG(DL_LOADED_LIBRARY, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_BLOCK(msg)   DISPATCHER_LOG_AUTO(DL_INFO, msg)
+
+#endif // !defined(__MFX_DISPATCHER_LOG_H)

+ 210 - 0
plugins/obs-qsv11/libmfx/include/mfx_dxva2_device.h

@@ -0,0 +1,210 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dxva2_device.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_DXVA2_DEVICE_H)
+#define __MFX_DXVA2_DEVICE_H
+
+#if defined(_WIN32) || defined(_WIN64)
+#include <windows.h>
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+#include <mfxdefs.h>
+
+#ifdef DXVA2DEVICE_LOG
+#include <stdio.h>
+#define DXVA2DEVICE_TRACE(expr) printf expr;
+#define DXVA2DEVICE_TRACE_OPERATION(expr) expr;
+#else
+#define DXVA2DEVICE_TRACE(expr)
+#define DXVA2DEVICE_TRACE_OPERATION(expr) 
+#endif
+
+namespace MFX
+{
+
+class DXDevice
+{
+public:
+    // Default constructor
+    DXDevice(void);
+    // Destructor
+    virtual
+    ~DXDevice(void) = 0;
+
+    // Initialize device using DXGI 1.1 or VAAPI interface
+    virtual
+    bool Init(const mfxU32 adapterNum) = 0;
+
+    // Obtain graphic card's parameter
+    mfxU32 GetVendorID(void) const;
+    mfxU32 GetDeviceID(void) const;
+    mfxU64 GetDriverVersion(void) const;
+    mfxU64 GetLUID(void) const;
+
+    // Provide the number of available adapters
+    mfxU32 GetAdapterCount(void) const;
+
+    // Close the object
+    virtual
+    void Close(void);
+
+    // Load the required DLL module
+    void LoadDLLModule(const wchar_t *pModuleName);
+
+protected:
+
+    // Free DLL module
+    void UnloadDLLModule(void);
+
+#if defined(_WIN32) || defined(_WIN64)
+    // Handle to the DLL library
+    HMODULE m_hModule;
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+    // Number of adapters available
+    mfxU32 m_numAdapters;
+
+    // Vendor ID
+    mfxU32 m_vendorID;
+    // Device ID
+    mfxU32 m_deviceID;
+    // x.x.x.x each x of two bytes
+    mfxU64 m_driverVersion;
+    // LUID
+    mfxU64 m_luid;
+
+private:
+    // unimplemented by intent to make this class and its descendants non-copyable
+    DXDevice(const DXDevice &);
+    void operator=(const DXDevice &);
+};
+
+#if defined(_WIN32) || defined(_WIN64)
+class D3D9Device : public DXDevice
+{
+public:
+    // Default constructor
+    D3D9Device(void);
+    // Destructor
+    virtual
+        ~D3D9Device(void);
+
+    // Initialize device using D3D v9 interface
+    virtual
+        bool Init(const mfxU32 adapterNum);
+
+    // Close the object
+    virtual
+        void Close(void);
+
+protected:
+
+    // Pointer to the D3D v9 interface
+    void *m_pD3D9;
+    // Pointer to the D3D v9 extended interface
+    void *m_pD3D9Ex;
+
+};
+
+class DXGI1Device : public DXDevice
+{
+public:
+    // Default constructor
+    DXGI1Device(void);
+    // Destructor
+    virtual
+    ~DXGI1Device(void);
+
+    // Initialize device
+    virtual
+    bool Init(const mfxU32 adapterNum);
+
+    // Close the object
+    virtual
+    void Close(void);
+
+protected:
+
+    // Pointer to the DXGI1 factory
+    void *m_pDXGIFactory1;
+    // Pointer to the current DXGI1 adapter
+    void *m_pDXGIAdapter1;
+
+};
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+class DXVA2Device
+{
+public:
+    // Default constructor
+    DXVA2Device(void);
+    // Destructor
+    ~DXVA2Device(void);
+
+    // Initialize device using D3D v9 interface
+    bool InitD3D9(const mfxU32 adapterNum);
+
+    // Initialize device using DXGI 1.1 interface
+    bool InitDXGI1(const mfxU32 adapterNum);
+
+    // Obtain graphic card's parameter
+    mfxU32 GetVendorID(void) const;
+    mfxU32 GetDeviceID(void) const;
+    mfxU64 GetDriverVersion(void) const;
+
+    // Provide the number of available adapters
+    mfxU32 GetAdapterCount(void) const;
+
+    void Close(void);
+
+protected:
+
+    // Get vendor & device IDs by alternative way (D3D9 in Remote Desktop sessions)
+    void UseAlternativeWay(const D3D9Device *pD3D9Device);
+
+    // Number of adapters available
+    mfxU32 m_numAdapters;
+
+    // Vendor ID
+    mfxU32 m_vendorID;
+    // Device ID
+    mfxU32 m_deviceID;
+    //x.x.x.x
+    mfxU64 m_driverVersion;
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    DXVA2Device(const DXVA2Device &);
+    void operator=(const DXVA2Device &);
+};
+
+} // namespace MFX
+
+#endif // __MFX_DXVA2_DEVICE_H

+ 142 - 0
plugins/obs-qsv11/libmfx/include/mfx_exposed_functions_list.h

@@ -0,0 +1,142 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_exposed_functions_list.h
+
+\* ****************************************************************************** */
+
+//
+// WARNING:
+// this file doesn't contain an include guard by intension.
+// The file may be included into a source file many times.
+// That is why this header doesn't contain any include directive.
+// Please, do no try to fix it.
+//
+
+
+
+// Use define API_VERSION to set the API of functions listed further
+// When new functions are added new section with functions declarations must be started with updated define
+
+//
+// API version 1.0 functions
+//
+
+// API version where a function is added. Minor value should precedes the major value
+#define API_VERSION {{0, 1}}
+
+// CORE interface functions
+FUNCTION(mfxStatus, MFXVideoCORE_SetBufferAllocator, (mfxSession session, mfxBufferAllocator *allocator), (session, allocator))
+FUNCTION(mfxStatus, MFXVideoCORE_SetFrameAllocator, (mfxSession session, mfxFrameAllocator *allocator), (session, allocator))
+FUNCTION(mfxStatus, MFXVideoCORE_SetHandle, (mfxSession session, mfxHandleType type, mfxHDL hdl), (session, type, hdl))
+FUNCTION(mfxStatus, MFXVideoCORE_GetHandle, (mfxSession session, mfxHandleType type, mfxHDL *hdl), (session, type, hdl))
+
+FUNCTION(mfxStatus, MFXVideoCORE_SyncOperation, (mfxSession session, mfxSyncPoint syncp, mfxU32 wait), (session, syncp, wait))
+
+// ENCODE interface functions
+FUNCTION(mfxStatus, MFXVideoENCODE_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out))
+FUNCTION(mfxStatus, MFXVideoENCODE_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request))
+FUNCTION(mfxStatus, MFXVideoENCODE_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus, MFXVideoENCODE_GetVideoParam, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_GetEncodeStat, (mfxSession session, mfxEncodeStat *stat), (session, stat))
+FUNCTION(mfxStatus, MFXVideoENCODE_EncodeFrameAsync, (mfxSession session, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp), (session, ctrl, surface, bs, syncp))
+
+// DECODE interface functions
+FUNCTION(mfxStatus, MFXVideoDECODE_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out))
+FUNCTION(mfxStatus, MFXVideoDECODE_DecodeHeader, (mfxSession session, mfxBitstream *bs, mfxVideoParam *par), (session, bs, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request))
+FUNCTION(mfxStatus, MFXVideoDECODE_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus, MFXVideoDECODE_GetVideoParam, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_GetDecodeStat, (mfxSession session, mfxDecodeStat *stat), (session, stat))
+FUNCTION(mfxStatus, MFXVideoDECODE_SetSkipMode, (mfxSession session, mfxSkipMode mode), (session, mode))
+FUNCTION(mfxStatus, MFXVideoDECODE_GetPayload, (mfxSession session, mfxU64 *ts, mfxPayload *payload), (session, ts, payload))
+FUNCTION(mfxStatus, MFXVideoDECODE_DecodeFrameAsync, (mfxSession session, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp), (session, bs, surface_work, surface_out, syncp))
+
+// VPP interface functions
+FUNCTION(mfxStatus, MFXVideoVPP_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out))
+FUNCTION(mfxStatus, MFXVideoVPP_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request))
+FUNCTION(mfxStatus, MFXVideoVPP_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus, MFXVideoVPP_GetVideoParam, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_GetVPPStat, (mfxSession session, mfxVPPStat *stat), (session, stat))
+FUNCTION(mfxStatus, MFXVideoVPP_RunFrameVPPAsync, (mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp), (session, in, out, aux, syncp))
+
+#undef API_VERSION
+
+//
+// API version 1.1 functions
+//
+
+#define API_VERSION {{1, 1}}
+
+FUNCTION(mfxStatus, MFXVideoUSER_Register, (mfxSession session, mfxU32 type, const mfxPlugin *par), (session, type, par))
+FUNCTION(mfxStatus, MFXVideoUSER_Unregister, (mfxSession session, mfxU32 type), (session, type))
+FUNCTION(mfxStatus, MFXVideoUSER_ProcessFrameAsync, (mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp), (session, in, in_num, out, out_num, syncp))
+
+#undef API_VERSION
+
+//
+// API version 1.10 functions
+//
+
+#define API_VERSION {{10, 1}}
+
+FUNCTION(mfxStatus, MFXVideoENC_Query,(mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session,in,out))
+FUNCTION(mfxStatus, MFXVideoENC_QueryIOSurf,(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session,par,request))
+FUNCTION(mfxStatus, MFXVideoENC_Init,(mfxSession session, mfxVideoParam *par), (session,par))
+FUNCTION(mfxStatus, MFXVideoENC_Reset,(mfxSession session, mfxVideoParam *par), (session,par))
+FUNCTION(mfxStatus, MFXVideoENC_Close,(mfxSession session),(session))
+FUNCTION(mfxStatus, MFXVideoENC_ProcessFrameAsync,(mfxSession session, mfxENCInput *in, mfxENCOutput *out, mfxSyncPoint *syncp),(session,in,out,syncp))
+
+FUNCTION(mfxStatus, MFXVideoVPP_RunFrameVPPAsyncEx, (mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *work, mfxFrameSurface1 **out, mfxSyncPoint *syncp), (session, in, work, out, syncp))
+
+#undef API_VERSION
+
+#define API_VERSION {{13, 1}}
+
+FUNCTION(mfxStatus, MFXVideoPAK_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out))
+FUNCTION(mfxStatus, MFXVideoPAK_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request))
+FUNCTION(mfxStatus, MFXVideoPAK_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoPAK_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoPAK_Close, (mfxSession session), (session))
+FUNCTION(mfxStatus, MFXVideoPAK_ProcessFrameAsync, (mfxSession session, mfxPAKInput *in, mfxPAKOutput *out, mfxSyncPoint *syncp), (session, in, out, syncp))
+
+#undef API_VERSION
+
+#define API_VERSION {{14, 1}}
+
+// FUNCTION(mfxStatus, MFXInitEx, (mfxInitParam par, mfxSession session), (par, session))
+FUNCTION(mfxStatus, MFXDoWork, (mfxSession session), (session))
+
+#undef API_VERSION

+ 161 - 0
plugins/obs-qsv11/libmfx/include/mfx_library_iterator.h

@@ -0,0 +1,161 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_library_iterator.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_LIBRARY_ITERATOR_H)
+#define __MFX_LIBRARY_ITERATOR_H
+
+
+#include <mfxvideo.h>
+#include "mfx_win_reg_key.h"
+#include "mfx_dispatcher.h"
+
+#if !defined(_WIN32) && !defined(_WIN64)
+struct mfx_disp_adapters
+{
+    mfxU32 vendor_id;
+    mfxU32 device_id;
+};
+
+#ifndef __APPLE__
+#define MFX_SO_BASE_NAME_LEN 15 // sizeof("libmfxhw32-p.so") = 15
+#else
+
+#define MFX_SO_BASE_NAME_LEN 16 // sizeof("libmfxhw64.dylib") = 16
+#endif
+
+#define MFX_MIN_REAL_LIBNAME MFX_SO_BASE_NAME_LEN + 4 // sizeof("libmfxhw32-p.so.0.0") >= 19
+#define MFX_MAX_REAL_LIBNAME MFX_MIN_REAL_LIBNAME + 8 // sizeof("libmfxhw32-p.so.<mj>.<mn>") <= 27, max(sizeof(<mj>))=sizeof(0xFFFF) = sizeof(65535) = 5
+
+struct mfx_libs
+{
+    char name[MFX_MAX_REAL_LIBNAME+1];
+    mfxVersion version;
+};
+#endif
+
+namespace MFX
+{
+
+// declare desired storage ID
+#if defined(_WIN32) || defined(_WIN64)
+enum
+{
+    MFX_UNKNOWN_KEY             = -1,
+    MFX_CURRENT_USER_KEY        = 0,
+    MFX_LOCAL_MACHINE_KEY       = 1,
+    MFX_APP_FOLDER              = 2,
+
+    MFX_STORAGE_ID_FIRST    = MFX_CURRENT_USER_KEY,
+    MFX_STORAGE_ID_LAST     = MFX_LOCAL_MACHINE_KEY
+};
+#else
+enum
+{
+    MFX_UNKNOWN_KEY     = -1,
+    MFX_STORAGE_ID_OPT  = 0, // storage is: /opt/intel
+    MFX_APP_FOLDER      = 1,
+
+    MFX_STORAGE_ID_FIRST   =  MFX_STORAGE_ID_OPT,
+    MFX_STORAGE_ID_LAST    = MFX_STORAGE_ID_OPT
+};
+#endif
+
+// Try to initialize using given implementation type. Select appropriate type automatically in case of MFX_IMPL_VIA_ANY.
+// Params: adapterNum - in, pImplInterface - in/out, pVendorID - out, pDeviceID - out
+mfxStatus SelectImplementationType(const mfxU32 adapterNum, mfxIMPL *pImplInterface, mfxU32 *pVendorID, mfxU32 *pDeviceID);
+
+class MFXLibraryIterator
+{
+public:
+    // Default constructor
+    MFXLibraryIterator(void);
+    // Destructor
+    ~MFXLibraryIterator(void);
+
+    // Initialize the iterator
+    mfxStatus Init(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID);
+
+    // Get the next library path
+    mfxStatus SelectDLLVersion(msdk_disp_char *pPath, size_t pathSize, 
+                               eMfxImplType *pImplType, mfxVersion minVersion);
+
+    // Return interface type on which Intel adapter was found (if any): D3D9 or D3D11
+    mfxIMPL GetImplementationType(); 
+
+    // Retrun registry subkey name on which dll was selected after sucesfull call to selectDllVesion
+    bool GetSubKeyName(msdk_disp_char *subKeyName, size_t length) const;
+
+    int  GetStorageID() const { return m_StorageID; }
+protected:
+
+    // Release the iterator
+    void Release(void);
+
+    // Initialize the registry iterator
+    mfxStatus InitRegistry(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID);
+    // Initialize the app folder iterator
+    mfxStatus InitFolder(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, const msdk_disp_char * path);
+
+
+    eMfxImplType m_implType;                                    // Required library implementation 
+    mfxIMPL m_implInterface;                                    // Required interface (D3D9, D3D11)
+
+    mfxU32 m_vendorID;                                          // (mfxU32) property of used graphic card
+    mfxU32 m_deviceID;                                          // (mfxU32) property of used graphic card
+    bool   m_bIsSubKeyValid;
+    wchar_t m_SubKeyName[MFX_MAX_REGISTRY_KEY_NAME];            // registry subkey for selected module loaded 
+    int    m_StorageID;
+    
+#if defined(_WIN32) || defined(_WIN64)
+    WinRegKey m_baseRegKey;                                     // (WinRegKey) main registry key    
+
+    mfxU32 m_lastLibIndex;                                      // (mfxU32) index of previously returned library
+    mfxU32 m_lastLibMerit;                                      // (mfxU32) merit of previously returned library
+#else
+    int                       m_lastLibIndex;                   // (mfxU32) index of previously returned library
+
+    mfxU32                    m_adapters_num;
+    struct mfx_disp_adapters* m_adapters;
+    int                       m_selected_adapter;
+    mfxU32                    m_libs_num;
+    struct mfx_libs*          m_libs;
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+    msdk_disp_char  m_path[260];
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    MFXLibraryIterator(const MFXLibraryIterator &);
+    void operator=(const MFXLibraryIterator &);
+};
+
+} // namespace MFX
+
+#endif // __MFX_LIBRARY_ITERATOR_H

+ 59 - 0
plugins/obs-qsv11/libmfx/include/mfx_load_dll.h

@@ -0,0 +1,59 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_load_dll.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_LOAD_DLL_H)
+#define __MFX_LOAD_DLL_H
+
+#include "mfx_dispatcher.h"
+
+namespace MFX
+{
+
+
+    //
+    // declare DLL loading routines
+    //
+
+    mfxStatus mfx_get_rt_dll_name(msdk_disp_char *pPath, size_t pathSize);
+    mfxStatus mfx_get_default_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType);
+    mfxStatus mfx_get_default_plugin_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType);
+
+    mfxStatus mfx_get_default_audio_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType);
+    
+
+    mfxModuleHandle mfx_dll_load(const msdk_disp_char *file_name);
+    //increments reference counter
+    mfxModuleHandle mfx_get_dll_handle(const msdk_disp_char *file_name);
+    mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *func_name);
+    bool mfx_dll_free(mfxModuleHandle handle);
+
+} // namespace MFX
+
+#endif  // __MFX_LOAD_DLL_H

+ 93 - 0
plugins/obs-qsv11/libmfx/include/mfx_load_plugin.h

@@ -0,0 +1,93 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_load_plugin.h
+
+\* ****************************************************************************** */
+
+#pragma once
+#include "mfxplugin.h"
+#include "mfx_dispatcher_defs.h"
+#include "mfx_plugin_hive.h"
+
+namespace MFX
+{
+    typedef mfxStatus (MFX_CDECL *CreatePluginPtr_t)(mfxPluginUID uid, mfxPlugin* plugin);
+
+    class PluginModule
+    {
+        mfxModuleHandle mHmodule;
+        CreatePluginPtr_t mCreatePluginPtr;
+        msdk_disp_char mPath[MAX_PLUGIN_PATH];
+        
+    public:
+        PluginModule();
+        PluginModule(const msdk_disp_char * path);
+        PluginModule(const PluginModule & that) ;
+        PluginModule & operator = (const PluginModule & that);
+        bool Create(mfxPluginUID guid, mfxPlugin&);
+        ~PluginModule(void);
+
+    private:
+        void Tidy();
+    };
+
+    class MFXPluginFactory {
+        struct FactoryRecord {
+            mfxPluginParam plgParams;
+            PluginModule module;
+            mfxPlugin plugin;
+            FactoryRecord () {}
+            FactoryRecord(const mfxPluginParam &plgParams,
+                          PluginModule &module,
+                          mfxPlugin plugin) 
+                : plgParams(plgParams) 
+                , module(module)
+                , plugin(plugin) {
+            }
+        };
+        MFXVector<FactoryRecord> mPlugins;
+        mfxU32 nPlugins;
+        mfxSession mSession;
+    public:
+        MFXPluginFactory(mfxSession session);
+        void Close();
+        mfxStatus Create(const PluginDescriptionRecord &);
+        bool Destroy(const mfxPluginUID &);
+        
+        ~MFXPluginFactory();
+    protected:
+        void DestroyPlugin( FactoryRecord & );
+        static bool RunVerification( const mfxPlugin & plg, const PluginDescriptionRecord &dsc, mfxPluginParam &pluginParams );
+        static bool VerifyEncoder( const mfxVideoCodecPlugin &videoCodec );
+        static bool VerifyAudioEncoder( const mfxAudioCodecPlugin &audioCodec );
+        static bool VerifyEnc( const mfxVideoCodecPlugin &videoEnc );
+        static bool VerifyVpp( const mfxVideoCodecPlugin &videoCodec );
+        static bool VerifyDecoder( const mfxVideoCodecPlugin &videoCodec );
+        static bool VerifyAudioDecoder( const mfxAudioCodecPlugin &audioCodec );
+        static bool VerifyCodecCommon( const mfxVideoCodecPlugin & Video );
+    };
+}

+ 132 - 0
plugins/obs-qsv11/libmfx/include/mfx_plugin_hive.h

@@ -0,0 +1,132 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_plugin_hive.h
+
+\* ****************************************************************************** */
+
+#pragma once
+
+#include "mfx_dispatcher_defs.h"
+#include "mfxplugin.h"
+#include "mfx_win_reg_key.h"
+#include "mfx_vector.h"
+#include <string.h>
+#include <memory>
+#include <stdio.h>
+
+struct MFX_DISP_HANDLE;
+
+namespace MFX {
+
+    enum 
+    {
+        MAX_PLUGIN_PATH = 4096
+    };
+    
+    enum
+    {
+        MAX_PLUGIN_NAME = 4096
+    };
+
+    inline bool operator == (const mfxPluginUID &lhs, const mfxPluginUID & rhs) 
+    {
+        return !memcmp(lhs.Data, rhs.Data, sizeof(mfxPluginUID));
+    }
+    
+    inline bool operator != (const mfxPluginUID &lhs, const mfxPluginUID & rhs) 
+    {
+        return !(lhs == rhs);
+    }
+#ifdef _WIN32
+    //warning C4351: new behavior: elements of array 'MFX::PluginDescriptionRecord::sName' will be default initialized
+    #pragma warning (disable: 4351)
+#endif
+    class PluginDescriptionRecord :  public mfxPluginParam 
+    {
+    public:
+        msdk_disp_char sPath[MAX_PLUGIN_PATH];
+        char sName[MAX_PLUGIN_NAME];
+        //used for FS plugins that has poor description
+        bool onlyVersionRegistered;
+        bool Default;
+        PluginDescriptionRecord()
+            : mfxPluginParam()
+            , sPath()
+            , sName()
+            , onlyVersionRegistered()
+            , Default()
+        {
+        }
+    };
+
+    typedef MFXVector<PluginDescriptionRecord> MFXPluginStorage;
+
+    class  MFXPluginStorageBase : public MFXPluginStorage 
+    {
+    protected:
+        mfxVersion mCurrentAPIVersion;
+    protected:
+        MFXPluginStorageBase(mfxVersion currentAPIVersion) 
+            : mCurrentAPIVersion(currentAPIVersion)
+        {
+        }
+        void ConvertAPIVersion( mfxU32 APIVersion, PluginDescriptionRecord &descriptionRecord) const
+        {
+            descriptionRecord.APIVersion.Minor = static_cast<mfxU16> (APIVersion & 0x0ff);
+            descriptionRecord.APIVersion.Major = static_cast<mfxU16> (APIVersion >> 8);
+        }
+    };
+
+    //populated from registry
+    class MFXPluginsInHive : public MFXPluginStorageBase
+    {
+    public:
+        MFXPluginsInHive(int mfxStorageID, const msdk_disp_char *msdkLibSubKey, mfxVersion currentAPIVersion);
+    };
+
+    //plugins are loaded from FS close to executable
+    class MFXPluginsInFS : public MFXPluginStorageBase
+    {
+        bool mIsVersionParsed;
+        bool mIsAPIVersionParsed;
+    public:
+        MFXPluginsInFS(mfxVersion currentAPIVersion);
+    private:
+        bool ParseFile(FILE * f, PluginDescriptionRecord & des);
+        bool ParseKVPair( msdk_disp_char *key, msdk_disp_char * value, PluginDescriptionRecord & des);
+    };
+
+
+    //plugins are loaded from FS close to Runtime library
+    class MFXDefaultPlugins : public MFXPluginStorageBase
+    {
+    public:
+        MFXDefaultPlugins(mfxVersion currentAPIVersion, MFX_DISP_HANDLE * hdl, int implType);
+    private:
+    };
+
+}

+ 220 - 0
plugins/obs-qsv11/libmfx/include/mfx_vector.h

@@ -0,0 +1,220 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_vector.h
+
+\* ****************************************************************************** */
+
+#pragma once
+#include "mfxstructures.h"
+#include <exception>
+
+namespace MFX 
+{
+    template <class T>
+    class iterator_tmpl 
+    {
+        template <class U> friend class MFXVector;
+        mfxU32 mIndex;
+        T* mRecords;
+        iterator_tmpl(mfxU32 index , T * records) 
+            : mIndex (index)
+            , mRecords(records)
+        {}
+    public:
+        iterator_tmpl() 
+            : mIndex ()
+            , mRecords() 
+        {}
+        bool  operator ==(const iterator_tmpl<T> & that )const 
+        {
+            return mIndex == that.mIndex;
+        }
+        bool  operator !=(const iterator_tmpl<T> & that )const 
+        {
+            return mIndex != that.mIndex;
+        }
+        mfxU32 operator - (const iterator_tmpl<T> &that) const 
+        {
+            return mIndex - that.mIndex;
+        }
+        iterator_tmpl<T> & operator ++() 
+        {
+            mIndex++;
+            return * this;
+        }
+        iterator_tmpl<T> & operator ++(int) 
+        {
+            mIndex++;
+            return * this;
+        }
+        T & operator *() 
+        {
+            return mRecords[mIndex];
+        }
+        T * operator ->() 
+        {
+            return mRecords + mIndex;
+        }
+    };
+
+    class MFXVectorRangeError : public std::exception
+    {
+    };
+
+    template <class T>
+    class MFXVector  
+    {
+        T*      mRecords;
+        mfxU32  mNrecords;
+    public:
+        MFXVector()
+            : mRecords()
+            , mNrecords()
+        {}
+        MFXVector(const MFXVector & rhs)
+            : mRecords()
+            , mNrecords()
+        {
+            insert(end(), rhs.begin(), rhs.end());
+        }
+        MFXVector & operator = (const MFXVector & rhs)
+        {
+            if (this != &rhs) 
+            {
+                clear();
+                insert(end(), rhs.begin(), rhs.end());
+            }
+            return *this;
+        }
+        virtual ~MFXVector ()
+        {
+            clear();
+        }
+        typedef iterator_tmpl<T> iterator;
+
+        iterator begin() const 
+        {
+            return iterator(0u, mRecords);
+        }
+        iterator end() const 
+        {
+            return iterator(mNrecords, mRecords);
+        }
+        void insert(iterator where, iterator beg_iter, iterator end_iter) 
+        {
+            mfxU32 elementsToInsert = (end_iter - beg_iter);
+            if (!elementsToInsert)
+            {
+                return;
+            }
+            if (where.mIndex > mNrecords)
+            {
+                throw MFXVectorRangeError();
+            }
+
+            T *newRecords = new T[mNrecords + elementsToInsert]();
+            mfxU32 i = 0;
+            
+            // save left
+            for (; i < where.mIndex; i++) 
+            {
+                newRecords[i] = mRecords[i];
+            }
+            // insert
+            for (; beg_iter != end_iter; beg_iter++, i++) 
+            {
+                newRecords[i] = *beg_iter;
+            }
+    
+            //save right
+            for (; i < mNrecords + elementsToInsert; i++) 
+            {
+                newRecords[i] = mRecords[i - elementsToInsert];
+            }
+
+            delete [] mRecords;
+
+            mRecords = newRecords;
+            mNrecords = i;
+        }
+        T& operator [] (mfxU32 idx) 
+        {
+          return mRecords[idx];
+        }
+        void push_back(const T& obj) 
+        {
+            T *newRecords = new T[mNrecords + 1]();
+            mfxU32 i = 0;
+            for (; i <mNrecords; i++) 
+            {
+                newRecords[i] = mRecords[i];
+            }
+            newRecords[i] = obj;
+            delete [] mRecords;
+
+            mRecords = newRecords;
+            mNrecords = i + 1;
+            
+        }
+        void erase (iterator at) 
+        {
+            if (at.mIndex >= mNrecords)
+            {
+                throw MFXVectorRangeError();
+            }
+            mNrecords--; 
+            mfxU32 i = at.mIndex;
+            for (; i != mNrecords; i++)
+            {
+                mRecords[i] = mRecords[i+1];
+            }
+            //destroy last element
+            mRecords[i] = T();
+        }
+        void resize(mfxU32 nSize) 
+        {
+            T * newRecords = new T[nSize]();
+            for (mfxU32 i = 0; i <mNrecords; i++) 
+            {
+                newRecords[i] = mRecords[i];
+            }
+            delete [] mRecords;
+            mRecords = newRecords;
+            mNrecords = nSize;
+        }
+        mfxU32 size() const 
+        {
+            return mNrecords;
+        }
+        void clear() 
+        {
+            delete [] mRecords;
+            mRecords = 0;
+            mNrecords = 0;
+        }
+    };
+}

+ 116 - 0
plugins/obs-qsv11/libmfx/include/mfx_win_reg_key.h

@@ -0,0 +1,116 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_win_reg_key.h
+
+\* ****************************************************************************** */
+
+#if !defined(__MFX_WIN_REG_KEY_H)
+#define __MFX_WIN_REG_KEY_H
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#include <windows.h>
+#include "mfxplugin.h"
+#include "mfx_dispatcher_log.h"
+
+namespace MFX {
+
+template<class T> struct RegKey{};
+template<> struct RegKey<bool>{enum {type = REG_DWORD};};
+template<> struct RegKey<mfxU32>{enum {type = REG_DWORD};};
+template<> struct RegKey<mfxPluginUID>{enum {type = REG_BINARY};};
+template<> struct RegKey<mfxVersion>{enum {type = REG_DWORD};};
+template<> struct RegKey<char*>{enum {type = REG_SZ};};
+template<> struct RegKey<wchar_t*>{enum {type = REG_SZ};};
+
+
+class WinRegKey
+{
+public:
+    // Default constructor
+    WinRegKey(void);
+    // Destructor
+    ~WinRegKey(void);
+
+    // Open a registry key
+    bool Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired);
+    bool Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired);
+
+    // Query value
+    bool QueryInfo(LPDWORD lpcSubkeys);
+
+    bool QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData);
+    bool Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData);
+
+    bool Query(const wchar_t *pValueName, wchar_t *pData, mfxU32 &nData) {
+        DWORD dw = (DWORD)nData;
+        if (!Query(pValueName, RegKey<wchar_t*>::type, (LPBYTE)pData, &dw)){
+            return false;
+        }
+        nData = dw;
+        return true;
+    }
+
+    // Enumerate value names
+    bool EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType);
+    bool EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName);
+
+protected:
+
+    // Release the object
+    void Release(void);
+
+    HKEY m_hKey;                                                // (HKEY) handle to the opened key
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    WinRegKey(const WinRegKey &);
+    void operator=(const WinRegKey &);
+
+};
+
+
+template<class T>
+inline bool QueryKey(WinRegKey & key, const wchar_t *pValueName, T &data ) {
+    DWORD size = sizeof(data);
+    return key.Query(pValueName, RegKey<T>::type, (LPBYTE) &data, &size);
+}
+
+template<>
+inline bool QueryKey<bool>(WinRegKey & key, const wchar_t *pValueName, bool &data ) {
+    mfxU32 value = 0;
+    bool bRes = QueryKey(key, pValueName, value);
+    data = (1 == value);
+    return bRes;
+}
+
+
+} // namespace MFX
+
+#endif // #if defined(_WIN32) || defined(_WIN64)
+
+#endif // __MFX_WIN_REG_KEY_H

+ 81 - 0
plugins/obs-qsv11/libmfx/include/mfxaudio_exposed_functions_list.h

@@ -0,0 +1,81 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxaudio_exposed_function_list.h
+
+\* ****************************************************************************** */
+
+//
+// WARNING:
+// this file doesn't contain an include guard by intension.
+// The file may be included into a source file many times.
+// That is why this header doesn't contain any include directive.
+// Please, do no try to fix it.
+//
+
+//
+// API version 1.8 functions
+//
+
+// Minor value should precedes the major value
+#define API_VERSION {{8, 1}}
+
+// CORE interface functions
+FUNCTION(mfxStatus, MFXAudioCORE_SyncOperation, (mfxSession session, mfxSyncPoint syncp, mfxU32 wait), (session, syncp, wait))
+
+// ENCODE interface functions
+FUNCTION(mfxStatus, MFXAudioENCODE_Query, (mfxSession session, mfxAudioParam *in, mfxAudioParam *out), (session, in, out))
+FUNCTION(mfxStatus, MFXAudioENCODE_QueryIOSize, (mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request), (session, par, request))
+FUNCTION(mfxStatus, MFXAudioENCODE_Init, (mfxSession session, mfxAudioParam *par), (session, par))
+FUNCTION(mfxStatus, MFXAudioENCODE_Reset, (mfxSession session, mfxAudioParam *par), (session, par))
+FUNCTION(mfxStatus, MFXAudioENCODE_Close, (mfxSession session), (session))
+FUNCTION(mfxStatus, MFXAudioENCODE_GetAudioParam, (mfxSession session, mfxAudioParam *par), (session, par))
+FUNCTION(mfxStatus, MFXAudioENCODE_EncodeFrameAsync, (mfxSession session, mfxAudioFrame *frame, mfxBitstream *buffer_out, mfxSyncPoint *syncp), (session, frame, buffer_out, syncp))
+
+// DECODE interface functions
+FUNCTION(mfxStatus, MFXAudioDECODE_Query, (mfxSession session, mfxAudioParam *in, mfxAudioParam *out), (session, in, out))
+FUNCTION(mfxStatus, MFXAudioDECODE_DecodeHeader, (mfxSession session, mfxBitstream *bs, mfxAudioParam *par), (session, bs, par))
+FUNCTION(mfxStatus, MFXAudioDECODE_Init, (mfxSession session, mfxAudioParam *par), (session, par))
+FUNCTION(mfxStatus, MFXAudioDECODE_Reset, (mfxSession session, mfxAudioParam *par), (session, par))
+FUNCTION(mfxStatus, MFXAudioDECODE_Close, (mfxSession session), (session))
+FUNCTION(mfxStatus, MFXAudioDECODE_QueryIOSize, (mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request), (session, par, request))
+FUNCTION(mfxStatus, MFXAudioDECODE_GetAudioParam, (mfxSession session, mfxAudioParam *par), (session, par))
+FUNCTION(mfxStatus, MFXAudioDECODE_DecodeFrameAsync, (mfxSession session, mfxBitstream *bs, mfxAudioFrame *frame_out, mfxSyncPoint *syncp), (session, bs, frame_out, syncp))
+
+#undef API_VERSION
+
+//
+// API version 1.9 functions
+//
+
+#define API_VERSION {{9, 1}}
+
+FUNCTION(mfxStatus, MFXAudioUSER_Register, (mfxSession session, mfxU32 type, const mfxPlugin *par), (session, type, par))
+FUNCTION(mfxStatus, MFXAudioUSER_Unregister, (mfxSession session, mfxU32 type), (session, type))
+FUNCTION(mfxStatus, MFXAudioUSER_ProcessFrameAsync, (mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp), (session, in, in_num, out, out_num, syncp))
+
+
+#undef API_VERSION

+ 172 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxastructures.h

@@ -0,0 +1,172 @@
+/*******************************************************************************
+
+Copyright (C) 2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxastructures.h
+
+*******************************************************************************/
+#ifndef __MFXASTRUCTURES_H__
+#define __MFXASTRUCTURES_H__
+#include "mfxcommon.h"
+
+#if !defined (__GNUC__)
+#pragma warning(disable: 4201)
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* CodecId */
+enum {
+    MFX_CODEC_AAC         =MFX_MAKEFOURCC('A','A','C',' '),
+    MFX_CODEC_MP3         =MFX_MAKEFOURCC('M','P','3',' ')
+};
+
+enum {
+    /* AAC Profiles & Levels */
+    MFX_PROFILE_AAC_LC          =2,
+    MFX_PROFILE_AAC_LTP         =4,
+    MFX_PROFILE_AAC_MAIN        =1,
+    MFX_PROFILE_AAC_SSR         =3,
+    MFX_PROFILE_AAC_HE          =5,
+    MFX_PROFILE_AAC_ALS         =0x20,
+    MFX_PROFILE_AAC_BSAC        =22,
+    MFX_PROFILE_AAC_PS          =29,
+
+    /*MPEG AUDIO*/
+    MFX_AUDIO_MPEG1_LAYER1      =0x00000110, 
+    MFX_AUDIO_MPEG1_LAYER2      =0x00000120,
+    MFX_AUDIO_MPEG1_LAYER3      =0x00000140,
+    MFX_AUDIO_MPEG2_LAYER1      =0x00000210,
+    MFX_AUDIO_MPEG2_LAYER2      =0x00000220,
+    MFX_AUDIO_MPEG2_LAYER3      =0x00000240
+};
+
+/*AAC HE decoder down sampling*/
+enum {
+    MFX_AUDIO_AAC_HE_DWNSMPL_OFF=0,
+    MFX_AUDIO_AAC_HE_DWNSMPL_ON= 1
+};
+
+/* AAC decoder support of PS */
+enum {
+    MFX_AUDIO_AAC_PS_DISABLE=   0,
+    MFX_AUDIO_AAC_PS_PARSER=    1,
+    MFX_AUDIO_AAC_PS_ENABLE_BL= 111,
+    MFX_AUDIO_AAC_PS_ENABLE_UR= 411
+};
+
+/*AAC decoder SBR support*/
+enum {
+    MFX_AUDIO_AAC_SBR_DISABLE =  0,
+    MFX_AUDIO_AAC_SBR_ENABLE=    1,
+    MFX_AUDIO_AAC_SBR_UNDEF=     2
+};
+
+/*AAC header type*/
+enum{
+    MFX_AUDIO_AAC_ADTS=            1,
+    MFX_AUDIO_AAC_ADIF=            2,
+    MFX_AUDIO_AAC_RAW=             3,
+};
+
+/*AAC encoder stereo mode*/
+enum 
+{
+    MFX_AUDIO_AAC_MONO=            0,
+    MFX_AUDIO_AAC_LR_STEREO=       1,
+    MFX_AUDIO_AAC_MS_STEREO=       2,
+    MFX_AUDIO_AAC_JOINT_STEREO=    3
+};
+
+typedef struct {
+    mfxU32                CodecId;
+    mfxU16                CodecProfile;
+    mfxU16                CodecLevel;
+
+    mfxU32  Bitrate;
+    mfxU32  SampleFrequency;
+    mfxU16  NumChannel;
+    mfxU16  BitPerSample;
+
+    mfxU16                reserved1[22]; 
+
+    union {    
+        struct {   /* AAC Decoding Options */
+            mfxU16       FlagPSSupportLev;
+            mfxU16       Layer;
+            mfxU16       AACHeaderDataSize;
+            mfxU8        AACHeaderData[64];
+        };
+        struct {   /* AAC Encoding Options */
+            mfxU16       OutputFormat;
+            mfxU16       StereoMode;
+            mfxU16       reserved2[61]; 
+        };
+    };
+} mfxAudioInfoMFX;
+
+typedef struct {
+    mfxU16  AsyncDepth;
+    mfxU16  Protected;
+    mfxU16  reserved[14]; 
+
+    mfxAudioInfoMFX   mfx;
+    mfxExtBuffer**    ExtParam;
+    mfxU16            NumExtParam;
+} mfxAudioParam;
+
+typedef struct {
+    mfxU32  SuggestedInputSize;
+    mfxU32  SuggestedOutputSize;
+    mfxU32  reserved[6];
+} mfxAudioAllocRequest;
+
+typedef struct {
+    mfxU64  TimeStamp; /* 1/90KHz */
+    mfxU16  Locked;
+    mfxU16  NumChannels;
+    mfxU32  SampleFrequency;
+    mfxU16  BitPerSample;
+    mfxU16  reserved1[7]; 
+
+    mfxU8*  Data;
+    mfxU32  reserved2;
+    mfxU32  DataLength;
+    mfxU32  MaxLength;
+
+    mfxU32  NumExtParam;
+    mfxExtBuffer **ExtParam;
+} mfxAudioFrame;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
+

+ 113 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio++.h

@@ -0,0 +1,113 @@
+/*******************************************************************************
+
+Copyright (C) 2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+File Name: mfxaudio++.h
+
+
+*******************************************************************************/
+#ifndef __MFXAUDIOPLUSPLUS_H
+#define __MFXAUDIOPLUSPLUS_H
+
+#include "mfxaudio.h"
+
+class MFXAudioSession
+{
+public:
+    MFXAudioSession(void) { m_session = (mfxSession) 0; }
+    virtual ~MFXAudioSession(void) { Close(); }
+
+    virtual mfxStatus Init(mfxIMPL impl, mfxVersion *ver) { return MFXInit(impl, ver, &m_session); }
+    virtual mfxStatus Close(void)
+    {
+        mfxStatus mfxRes;
+        mfxRes = MFXClose(m_session); m_session = (mfxSession) 0;
+        return mfxRes;
+    }
+
+    virtual mfxStatus QueryIMPL(mfxIMPL *impl) { return MFXQueryIMPL(m_session, impl); }
+    virtual mfxStatus QueryVersion(mfxVersion *version) { return MFXQueryVersion(m_session, version); }
+
+    virtual mfxStatus JoinSession(mfxSession child_session) { return MFXJoinSession(m_session, child_session);}
+    virtual mfxStatus DisjoinSession( ) { return MFXDisjoinSession(m_session);}
+    virtual mfxStatus CloneSession( mfxSession *clone) { return MFXCloneSession(m_session, clone);}
+    virtual mfxStatus SetPriority( mfxPriority priority) { return MFXSetPriority(m_session, priority);}
+    virtual mfxStatus GetPriority( mfxPriority *priority) { return MFXGetPriority(m_session, priority);}
+
+    virtual mfxStatus SyncOperation(mfxSyncPoint syncp, mfxU32 wait) { return MFXAudioCORE_SyncOperation(m_session, syncp, wait); }
+
+    virtual operator mfxSession (void) { return m_session; }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+
+class MFXAudioDECODE
+{
+public:
+
+    MFXAudioDECODE(mfxSession session) { m_session = session; }
+    virtual ~MFXAudioDECODE(void) { Close(); }
+
+    virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) { return MFXAudioDECODE_Query(m_session, in, out); }
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxAudioParam *par) { return MFXAudioDECODE_DecodeHeader(m_session, bs, par); }
+    virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) { return MFXAudioDECODE_QueryIOSize(m_session, par, request); }
+    virtual mfxStatus Init(mfxAudioParam *par) { return MFXAudioDECODE_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxAudioParam *par) { return MFXAudioDECODE_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXAudioDECODE_Close(m_session); }
+    virtual mfxStatus GetAudioParam(mfxAudioParam *par) { return MFXAudioDECODE_GetAudioParam(m_session, par); }
+    virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs, mfxAudioFrame *frame, mfxSyncPoint *syncp) { return MFXAudioDECODE_DecodeFrameAsync(m_session, bs, frame, syncp); }
+
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+
+class MFXAudioENCODE
+{
+public:
+
+    MFXAudioENCODE(mfxSession session) { m_session = session; }
+    virtual ~MFXAudioENCODE(void) { Close(); }
+
+    virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) { return MFXAudioENCODE_Query(m_session, in, out); }
+    virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) { return MFXAudioENCODE_QueryIOSize(m_session, par, request); }
+    virtual mfxStatus Init(mfxAudioParam *par) { return MFXAudioENCODE_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxAudioParam *par) { return MFXAudioENCODE_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXAudioENCODE_Close(m_session); }
+    virtual mfxStatus GetAudioParam(mfxAudioParam *par) { return MFXAudioENCODE_GetAudioParam(m_session, par); }
+    virtual mfxStatus EncodeFrameAsync(mfxAudioFrame *frame, mfxBitstream *buffer_out, mfxSyncPoint *syncp) { return MFXAudioENCODE_EncodeFrameAsync(m_session, frame, buffer_out, syncp); }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+#endif

+ 70 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio.h

@@ -0,0 +1,70 @@
+/*******************************************************************************
+
+Copyright (C) 2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxaudio.h
+
+*******************************************************************************/
+
+#ifndef __MFXAUDIO_H__
+#define __MFXAUDIO_H__
+#include "mfxsession.h"
+#include "mfxastructures.h"
+
+#define MFX_AUDIO_VERSION_MAJOR 1
+#define MFX_AUDIO_VERSION_MINOR 15
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* AudioCORE */
+mfxStatus MFX_CDECL MFXAudioCORE_SyncOperation(mfxSession session, mfxSyncPoint syncp, mfxU32 wait);
+
+/* AudioENCODE */
+mfxStatus MFX_CDECL MFXAudioENCODE_Query(mfxSession session, mfxAudioParam *in, mfxAudioParam *out);
+mfxStatus MFX_CDECL MFXAudioENCODE_QueryIOSize(mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request);
+mfxStatus MFX_CDECL MFXAudioENCODE_Init(mfxSession session, mfxAudioParam *par);
+mfxStatus MFX_CDECL MFXAudioENCODE_Reset(mfxSession session, mfxAudioParam *par);
+mfxStatus MFX_CDECL MFXAudioENCODE_Close(mfxSession session);
+mfxStatus MFX_CDECL MFXAudioENCODE_GetAudioParam(mfxSession session, mfxAudioParam *par);
+mfxStatus MFX_CDECL MFXAudioENCODE_EncodeFrameAsync(mfxSession session, mfxAudioFrame *frame, mfxBitstream *bs, mfxSyncPoint *syncp);
+
+/* AudioDECODE */
+mfxStatus MFX_CDECL MFXAudioDECODE_Query(mfxSession session, mfxAudioParam *in, mfxAudioParam *out);
+mfxStatus MFX_CDECL MFXAudioDECODE_DecodeHeader(mfxSession session, mfxBitstream *bs, mfxAudioParam* par);
+mfxStatus MFX_CDECL MFXAudioDECODE_Init(mfxSession session, mfxAudioParam *par);
+mfxStatus MFX_CDECL MFXAudioDECODE_Reset(mfxSession session, mfxAudioParam *par);
+mfxStatus MFX_CDECL MFXAudioDECODE_Close(mfxSession session);
+mfxStatus MFX_CDECL MFXAudioDECODE_QueryIOSize(mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request);
+mfxStatus MFX_CDECL MFXAudioDECODE_GetAudioParam(mfxSession session, mfxAudioParam *par);
+mfxStatus MFX_CDECL MFXAudioDECODE_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxAudioFrame *frame, mfxSyncPoint *syncp);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif

+ 159 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxcommon.h

@@ -0,0 +1,159 @@
+/*******************************************************************************
+
+Copyright (C) 2013-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxcommon.h
+
+*******************************************************************************/
+#ifndef __MFXCOMMON_H__
+#define __MFXCOMMON_H__
+#include "mfxdefs.h"
+
+#if !defined (__GNUC__)
+#pragma warning(disable: 4201)
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define MFX_MAKEFOURCC(A,B,C,D)    ((((int)A))+(((int)B)<<8)+(((int)C)<<16)+(((int)D)<<24))
+
+/* Extended Configuration Header Structure */
+typedef struct {
+    mfxU32  BufferId;
+    mfxU32  BufferSz;
+} mfxExtBuffer;
+
+/* Library initialization and deinitialization */
+typedef mfxI32 mfxIMPL;
+#define MFX_IMPL_BASETYPE(x) (0x00ff & (x))
+
+enum  {
+    MFX_IMPL_AUTO         = 0x0000,  /* Auto Selection/In or Not Supported/Out */
+    MFX_IMPL_SOFTWARE     = 0x0001,  /* Pure Software Implementation */
+    MFX_IMPL_HARDWARE     = 0x0002,  /* Hardware Accelerated Implementation (default device) */
+    MFX_IMPL_AUTO_ANY     = 0x0003,  /* Auto selection of any hardware/software implementation */
+    MFX_IMPL_HARDWARE_ANY = 0x0004,  /* Auto selection of any hardware implementation */
+    MFX_IMPL_HARDWARE2    = 0x0005,  /* Hardware accelerated implementation (2nd device) */
+    MFX_IMPL_HARDWARE3    = 0x0006,  /* Hardware accelerated implementation (3rd device) */
+    MFX_IMPL_HARDWARE4    = 0x0007,  /* Hardware accelerated implementation (4th device) */
+    MFX_IMPL_RUNTIME      = 0x0008, 
+
+    MFX_IMPL_VIA_ANY      = 0x0100,
+    MFX_IMPL_VIA_D3D9     = 0x0200,
+    MFX_IMPL_VIA_D3D11    = 0x0300,
+    MFX_IMPL_VIA_VAAPI    = 0x0400,
+
+    MFX_IMPL_AUDIO        = 0x8000,
+     
+    MFX_IMPL_UNSUPPORTED  = 0x0000  /* One of the MFXQueryIMPL returns */
+};
+
+/* Version Info */
+typedef union {
+    struct {
+        mfxU16  Minor;
+        mfxU16  Major;
+    };
+    mfxU32  Version;
+} mfxVersion;
+
+/* session priority */
+typedef enum
+{
+    MFX_PRIORITY_LOW = 0,
+    MFX_PRIORITY_NORMAL = 1,
+    MFX_PRIORITY_HIGH = 2
+
+} mfxPriority;
+
+typedef struct _mfxEncryptedData mfxEncryptedData;
+typedef struct {
+     union {
+        struct {
+            mfxEncryptedData* EncryptedData;
+            mfxExtBuffer **ExtParam;
+            mfxU16  NumExtParam;
+        };
+         mfxU32  reserved[6];
+     };
+    mfxI64  DecodeTimeStamp; 
+    mfxU64  TimeStamp;
+    mfxU8*  Data;
+    mfxU32  DataOffset;
+    mfxU32  DataLength;
+    mfxU32  MaxLength;
+
+    mfxU16  PicStruct;
+    mfxU16  FrameType;
+    mfxU16  DataFlag;
+    mfxU16  reserved2;
+} mfxBitstream;
+
+typedef struct _mfxSyncPoint *mfxSyncPoint;
+
+/* GPUCopy */
+enum {
+    MFX_GPUCOPY_DEFAULT = 0,
+    MFX_GPUCOPY_ON      = 1,
+    MFX_GPUCOPY_OFF     = 2
+};
+
+typedef struct {
+    mfxIMPL     Implementation;
+    mfxVersion  Version;
+    mfxU16      ExternalThreads;
+    union {
+        struct {
+            mfxExtBuffer **ExtParam;
+            mfxU16  NumExtParam;
+        };
+        mfxU16  reserved2[5];
+    };
+    mfxU16      GPUCopy;
+    mfxU16      reserved[21];
+} mfxInitParam;
+
+enum {
+    MFX_EXTBUFF_THREADS_PARAM = MFX_MAKEFOURCC('T','H','D','P')
+};
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16       NumThread;
+    mfxI32       SchedulingType;
+    mfxI32       Priority;
+    mfxU16       reserved[55];
+} mfxExtThreadsParam;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+

+ 153 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxdefs.h

@@ -0,0 +1,153 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2007-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxdefs.h
+
+\* ****************************************************************************** */
+#ifndef __MFXDEFS_H__
+#define __MFXDEFS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+#if (defined( _WIN32 ) || defined ( _WIN64 )) && !defined (__GNUC__)
+  #define __INT64   __int64
+  #define __UINT64  unsigned __int64
+#else
+  #define __INT64   long long
+  #define __UINT64  unsigned long long
+#endif
+
+#ifdef _WIN32
+    #define MFX_CDECL __cdecl
+    #define MFX_STDCALL __stdcall
+#else
+    #define MFX_CDECL
+    #define MFX_STDCALL
+#endif /* _WIN32 */
+
+#define MFX_INFINITE 0xFFFFFFFF
+
+typedef unsigned char       mfxU8;
+typedef char                mfxI8;
+typedef short               mfxI16;
+typedef unsigned short      mfxU16;
+typedef unsigned int        mfxU32;
+typedef int                 mfxI32;
+#if defined( _WIN32 ) || defined ( _WIN64 )
+typedef unsigned long       mfxUL32;
+typedef long                mfxL32;
+#else
+typedef unsigned int        mfxUL32;
+typedef int                 mfxL32;
+#endif
+typedef float               mfxF32;
+typedef double              mfxF64;
+typedef __UINT64            mfxU64;
+typedef __INT64             mfxI64;
+typedef void*               mfxHDL;
+typedef mfxHDL              mfxMemId;
+typedef void*               mfxThreadTask;
+typedef char                mfxChar;
+
+typedef struct {
+    mfxI16  x;
+    mfxI16  y;
+} mfxI16Pair;
+
+typedef struct {
+    mfxHDL first;
+    mfxHDL second;
+} mfxHDLPair;
+
+
+/*********************************************************************************\
+Error message
+\*********************************************************************************/
+typedef enum
+{
+    /* no error */
+    MFX_ERR_NONE                        = 0,    /* no error */
+
+    /* reserved for unexpected errors */
+    MFX_ERR_UNKNOWN                     = -1,   /* unknown error. */
+
+    /* error codes <0 */
+    MFX_ERR_NULL_PTR                    = -2,   /* null pointer */
+    MFX_ERR_UNSUPPORTED                 = -3,   /* undeveloped feature */
+    MFX_ERR_MEMORY_ALLOC                = -4,   /* failed to allocate memory */
+    MFX_ERR_NOT_ENOUGH_BUFFER           = -5,   /* insufficient buffer at input/output */
+    MFX_ERR_INVALID_HANDLE              = -6,   /* invalid handle */
+    MFX_ERR_LOCK_MEMORY                 = -7,   /* failed to lock the memory block */
+    MFX_ERR_NOT_INITIALIZED             = -8,   /* member function called before initialization */
+    MFX_ERR_NOT_FOUND                   = -9,   /* the specified object is not found */
+    MFX_ERR_MORE_DATA                   = -10,  /* expect more data at input */
+    MFX_ERR_MORE_SURFACE                = -11,  /* expect more surface at output */
+    MFX_ERR_ABORTED                     = -12,  /* operation aborted */
+    MFX_ERR_DEVICE_LOST                 = -13,  /* lose the HW acceleration device */
+    MFX_ERR_INCOMPATIBLE_VIDEO_PARAM    = -14,  /* incompatible video parameters */
+    MFX_ERR_INVALID_VIDEO_PARAM         = -15,  /* invalid video parameters */
+    MFX_ERR_UNDEFINED_BEHAVIOR          = -16,  /* undefined behavior */
+    MFX_ERR_DEVICE_FAILED               = -17,  /* device operation failure */
+    MFX_ERR_MORE_BITSTREAM              = -18,  /* expect more bitstream buffers at output */
+    MFX_ERR_INCOMPATIBLE_AUDIO_PARAM    = -19,  /* incompatible audio parameters */
+    MFX_ERR_INVALID_AUDIO_PARAM         = -20,  /* invalid audio parameters */
+
+    /* warnings >0 */
+    MFX_WRN_IN_EXECUTION                = 1,    /* the previous asynchronous operation is in execution */
+    MFX_WRN_DEVICE_BUSY                 = 2,    /* the HW acceleration device is busy */
+    MFX_WRN_VIDEO_PARAM_CHANGED         = 3,    /* the video parameters are changed during decoding */
+    MFX_WRN_PARTIAL_ACCELERATION        = 4,    /* SW is used */
+    MFX_WRN_INCOMPATIBLE_VIDEO_PARAM    = 5,    /* incompatible video parameters */
+    MFX_WRN_VALUE_NOT_CHANGED           = 6,    /* the value is saturated based on its valid range */
+    MFX_WRN_OUT_OF_RANGE                = 7,    /* the value is out of valid range */
+    MFX_WRN_FILTER_SKIPPED              = 10,   /* one of requested filters has been skipped */
+    MFX_WRN_INCOMPATIBLE_AUDIO_PARAM    = 11,   /* incompatible audio parameters */
+
+    /* threading statuses */
+    MFX_TASK_DONE = MFX_ERR_NONE,               /* task has been completed */
+    MFX_TASK_WORKING                    = 8,    /* there is some more work to do */
+    MFX_TASK_BUSY                       = 9     /* task is waiting for resources */
+
+} mfxStatus;
+
+
+// Application 
+#if defined(MFX_DISPATCHER_EXPOSED_PREFIX)
+
+#include "mfxdispatcherprefixedfunctions.h"
+
+#endif // MFX_DISPATCHER_EXPOSED_PREFIX
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MFXDEFS_H__ */

+ 80 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxenc.h

@@ -0,0 +1,80 @@
+/******************************************************************************* *\
+
+Copyright (C) 2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxenc.h
+
+*******************************************************************************/
+#ifndef __MFXENC_H__
+#define __MFXENC_H__
+#include "mfxdefs.h"
+#include "mfxvstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef struct _mfxENCInput mfxENCInput;
+struct _mfxENCInput{
+    mfxU32  reserved[32];
+
+    mfxFrameSurface1 *InSurface;
+
+    mfxU16  NumFrameL0;
+    mfxFrameSurface1 **L0Surface;
+    mfxU16  NumFrameL1;
+    mfxFrameSurface1 **L1Surface;
+
+    mfxU16  NumExtParam;
+    mfxExtBuffer    **ExtParam;
+} ;
+typedef struct _mfxENCOutput mfxENCOutput;
+struct _mfxENCOutput{
+    mfxU32  reserved[32];
+
+    mfxFrameSurface1 *OutSurface;
+
+    mfxU16  NumExtParam;
+    mfxExtBuffer    **ExtParam;
+} ;
+
+
+mfxStatus MFX_CDECL MFXVideoENC_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+mfxStatus MFX_CDECL MFXVideoENC_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request);
+mfxStatus MFX_CDECL MFXVideoENC_Init(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoENC_Reset(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoENC_Close(mfxSession session);
+
+mfxStatus MFX_CDECL MFXVideoENC_ProcessFrameAsync(mfxSession session, mfxENCInput *in, mfxENCOutput *out, mfxSyncPoint *syncp);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+
+#endif
+

+ 107 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxjpeg.h

@@ -0,0 +1,107 @@
+/******************************************************************************* *\
+
+Copyright (C) 2010-2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxjpeg.h
+
+*******************************************************************************/
+#ifndef __MFX_JPEG_H__
+#define __MFX_JPEG_H__
+
+#include "mfxdefs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* CodecId */
+enum {
+    MFX_CODEC_JPEG    = MFX_MAKEFOURCC('J','P','E','G')
+};
+
+/* CodecProfile, CodecLevel */
+enum
+{
+    MFX_PROFILE_JPEG_BASELINE      = 1
+};
+
+enum
+{
+    MFX_ROTATION_0      = 0,
+    MFX_ROTATION_90     = 1,
+    MFX_ROTATION_180    = 2,
+    MFX_ROTATION_270    = 3
+};
+
+enum {
+    MFX_EXTBUFF_JPEG_QT     =   MFX_MAKEFOURCC('J','P','G','Q'),
+    MFX_EXTBUFF_JPEG_HUFFMAN     =   MFX_MAKEFOURCC('J','P','G','H')
+};
+
+enum {
+    MFX_JPEG_COLORFORMAT_UNKNOWN = 0,
+    MFX_JPEG_COLORFORMAT_YCbCr = 1,
+    MFX_JPEG_COLORFORMAT_RGB = 2
+};
+
+enum {
+    MFX_SCANTYPE_UNKNOWN = 0,
+    MFX_SCANTYPE_INTERLEAVED = 1,
+    MFX_SCANTYPE_NONINTERLEAVED = 2
+};
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU16  reserved[7];
+    mfxU16  NumTable;
+
+    mfxU16    Qm[4][64];
+} mfxExtJPEGQuantTables;
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU16  reserved[2];
+    mfxU16  NumDCTable;
+    mfxU16  NumACTable;
+
+    struct {
+        mfxU8   Bits[16];
+        mfxU8   Values[12];
+    } DCTables[4];
+
+    struct {
+        mfxU8   Bits[16];
+        mfxU8   Values[162];
+    } ACTables[4];
+} mfxExtJPEGHuffmanTables;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+#endif // __MFX_JPEG_H__

+ 109 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxmvc.h

@@ -0,0 +1,109 @@
+/******************************************************************************* *\
+
+Copyright (C) 2010-2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxmvc.h
+
+*******************************************************************************/
+#ifndef __MFXMVC_H__
+#define __MFXMVC_H__
+
+#include "mfxdefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CodecProfile, CodecLevel */
+enum {
+    /* MVC profiles */
+    MFX_PROFILE_AVC_MULTIVIEW_HIGH =118,
+    MFX_PROFILE_AVC_STEREO_HIGH    =128
+};
+
+/* Extended Buffer Ids */
+enum {
+    MFX_EXTBUFF_MVC_SEQ_DESC =   MFX_MAKEFOURCC('M','V','C','D'),
+    MFX_EXTBUFF_MVC_TARGET_VIEWS    =   MFX_MAKEFOURCC('M','V','C','T')
+};
+
+typedef struct  {
+    mfxU16 ViewId;
+
+    mfxU16 NumAnchorRefsL0;
+    mfxU16 NumAnchorRefsL1;
+    mfxU16 AnchorRefL0[16];
+    mfxU16 AnchorRefL1[16];
+
+    mfxU16 NumNonAnchorRefsL0;
+    mfxU16 NumNonAnchorRefsL1;
+    mfxU16 NonAnchorRefL0[16];
+    mfxU16 NonAnchorRefL1[16];
+} mfxMVCViewDependency;
+
+typedef struct {
+    mfxU16 TemporalId;
+    mfxU16 LevelIdc;
+
+    mfxU16 NumViews;
+    mfxU16 NumTargetViews;
+    mfxU16 *TargetViewId;
+} mfxMVCOperationPoint;
+
+typedef struct  {
+    mfxExtBuffer Header;
+
+    mfxU32 NumView;
+    mfxU32 NumViewAlloc;
+    mfxMVCViewDependency *View;
+
+    mfxU32 NumViewId;
+    mfxU32 NumViewIdAlloc;
+    mfxU16 *ViewId;
+
+    mfxU32 NumOP;
+    mfxU32 NumOPAlloc;
+    mfxMVCOperationPoint *OP;
+
+    mfxU16 NumRefsTotal;
+    mfxU32 Reserved[16];
+
+} mfxExtMVCSeqDesc;
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU16 TemporalId;
+    mfxU32 NumView;
+    mfxU16 ViewId[1024];
+} mfxExtMVCTargetViews ;
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
+

+ 78 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxpak.h

@@ -0,0 +1,78 @@
+/******************************************************************************* *\
+
+Copyright (C) 2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxpak.h
+
+*******************************************************************************/
+#ifndef __MFXPAK_H__
+#define __MFXPAK_H__
+#include "mfxdefs.h"
+#include "mfxvstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef struct {
+    mfxU32  reserved[32];
+
+    mfxFrameSurface1 *InSurface;
+
+    mfxU16  NumFrameL0;
+    mfxFrameSurface1 **L0Surface;
+    mfxU16  NumFrameL1;
+    mfxFrameSurface1 **L1Surface;
+
+    mfxU16  NumExtParam;
+    mfxExtBuffer    **ExtParam;
+} mfxPAKInput;
+
+typedef struct {
+    mfxBitstream     *Bs; 
+
+    mfxFrameSurface1 *OutSurface;
+
+    mfxU16            NumExtParam;
+    mfxExtBuffer    **ExtParam;
+} mfxPAKOutput;
+
+typedef struct _mfxSession *mfxSession;
+mfxStatus MFX_CDECL MFXVideoPAK_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+mfxStatus MFX_CDECL MFXVideoPAK_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request);
+mfxStatus MFX_CDECL MFXVideoPAK_Init(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoPAK_Reset(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoPAK_Close(mfxSession session);
+
+mfxStatus MFX_CDECL MFXVideoPAK_ProcessFrameAsync(mfxSession session, mfxPAKInput *in, mfxPAKOutput *out,  mfxSyncPoint *syncp);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+
+#endif

+ 719 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin++.h

@@ -0,0 +1,719 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2007-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+File Name: mfxplugin++.h
+
+\* ****************************************************************************** */
+
+#ifndef __MFXPLUGINPLUSPLUS_H
+#define __MFXPLUGINPLUSPLUS_H
+
+#include "mfxplugin.h"
+
+// base class for MFXVideoUSER/MFXAudioUSER API
+
+class MFXBaseUSER {
+public:
+    explicit MFXBaseUSER(mfxSession session = NULL)
+        : m_session(session){}
+
+    virtual ~MFXBaseUSER() {};
+
+    virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) = 0;
+    virtual mfxStatus Unregister(mfxU32 type) = 0;
+    virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) = 0;
+
+protected:
+    mfxSession m_session;
+};
+
+//c++ wrapper over only 3 exposed functions from MFXVideoUSER module
+class MFXVideoUSER: public MFXBaseUSER {
+public:
+    explicit MFXVideoUSER(mfxSession session = NULL)
+        : MFXBaseUSER(session){}
+
+    virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) {
+        return MFXVideoUSER_Register(m_session, type, par);
+    }
+    virtual mfxStatus Unregister(mfxU32 type) {
+        return MFXVideoUSER_Unregister(m_session, type);
+    }
+    virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) {
+        return MFXVideoUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp);
+    }
+};
+
+//c++ wrapper over only 3 exposed functions from MFXAudioUSER module
+class MFXAudioUSER: public MFXBaseUSER {
+public:
+    explicit MFXAudioUSER(mfxSession session = NULL)
+        : MFXBaseUSER(session){}
+
+    virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) {
+        return MFXAudioUSER_Register(m_session, type, par);
+    }
+    virtual mfxStatus Unregister(mfxU32 type) {
+        return MFXAudioUSER_Unregister(m_session, type);
+    }
+    virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) {
+        return MFXAudioUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp);
+    }
+};
+
+
+//initialize mfxPlugin struct
+class MFXPluginParam {
+    mfxPluginParam m_param;
+
+public:
+    MFXPluginParam(mfxU32 CodecId, mfxU32  Type, mfxPluginUID uid, mfxThreadPolicy ThreadPolicy = MFX_THREADPOLICY_SERIAL, mfxU32  MaxThreadNum = 1)
+        : m_param() {
+        m_param.PluginUID = uid;
+        m_param.Type = Type;
+        m_param.CodecId = CodecId;
+        m_param.MaxThreadNum = MaxThreadNum;
+        m_param.ThreadPolicy = ThreadPolicy;
+    }
+    operator const mfxPluginParam& () const {
+        return m_param;
+    }
+    operator mfxPluginParam& () {
+        return m_param;
+    }
+};
+
+//common interface part for every plugin: decoder/encoder and generic
+struct MFXPlugin
+{
+    virtual ~MFXPlugin() {};
+    //init function always required for any transform or codec plugins, for codec plugins it maps to callback from MediaSDK
+    //for generic plugin application should call it
+    //MediaSDK mfxPlugin API mapping
+    virtual mfxStatus PluginInit(mfxCoreInterface *core) = 0;
+    //release CoreInterface, and destroy plugin state, not destroy plugin instance
+    virtual mfxStatus PluginClose() = 0;
+    virtual mfxStatus GetPluginParam(mfxPluginParam *par) = 0;
+    virtual mfxStatus Execute(mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a) = 0;
+    virtual mfxStatus FreeResources(mfxThreadTask task, mfxStatus sts) = 0;
+    //destroy plugin due to shared module distribution model plugin wont support virtual destructor
+    virtual void      Release() = 0;
+    //release resources associated with current instance of plugin, but do not release CoreInterface related resource set in pluginInit
+    virtual mfxStatus Close()  = 0;
+    //communication protocol between particular version of plugin and application
+    virtual mfxStatus SetAuxParams(void* auxParam, int auxParamSize) = 0;
+};
+
+//common extension interface that codec plugins should expose additionally to MFXPlugin
+struct MFXCodecPlugin : MFXPlugin
+{
+    virtual mfxStatus Init(mfxVideoParam *par) = 0;
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0;
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) =0;
+    virtual mfxStatus Reset(mfxVideoParam *par) = 0;
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) = 0;
+};
+
+//common extension interface that audio codec plugins should expose additionally to MFXPlugin
+struct MFXAudioCodecPlugin : MFXPlugin
+{
+    virtual mfxStatus Init(mfxAudioParam *par) = 0;
+    virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) =0;
+    virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) = 0;
+    virtual mfxStatus Reset(mfxAudioParam *par) = 0;
+    virtual mfxStatus GetAudioParam(mfxAudioParam *par) = 0;
+};
+
+//general purpose transform plugin interface, not a codec plugin
+struct MFXGenericPlugin : MFXPlugin
+{
+    virtual mfxStatus Init(mfxVideoParam *par) = 0;
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0;
+    virtual mfxStatus Submit(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) = 0;
+};
+
+//decoder plugins may only support this interface 
+struct MFXDecoderPlugin : MFXCodecPlugin
+{
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) = 0;
+    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0;
+    virtual mfxStatus DecodeFrameSubmit(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out,  mfxThreadTask *task) = 0;
+};
+
+//audio decoder plugins may only support this interface 
+struct MFXAudioDecoderPlugin : MFXAudioCodecPlugin
+{
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxAudioParam *par) = 0;
+//    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0;
+    virtual mfxStatus DecodeFrameSubmit(mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) = 0;
+};
+
+//encoder plugins may only support this interface 
+struct MFXEncoderPlugin : MFXCodecPlugin
+{
+    virtual mfxStatus EncodeFrameSubmit(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) = 0;
+};
+
+//audio encoder plugins may only support this interface 
+struct MFXAudioEncoderPlugin : MFXAudioCodecPlugin
+{
+    virtual mfxStatus EncodeFrameSubmit(mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) = 0;
+};
+
+//vpp plugins may only support this interface 
+struct MFXVPPPlugin : MFXCodecPlugin
+{
+    virtual mfxStatus VPPFrameSubmit(mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) = 0;
+    virtual mfxStatus VPPFrameSubmitEx(mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) = 0;
+};
+
+struct MFXEncPlugin : MFXCodecPlugin
+{
+    virtual mfxStatus EncFrameSubmit(mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) = 0;
+};
+
+
+
+
+class MFXCoreInterface
+{
+protected:
+    mfxCoreInterface m_core;
+public:
+
+    MFXCoreInterface()
+        : m_core() {
+    }
+    MFXCoreInterface(const mfxCoreInterface & pCore)
+        : m_core(pCore) {
+    }
+
+    MFXCoreInterface(const MFXCoreInterface & that)
+        : m_core(that.m_core) {
+    }
+    MFXCoreInterface &operator = (const MFXCoreInterface & that)
+    { 
+        m_core = that.m_core;
+        return *this;
+    }
+    bool IsCoreSet() {
+        return m_core.pthis != 0;
+    }
+    mfxStatus GetCoreParam(mfxCoreParam *par) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.GetCoreParam(m_core.pthis, par);
+    }
+    mfxStatus GetHandle (mfxHandleType type, mfxHDL *handle) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.GetHandle(m_core.pthis, type, handle);
+    }
+    mfxStatus IncreaseReference (mfxFrameData *fd) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.IncreaseReference(m_core.pthis, fd);
+    }
+    mfxStatus DecreaseReference (mfxFrameData *fd) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.DecreaseReference(m_core.pthis, fd);
+    }
+    mfxStatus CopyFrame (mfxFrameSurface1 *dst, mfxFrameSurface1 *src) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.CopyFrame(m_core.pthis, dst, src);
+    }
+    mfxStatus CopyBuffer(mfxU8 *dst, mfxU32 size, mfxFrameSurface1 *src) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.CopyBuffer(m_core.pthis, dst, size, src);
+    }
+    mfxStatus MapOpaqueSurface(mfxU32  num, mfxU32  type, mfxFrameSurface1 **op_surf) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.MapOpaqueSurface(m_core.pthis, num, type, op_surf);
+    }
+    mfxStatus UnmapOpaqueSurface(mfxU32  num, mfxU32  type, mfxFrameSurface1 **op_surf) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.UnmapOpaqueSurface(m_core.pthis, num, type, op_surf);
+    }
+    mfxStatus GetRealSurface(mfxFrameSurface1 *op_surf, mfxFrameSurface1 **surf) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.GetRealSurface(m_core.pthis, op_surf, surf);
+    }
+    mfxStatus GetOpaqueSurface(mfxFrameSurface1 *surf, mfxFrameSurface1 **op_surf) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.GetOpaqueSurface(m_core.pthis, surf, op_surf);
+    }
+    mfxStatus CreateAccelerationDevice(mfxHandleType type, mfxHDL *handle) {
+        if (!IsCoreSet()) {
+            return MFX_ERR_NULL_PTR;
+        }
+        return m_core.CreateAccelerationDevice(m_core.pthis, type, handle);
+    }
+    mfxFrameAllocator & FrameAllocator() {
+        return m_core.FrameAllocator;
+    }
+
+} ;
+
+/* Class adapter between "C" structure mfxPlugin and C++ interface MFXPlugin */
+
+namespace detail 
+{
+    template <class T>
+    class MFXPluginAdapterBase
+    {
+    protected:
+        mfxPlugin m_mfxAPI;
+    public:
+        MFXPluginAdapterBase( T *plugin, mfxVideoCodecPlugin *pCodec = NULL)
+        {
+            SetupCallbacks(plugin, pCodec);
+        }
+
+        MFXPluginAdapterBase( T *plugin, mfxAudioCodecPlugin *pCodec)
+        {
+            SetupCallbacks(plugin, pCodec);
+        }
+
+        operator  mfxPlugin () const {
+            return m_mfxAPI;
+        }
+        void SetupCallbacks(T *plugin) {
+            m_mfxAPI.pthis = plugin;
+            m_mfxAPI.PluginInit = _PluginInit;
+            m_mfxAPI.PluginClose = _PluginClose;
+            m_mfxAPI.GetPluginParam = _GetPluginParam;
+            m_mfxAPI.Submit = 0;
+            m_mfxAPI.Execute = _Execute;
+            m_mfxAPI.FreeResources = _FreeResources;
+        }
+
+        void SetupCallbacks( T *plugin, mfxVideoCodecPlugin *pCodec) {
+            SetupCallbacks(plugin);
+            m_mfxAPI.Video = pCodec;
+        }
+
+        void SetupCallbacks( T *plugin, mfxAudioCodecPlugin *pCodec) {
+            SetupCallbacks(plugin);
+            m_mfxAPI.Audio = pCodec;
+        }
+    private:
+
+        static mfxStatus _PluginInit(mfxHDL pthis, mfxCoreInterface *core) {
+            return reinterpret_cast<T*>(pthis)->PluginInit(core); 
+        }
+        static mfxStatus _PluginClose(mfxHDL pthis) { 
+            return reinterpret_cast<T*>(pthis)->PluginClose(); 
+        }
+        static mfxStatus _GetPluginParam(mfxHDL pthis, mfxPluginParam *par) { 
+            return reinterpret_cast<T*>(pthis)->GetPluginParam(par); 
+        }
+        static mfxStatus _Execute(mfxHDL pthis, mfxThreadTask task, mfxU32 thread_id, mfxU32 call_count) { 
+            return reinterpret_cast<T*>(pthis)->Execute(task, thread_id, call_count); 
+        }
+        static mfxStatus _FreeResources(mfxHDL pthis, mfxThreadTask task, mfxStatus sts) { 
+            return reinterpret_cast<T*>(pthis)->FreeResources(task, sts); 
+        }
+    };
+
+    template<class T>
+    class MFXCodecPluginAdapterBase : public MFXPluginAdapterBase<T>
+    {
+    protected:
+        //stub to feed mediasdk plugin API
+        mfxVideoCodecPlugin   m_codecPlg;
+    public:
+        MFXCodecPluginAdapterBase(T * pCodecPlg)
+            : MFXPluginAdapterBase<T>(pCodecPlg, &m_codecPlg)
+            , m_codecPlg()
+        {
+            m_codecPlg.Query = _Query;
+            m_codecPlg.QueryIOSurf = _QueryIOSurf ;
+            m_codecPlg.Init = _Init;
+            m_codecPlg.Reset = _Reset;
+            m_codecPlg.Close = _Close;
+            m_codecPlg.GetVideoParam = _GetVideoParam;
+        }
+        MFXCodecPluginAdapterBase(const MFXCodecPluginAdapterBase<T> & that) 
+            : MFXPluginAdapterBase<T>(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg)
+            , m_codecPlg() {
+            SetupCallbacks();
+        }
+        MFXCodecPluginAdapterBase<T>& operator = (const MFXCodecPluginAdapterBase<T> & that) {
+            MFXPluginAdapterBase<T> :: SetupCallbacks(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg);
+            SetupCallbacks();
+            return *this;
+        }
+
+    private:
+        void SetupCallbacks() {
+            m_codecPlg.Query = _Query;
+            m_codecPlg.QueryIOSurf = _QueryIOSurf ;
+            m_codecPlg.Init = _Init;
+            m_codecPlg.Reset = _Reset;
+            m_codecPlg.Close = _Close;
+            m_codecPlg.GetVideoParam = _GetVideoParam;
+        }
+        static mfxStatus _Query(mfxHDL pthis, mfxVideoParam *in, mfxVideoParam *out) {
+            return reinterpret_cast<T*>(pthis)->Query(in, out);
+        }
+        static mfxStatus _QueryIOSurf(mfxHDL pthis, mfxVideoParam *par, mfxFrameAllocRequest *in,  mfxFrameAllocRequest *out){
+            return reinterpret_cast<T*>(pthis)->QueryIOSurf(par, in, out);
+        }
+        static mfxStatus _Init(mfxHDL pthis, mfxVideoParam *par){
+            return reinterpret_cast<T*>(pthis)->Init(par);
+        }
+        static mfxStatus _Reset(mfxHDL pthis, mfxVideoParam *par){
+            return reinterpret_cast<T*>(pthis)->Reset(par);
+        }
+        static mfxStatus _Close(mfxHDL pthis) {
+            return reinterpret_cast<T*>(pthis)->Close();
+        }
+        static mfxStatus _GetVideoParam(mfxHDL pthis, mfxVideoParam *par) {
+            return reinterpret_cast<T*>(pthis)->GetVideoParam(par);
+        }
+    };
+
+    template<class T>
+    class MFXAudioCodecPluginAdapterBase : public MFXPluginAdapterBase<T>
+    {
+    protected:
+        //stub to feed mediasdk plugin API
+        mfxAudioCodecPlugin   m_codecPlg;
+    public:
+        MFXAudioCodecPluginAdapterBase(T * pCodecPlg)
+            : MFXPluginAdapterBase<T>(pCodecPlg, &m_codecPlg)
+            , m_codecPlg()
+        {
+            m_codecPlg.Query = _Query;
+            m_codecPlg.QueryIOSize = _QueryIOSize ;
+            m_codecPlg.Init = _Init;
+            m_codecPlg.Reset = _Reset;
+            m_codecPlg.Close = _Close;
+            m_codecPlg.GetAudioParam = _GetAudioParam;
+        }
+        MFXAudioCodecPluginAdapterBase(const MFXCodecPluginAdapterBase<T> & that) 
+            : MFXPluginAdapterBase<T>(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg)
+            , m_codecPlg() {
+            SetupCallbacks();
+        }
+        MFXAudioCodecPluginAdapterBase<T>& operator = (const MFXAudioCodecPluginAdapterBase<T> & that) {
+            MFXPluginAdapterBase<T> :: SetupCallbacks(reinterpret_cast<T*>(that.m_mfxAPI.pthis), &m_codecPlg);
+            SetupCallbacks();
+            return *this;
+        }
+
+    private:
+        void SetupCallbacks() {
+            m_codecPlg.Query = _Query;
+            m_codecPlg.QueryIOSize = _QueryIOSize;
+            m_codecPlg.Init = _Init;
+            m_codecPlg.Reset = _Reset;
+            m_codecPlg.Close = _Close;
+            m_codecPlg.GetAudioParam = _GetAudioParam;
+        }
+        static mfxStatus _Query(mfxHDL pthis, mfxAudioParam *in, mfxAudioParam *out) {
+            return reinterpret_cast<T*>(pthis)->Query(in, out);
+        }
+        static mfxStatus _QueryIOSize(mfxHDL pthis, mfxAudioParam *par, mfxAudioAllocRequest *request){
+            return reinterpret_cast<T*>(pthis)->QueryIOSize(par, request);
+        }
+        static mfxStatus _Init(mfxHDL pthis, mfxAudioParam *par){
+            return reinterpret_cast<T*>(pthis)->Init(par);
+        }
+        static mfxStatus _Reset(mfxHDL pthis, mfxAudioParam *par){
+            return reinterpret_cast<T*>(pthis)->Reset(par);
+        }
+        static mfxStatus _Close(mfxHDL pthis) {
+            return reinterpret_cast<T*>(pthis)->Close();
+        }
+        static mfxStatus _GetAudioParam(mfxHDL pthis, mfxAudioParam *par) {
+            return reinterpret_cast<T*>(pthis)->GetAudioParam(par);
+        }
+    };
+    
+    template <class T>
+    struct MFXPluginAdapterInternal{};
+    template<>
+    class MFXPluginAdapterInternal<MFXGenericPlugin> : public MFXPluginAdapterBase<MFXGenericPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXGenericPlugin *pPlugin)
+            : MFXPluginAdapterBase<MFXGenericPlugin>(pPlugin)
+        {
+            m_mfxAPI.Submit = _Submit;
+        }
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that )
+            : MFXPluginAdapterBase<MFXGenericPlugin>(that) {
+            m_mfxAPI.Submit = that._Submit;
+        }
+        MFXPluginAdapterInternal<MFXGenericPlugin>& operator = (const MFXPluginAdapterInternal<MFXGenericPlugin> & that) {
+            MFXPluginAdapterBase<MFXGenericPlugin>::operator=(that);
+            m_mfxAPI.Submit = that._Submit;
+            return *this;
+        }
+
+    private:
+        static mfxStatus _Submit(mfxHDL pthis, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) { 
+            return reinterpret_cast<MFXGenericPlugin*>(pthis)->Submit(in, in_num, out, out_num, task); 
+        }
+    };
+
+    template<>
+    class MFXPluginAdapterInternal<MFXDecoderPlugin> : public MFXCodecPluginAdapterBase<MFXDecoderPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXDecoderPlugin *pPlugin)
+            : MFXCodecPluginAdapterBase<MFXDecoderPlugin>(pPlugin)
+        {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
+        : MFXCodecPluginAdapterBase<MFXDecoderPlugin>(that) {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal<MFXDecoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXDecoderPlugin> & that) {
+            MFXCodecPluginAdapterBase<MFXDecoderPlugin>::operator=(that);
+            SetupCallbacks();
+            return *this;
+        }
+
+    private:
+        void SetupCallbacks() {
+            m_codecPlg.DecodeHeader = _DecodeHeader;
+            m_codecPlg.GetPayload = _GetPayload;
+            m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit;
+        }
+        static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxVideoParam *par) {
+            return reinterpret_cast<MFXDecoderPlugin*>(pthis)->DecodeHeader(bs, par);
+        }
+        static mfxStatus _GetPayload(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload) {
+            return reinterpret_cast<MFXDecoderPlugin*>(pthis)->GetPayload(ts, payload);
+        }
+        static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out,  mfxThreadTask *task) {
+            return reinterpret_cast<MFXDecoderPlugin*>(pthis)->DecodeFrameSubmit(bs, surface_work, surface_out, task);
+        }
+    };
+
+    template<>
+    class MFXPluginAdapterInternal<MFXAudioDecoderPlugin> : public MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXAudioDecoderPlugin *pPlugin)
+            : MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>(pPlugin)
+        {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
+        : MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>(that) {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal<MFXAudioDecoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXAudioDecoderPlugin> & that) {
+            MFXAudioCodecPluginAdapterBase<MFXAudioDecoderPlugin>::operator=(that);
+            SetupCallbacks();
+            return *this;
+        }
+
+    private:
+        void SetupCallbacks() {
+            m_codecPlg.DecodeHeader = _DecodeHeader;
+//            m_codecPlg.GetPayload = _GetPayload;
+            m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit;
+        }
+        static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxAudioParam *par) {
+            return reinterpret_cast<MFXAudioDecoderPlugin*>(pthis)->DecodeHeader(bs, par);
+        }
+//        static mfxStatus _GetPayload(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload) {
+  //          return reinterpret_cast<MFXAudioDecoderPlugin*>(pthis)->GetPayload(ts, payload);
+    //    }
+        static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) {
+            return reinterpret_cast<MFXAudioDecoderPlugin*>(pthis)->DecodeFrameSubmit(in, out, task);
+        }
+    };
+
+    template<>
+    class MFXPluginAdapterInternal<MFXEncoderPlugin> : public MFXCodecPluginAdapterBase<MFXEncoderPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXEncoderPlugin *pPlugin)
+            : MFXCodecPluginAdapterBase<MFXEncoderPlugin>(pPlugin)
+        {
+            m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
+        }
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
+            : MFXCodecPluginAdapterBase<MFXEncoderPlugin>(that) {
+            m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
+        }
+
+        MFXPluginAdapterInternal<MFXEncoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXEncoderPlugin> & that) {
+            MFXCodecPluginAdapterBase<MFXEncoderPlugin>::operator = (that);
+            m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
+            return *this;
+        }
+
+    private:
+        static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) {
+            return reinterpret_cast<MFXEncoderPlugin*>(pthis)->EncodeFrameSubmit(ctrl, surface, bs, task);
+        }
+    };
+
+    template<>
+    class MFXPluginAdapterInternal<MFXAudioEncoderPlugin> : public MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXAudioEncoderPlugin *pPlugin)
+            : MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>(pPlugin)
+        {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
+        : MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>(that) {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal<MFXAudioEncoderPlugin>& operator = (const MFXPluginAdapterInternal<MFXAudioEncoderPlugin> & that) {
+            MFXAudioCodecPluginAdapterBase<MFXAudioEncoderPlugin>::operator=(that);
+            SetupCallbacks();
+            return *this;
+        }
+
+    private:
+        void SetupCallbacks() {
+            m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit;
+        }
+        static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) {
+            return reinterpret_cast<MFXAudioEncoderPlugin*>(pthis)->EncodeFrameSubmit(aFrame, out, task);
+        }
+    };
+
+    template<>
+    class MFXPluginAdapterInternal<MFXEncPlugin> : public MFXCodecPluginAdapterBase<MFXEncPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXEncPlugin *pPlugin)
+            : MFXCodecPluginAdapterBase<MFXEncPlugin>(pPlugin)
+        {
+            m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit;
+        }
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
+            : MFXCodecPluginAdapterBase<MFXEncPlugin>(that) {
+            m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit;
+        }
+
+        MFXPluginAdapterInternal<MFXEncPlugin>& operator = (const MFXPluginAdapterInternal<MFXEncPlugin> & that) {
+            MFXCodecPluginAdapterBase<MFXEncPlugin>::operator = (that);
+            m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit;
+            return *this;
+        }
+
+    private:
+        static mfxStatus _ENCFrameSubmit(mfxHDL pthis,mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) {
+            return reinterpret_cast<MFXEncPlugin*>(pthis)->EncFrameSubmit(in, out, task);
+        }
+    };
+
+
+    template<>
+    class MFXPluginAdapterInternal<MFXVPPPlugin> : public MFXCodecPluginAdapterBase<MFXVPPPlugin>
+    {
+    public:
+        MFXPluginAdapterInternal(MFXVPPPlugin *pPlugin)
+            : MFXCodecPluginAdapterBase<MFXVPPPlugin>(pPlugin)
+        {
+            SetupCallbacks();
+        }
+        MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that)
+            : MFXCodecPluginAdapterBase<MFXVPPPlugin>(that) {
+            SetupCallbacks();
+        }
+
+        MFXPluginAdapterInternal<MFXVPPPlugin>& operator = (const MFXPluginAdapterInternal<MFXVPPPlugin> & that) {
+            MFXCodecPluginAdapterBase<MFXVPPPlugin>::operator = (that);
+            SetupCallbacks();
+            return *this;
+        }
+
+    private:
+        void SetupCallbacks() {
+            m_codecPlg.VPPFrameSubmit = _VPPFrameSubmit;
+            m_codecPlg.VPPFrameSubmitEx = _VPPFrameSubmitEx;
+        }
+        static mfxStatus _VPPFrameSubmit(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) {
+            return reinterpret_cast<MFXVPPPlugin*>(pthis)->VPPFrameSubmit(surface_in, surface_out, aux, task);
+        }
+        static mfxStatus _VPPFrameSubmitEx(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) {
+            return reinterpret_cast<MFXVPPPlugin*>(pthis)->VPPFrameSubmitEx(surface_in, surface_work, surface_out, task);
+        }
+    };
+}
+
+/* adapter for particular plugin type*/
+template<class T>
+class MFXPluginAdapter
+{
+public:
+    detail::MFXPluginAdapterInternal<T> m_Adapter;
+    
+    operator  mfxPlugin () const {
+        return m_Adapter.operator mfxPlugin();
+    }
+
+    MFXPluginAdapter(T* pPlugin = NULL)
+        : m_Adapter(pPlugin)
+    {
+    }
+};
+
+template<class T>
+inline MFXPluginAdapter<T> make_mfx_plugin_adapter(T* pPlugin) {
+
+    MFXPluginAdapter<T> adapt(pPlugin);
+    return adapt;
+}
+
+#endif // __MFXPLUGINPLUSPLUS_H

+ 206 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin.h

@@ -0,0 +1,206 @@
+/******************************************************************************* *\
+
+Copyright (C) 2007-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxplugin.h
+
+*******************************************************************************/
+#ifndef __MFXPLUGIN_H__
+#define __MFXPLUGIN_H__
+#include "mfxvideo.h"
+#include "mfxaudio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef struct {
+    mfxU8  Data[16];
+} mfxPluginUID;
+
+static const mfxPluginUID  MFX_PLUGINID_HEVCD_SW     = {{0x15, 0xdd, 0x93, 0x68, 0x25, 0xad, 0x47, 0x5e, 0xa3, 0x4e, 0x35, 0xf3, 0xf5, 0x42, 0x17, 0xa6}};
+static const mfxPluginUID  MFX_PLUGINID_HEVCD_HW     = {{0x33, 0xa6, 0x1c, 0x0b, 0x4c, 0x27, 0x45, 0x4c, 0xa8, 0xd8, 0x5d, 0xde, 0x75, 0x7c, 0x6f, 0x8e}};
+static const mfxPluginUID  MFX_PLUGINID_HEVCE_SW     = {{0x2f, 0xca, 0x99, 0x74, 0x9f, 0xdb, 0x49, 0xae, 0xb1, 0x21, 0xa5, 0xb6, 0x3e, 0xf5, 0x68, 0xf7}};
+static const mfxPluginUID  MFX_PLUGINID_HEVCE_GACC   = {{0xe5, 0x40, 0x0a, 0x06, 0xc7, 0x4d, 0x41, 0xf5, 0xb1, 0x2d, 0x43, 0x0b, 0xba, 0xa2, 0x3d, 0x0b}};
+static const mfxPluginUID  MFX_PLUGINID_HEVCE_HW     = {{0x6f, 0xad, 0xc7, 0x91, 0xa0, 0xc2, 0xeb, 0x47, 0x9a, 0xb6, 0xdc, 0xd5, 0xea, 0x9d, 0xa3, 0x47}};
+static const mfxPluginUID  MFX_PLUGINID_VP8D_HW      = {{0xf6, 0x22, 0x39, 0x4d, 0x8d, 0x87, 0x45, 0x2f, 0x87, 0x8c, 0x51, 0xf2, 0xfc, 0x9b, 0x41, 0x31}};
+static const mfxPluginUID  MFX_PLUGINID_VP8E_HW      = {{0xbf, 0xfc, 0x51, 0x8c, 0xde, 0x13, 0x4d, 0xf9, 0x8a, 0x96, 0xf4, 0xcf, 0x81, 0x6c, 0x0f, 0xac}};
+static const mfxPluginUID  MFX_PLUGINID_VP9E_HW      = {{0xce, 0x44, 0xef, 0x6f, 0x1a, 0x6d, 0x22, 0x46, 0xb4, 0x12, 0xbb, 0x38, 0xd6, 0xe4, 0x51, 0x82}};
+static const mfxPluginUID  MFX_PLUGINID_VP9D_HW      = {{0xa9, 0x22, 0x39, 0x4d, 0x8d, 0x87, 0x45, 0x2f, 0x87, 0x8c, 0x51, 0xf2, 0xfc, 0x9b, 0x41, 0x31}};
+static const mfxPluginUID  MFX_PLUGINID_CAMERA_HW    = {{0x54, 0x54, 0x26, 0x16, 0x24, 0x33, 0x41, 0xe6, 0x93, 0xae, 0x89, 0x99, 0x42, 0xce, 0x73, 0x55}};
+static const mfxPluginUID  MFX_PLUGINID_CAPTURE_HW   = {{0x22, 0xd6, 0x2c, 0x07, 0xe6, 0x72, 0x40, 0x8f, 0xbb, 0x4c, 0xc2, 0x0e, 0xd7, 0xa0, 0x53, 0xe4}};
+static const mfxPluginUID  MFX_PLUGINID_ITELECINE_HW = {{0xe7, 0x44, 0x75, 0x3a, 0xcd, 0x74, 0x40, 0x2e, 0x89, 0xa2, 0xee, 0x06, 0x35, 0x49, 0x61, 0x79}};
+static const mfxPluginUID  MFX_PLUGINID_H264LA_HW    = {{0x58, 0x8f, 0x11, 0x85, 0xd4, 0x7b, 0x42, 0x96, 0x8d, 0xea, 0x37, 0x7b, 0xb5, 0xd0, 0xdc, 0xb4}};
+static const mfxPluginUID  MFX_PLUGINID_AACD         = {{0xe9, 0x34, 0x67, 0x25, 0xac, 0x2f, 0x4c, 0x93, 0xaa, 0x58, 0x5c, 0x11, 0xc7, 0x08, 0x7c, 0xf4}};
+static const mfxPluginUID  MFX_PLUGINID_AACE         = {{0xb2, 0xa2, 0xa0, 0x5a, 0x4e, 0xac, 0x46, 0xbf, 0xa9, 0xde, 0x7e, 0x80, 0xc9, 0x8d, 0x2e, 0x18}};
+static const mfxPluginUID  MFX_PLUGINID_HEVCE_FEI_HW = {{0x87, 0xe0, 0xe8, 0x02, 0x07, 0x37, 0x52, 0x40, 0x85, 0x25, 0x15, 0xcf, 0x4a, 0x5e, 0xdd, 0xe6}};
+
+
+typedef enum {
+    MFX_PLUGINTYPE_VIDEO_GENERAL   = 0,
+    MFX_PLUGINTYPE_VIDEO_DECODE    = 1,
+    MFX_PLUGINTYPE_VIDEO_ENCODE    = 2,
+    MFX_PLUGINTYPE_VIDEO_VPP       = 3,
+    MFX_PLUGINTYPE_VIDEO_ENC       = 4,
+    MFX_PLUGINTYPE_AUDIO_DECODE    = 5,
+    MFX_PLUGINTYPE_AUDIO_ENCODE    = 6
+} mfxPluginType;
+
+typedef enum {
+    MFX_THREADPOLICY_SERIAL    = 0,
+    MFX_THREADPOLICY_PARALLEL    = 1
+} mfxThreadPolicy;
+
+typedef struct mfxPluginParam {
+    mfxU32  reserved[6];
+    mfxU16  reserved1;
+    mfxU16  PluginVersion;
+    mfxVersion   APIVersion;
+    mfxPluginUID PluginUID;
+    mfxU32  Type;
+    mfxU32  CodecId;
+    mfxThreadPolicy ThreadPolicy;
+    mfxU32  MaxThreadNum;
+} mfxPluginParam;
+
+typedef struct mfxCoreParam{
+    mfxU32  reserved[13];
+    mfxIMPL Impl;
+    mfxVersion Version;
+    mfxU32  NumWorkingThread;
+} mfxCoreParam;
+
+typedef struct mfxCoreInterface {
+    mfxHDL pthis;
+
+    mfxHDL reserved1[2];
+    mfxFrameAllocator FrameAllocator;
+    mfxBufferAllocator reserved3;
+
+    mfxStatus (MFX_CDECL *GetCoreParam)(mfxHDL pthis, mfxCoreParam *par);
+    mfxStatus (MFX_CDECL *GetHandle) (mfxHDL pthis, mfxHandleType type, mfxHDL *handle);
+    mfxStatus (MFX_CDECL *IncreaseReference) (mfxHDL pthis, mfxFrameData *fd);
+    mfxStatus (MFX_CDECL *DecreaseReference) (mfxHDL pthis, mfxFrameData *fd);
+    mfxStatus (MFX_CDECL *CopyFrame) (mfxHDL pthis, mfxFrameSurface1 *dst, mfxFrameSurface1 *src);
+    mfxStatus (MFX_CDECL *CopyBuffer)(mfxHDL pthis, mfxU8 *dst, mfxU32 size, mfxFrameSurface1 *src);
+
+    mfxStatus (MFX_CDECL *MapOpaqueSurface)(mfxHDL pthis, mfxU32  num, mfxU32  type, mfxFrameSurface1 **op_surf);
+    mfxStatus (MFX_CDECL *UnmapOpaqueSurface)(mfxHDL pthis, mfxU32  num, mfxU32  type, mfxFrameSurface1 **op_surf);
+
+    mfxStatus (MFX_CDECL *GetRealSurface)(mfxHDL pthis, mfxFrameSurface1 *op_surf, mfxFrameSurface1 **surf);
+    mfxStatus (MFX_CDECL *GetOpaqueSurface)(mfxHDL pthis, mfxFrameSurface1 *surf, mfxFrameSurface1 **op_surf);
+
+    mfxStatus (MFX_CDECL *CreateAccelerationDevice)(mfxHDL pthis, mfxHandleType type, mfxHDL *handle);
+
+    mfxHDL reserved4[3];
+} mfxCoreInterface;
+
+/* video codec plugin extension*/
+typedef struct _mfxENCInput mfxENCInput;
+typedef struct _mfxENCOutput mfxENCOutput;
+typedef struct mfxVideoCodecPlugin{
+    mfxStatus (MFX_CDECL *Query)(mfxHDL pthis, mfxVideoParam *in, mfxVideoParam *out);
+    mfxStatus (MFX_CDECL *QueryIOSurf)(mfxHDL pthis, mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out); 
+    mfxStatus (MFX_CDECL *Init)(mfxHDL pthis, mfxVideoParam *par);
+    mfxStatus (MFX_CDECL *Reset)(mfxHDL pthis, mfxVideoParam *par);
+    mfxStatus (MFX_CDECL *Close)(mfxHDL pthis);
+    mfxStatus (MFX_CDECL *GetVideoParam)(mfxHDL pthis, mfxVideoParam *par);
+
+    mfxStatus (MFX_CDECL *EncodeFrameSubmit)(mfxHDL pthis, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task);
+    
+    mfxStatus (MFX_CDECL *DecodeHeader)(mfxHDL pthis, mfxBitstream *bs, mfxVideoParam *par);
+    mfxStatus (MFX_CDECL *GetPayload)(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload);
+    mfxStatus (MFX_CDECL *DecodeFrameSubmit)(mfxHDL pthis, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out,  mfxThreadTask *task);
+
+    mfxStatus (MFX_CDECL *VPPFrameSubmit)(mfxHDL pthis,  mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxThreadTask *task);
+    mfxStatus (MFX_CDECL *VPPFrameSubmitEx)(mfxHDL pthis,  mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task);
+
+    mfxStatus (MFX_CDECL *ENCFrameSubmit)(mfxHDL pthis,  mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task);
+
+    mfxHDL reserved1[3];
+    mfxU32 reserved2[8];
+} mfxVideoCodecPlugin;
+
+typedef struct mfxAudioCodecPlugin{
+    mfxStatus (MFX_CDECL *Query)(mfxHDL pthis, mfxAudioParam *in, mfxAudioParam *out);
+    mfxStatus (MFX_CDECL *QueryIOSize)(mfxHDL pthis, mfxAudioParam *par, mfxAudioAllocRequest *request); 
+    mfxStatus (MFX_CDECL *Init)(mfxHDL pthis, mfxAudioParam *par);
+    mfxStatus (MFX_CDECL *Reset)(mfxHDL pthis, mfxAudioParam *par);
+    mfxStatus (MFX_CDECL *Close)(mfxHDL pthis);
+    mfxStatus (MFX_CDECL *GetAudioParam)(mfxHDL pthis, mfxAudioParam *par);
+
+    mfxStatus (MFX_CDECL *EncodeFrameSubmit)(mfxHDL pthis, mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task);
+    
+    mfxStatus (MFX_CDECL *DecodeHeader)(mfxHDL pthis, mfxBitstream *bs, mfxAudioParam *par);
+//    mfxStatus (MFX_CDECL *GetPayload)(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload);
+    mfxStatus (MFX_CDECL *DecodeFrameSubmit)(mfxHDL pthis, mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task);
+
+    mfxHDL reserved1[6];
+    mfxU32 reserved2[8];
+} mfxAudioCodecPlugin;
+
+typedef struct mfxPlugin{
+    mfxHDL pthis;
+
+    mfxStatus (MFX_CDECL *PluginInit) (mfxHDL pthis, mfxCoreInterface *core);
+    mfxStatus (MFX_CDECL *PluginClose) (mfxHDL pthis);
+
+    mfxStatus (MFX_CDECL *GetPluginParam)(mfxHDL pthis, mfxPluginParam *par);
+
+    mfxStatus (MFX_CDECL *Submit)(mfxHDL pthis, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task);
+    mfxStatus (MFX_CDECL *Execute)(mfxHDL pthis, mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a);
+    mfxStatus (MFX_CDECL *FreeResources)(mfxHDL pthis, mfxThreadTask task, mfxStatus sts);
+
+    union {
+        mfxVideoCodecPlugin  *Video;
+        mfxAudioCodecPlugin  *Audio;
+    };
+
+    mfxHDL reserved[8];
+} mfxPlugin;
+
+
+
+mfxStatus MFX_CDECL MFXVideoUSER_Register(mfxSession session, mfxU32 type, const mfxPlugin *par);
+mfxStatus MFX_CDECL MFXVideoUSER_Unregister(mfxSession session, mfxU32 type);
+mfxStatus MFX_CDECL MFXVideoUSER_ProcessFrameAsync(mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp);
+
+mfxStatus MFX_CDECL MFXVideoUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version);
+mfxStatus MFX_CDECL MFXVideoUSER_LoadByPath(mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len);
+mfxStatus MFX_CDECL MFXVideoUSER_UnLoad(mfxSession session, const mfxPluginUID *uid);
+
+mfxStatus MFX_CDECL MFXAudioUSER_Register(mfxSession session, mfxU32 type, const mfxPlugin *par);
+mfxStatus MFX_CDECL MFXAudioUSER_Unregister(mfxSession session, mfxU32 type);
+mfxStatus MFX_CDECL MFXAudioUSER_ProcessFrameAsync(mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp);
+
+mfxStatus MFX_CDECL MFXAudioUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version);
+mfxStatus MFX_CDECL MFXAudioUSER_UnLoad(mfxSession session, const mfxPluginUID *uid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+#endif /* __MFXPLUGIN_H__ */

+ 60 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxsession.h

@@ -0,0 +1,60 @@
+/*******************************************************************************
+
+Copyright (C) 2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxsession.h
+
+*******************************************************************************/
+#ifndef __MFXSESSION_H__
+#define __MFXSESSION_H__
+#include "mfxcommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* Global Functions */
+typedef struct _mfxSession *mfxSession;
+mfxStatus MFX_CDECL MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session);
+mfxStatus MFX_CDECL MFXInitEx(mfxInitParam par, mfxSession *session);
+mfxStatus MFX_CDECL MFXClose(mfxSession session);
+
+mfxStatus MFX_CDECL MFXQueryIMPL(mfxSession session, mfxIMPL *impl);
+mfxStatus MFX_CDECL MFXQueryVersion(mfxSession session, mfxVersion *version);
+
+mfxStatus MFX_CDECL MFXJoinSession(mfxSession session, mfxSession child);
+mfxStatus MFX_CDECL MFXDisjoinSession(mfxSession session);
+mfxStatus MFX_CDECL MFXCloneSession(mfxSession session, mfxSession *clone);
+mfxStatus MFX_CDECL MFXSetPriority(mfxSession session, mfxPriority priority);
+mfxStatus MFX_CDECL MFXGetPriority(mfxSession session, mfxPriority *priority);
+mfxStatus MFX_CDECL MFXDoWork(mfxSession session);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+

+ 1379 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxstructures.h

@@ -0,0 +1,1379 @@
+/******************************************************************************* *\
+
+Copyright (C) 2007-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxstructures.h
+
+*******************************************************************************/
+#ifndef __MFXSTRUCTURES_H__
+#define __MFXSTRUCTURES_H__
+#include "mfxcommon.h"
+
+#if !defined (__GNUC__)
+#pragma warning(disable: 4201)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Frame ID for SVC and MVC */
+typedef struct {
+    mfxU16      TemporalId;
+    mfxU16      PriorityId;
+    union {
+        struct {
+            mfxU16  DependencyId;
+            mfxU16  QualityId;
+        };
+        struct {
+            mfxU16  ViewId;
+        };
+    };
+} mfxFrameId;
+
+#pragma pack(push, 4)
+/* Frame Info */
+typedef struct {
+    mfxU32  reserved[4];
+    mfxU16  reserved4;
+    mfxU16  BitDepthLuma;
+    mfxU16  BitDepthChroma;
+    mfxU16  Shift;
+
+    mfxFrameId FrameId;
+
+    mfxU32  FourCC;
+    union {
+        struct { /* Frame parameters */
+            mfxU16  Width;
+            mfxU16  Height;
+
+            mfxU16  CropX;
+            mfxU16  CropY;
+            mfxU16  CropW;
+            mfxU16  CropH;
+        };
+        struct { /* Buffer parameters (for plain formats like P8) */
+            mfxU64 BufferSize;
+            mfxU32 reserved5;
+        };
+    };
+
+    mfxU32  FrameRateExtN;
+    mfxU32  FrameRateExtD;
+    mfxU16  reserved3;
+
+    mfxU16  AspectRatioW;
+    mfxU16  AspectRatioH;
+
+    mfxU16  PicStruct;
+    mfxU16  ChromaFormat;
+    mfxU16  reserved2;
+} mfxFrameInfo;
+#pragma pack(pop)
+
+/* FourCC */
+enum {
+    MFX_FOURCC_NV12         = MFX_MAKEFOURCC('N','V','1','2'),   /* Native Format */
+    MFX_FOURCC_YV12         = MFX_MAKEFOURCC('Y','V','1','2'),
+    MFX_FOURCC_NV16         = MFX_MAKEFOURCC('N','V','1','6'),
+    MFX_FOURCC_YUY2         = MFX_MAKEFOURCC('Y','U','Y','2'),
+    MFX_FOURCC_RGB3         = MFX_MAKEFOURCC('R','G','B','3'),   /* deprecated */
+    MFX_FOURCC_RGB4         = MFX_MAKEFOURCC('R','G','B','4'),   /* ARGB in that order, A channel is 8 MSBs */
+    MFX_FOURCC_P8           = 41,                                /*  D3DFMT_P8   */
+    MFX_FOURCC_P8_TEXTURE   = MFX_MAKEFOURCC('P','8','M','B'),
+    MFX_FOURCC_P010         = MFX_MAKEFOURCC('P','0','1','0'), 
+    MFX_FOURCC_P210         = MFX_MAKEFOURCC('P','2','1','0'),
+    MFX_FOURCC_BGR4         = MFX_MAKEFOURCC('B','G','R','4'),   /* ABGR in that order, A channel is 8 MSBs */
+    MFX_FOURCC_A2RGB10      = MFX_MAKEFOURCC('R','G','1','0'),   /* ARGB in that order, A channel is two MSBs */
+    MFX_FOURCC_ARGB16       = MFX_MAKEFOURCC('R','G','1','6'),   /* ARGB in that order, 64 bits, A channel is 16 MSBs */
+    MFX_FOURCC_ABGR16       = MFX_MAKEFOURCC('B','G','1','6'),   /* ABGR in that order, 64 bits, A channel is 16 MSBs */
+    MFX_FOURCC_R16          = MFX_MAKEFOURCC('R','1','6','U'),
+    MFX_FOURCC_AYUV         = MFX_MAKEFOURCC('A','Y','U','V'),   /* YUV 4:4:4, AYUV in that order, A channel is 8 MSBs */
+    MFX_FOURCC_AYUV_RGB4    = MFX_MAKEFOURCC('A','V','U','Y'),   /* ARGB in that order, A channel is 8 MSBs stored in AYUV surface*/
+    MFX_FOURCC_UYVY         = MFX_MAKEFOURCC('U','Y','V','Y')
+};
+
+/* PicStruct */
+enum {
+    MFX_PICSTRUCT_UNKNOWN       =0x00,
+    MFX_PICSTRUCT_PROGRESSIVE   =0x01,
+    MFX_PICSTRUCT_FIELD_TFF     =0x02,
+    MFX_PICSTRUCT_FIELD_BFF     =0x04,
+
+    MFX_PICSTRUCT_FIELD_REPEATED=0x10,  /* first field repeated, pic_struct=5 or 6 in H.264 */
+    MFX_PICSTRUCT_FRAME_DOUBLING=0x20,  /* pic_struct=7 in H.264 */
+    MFX_PICSTRUCT_FRAME_TRIPLING=0x40   /* pic_struct=8 in H.264 */
+};
+
+/* ColorFormat */
+enum {
+    MFX_CHROMAFORMAT_MONOCHROME =0,
+    MFX_CHROMAFORMAT_YUV420     =1,
+    MFX_CHROMAFORMAT_YUV422     =2,
+    MFX_CHROMAFORMAT_YUV444     =3,
+    MFX_CHROMAFORMAT_YUV400     = MFX_CHROMAFORMAT_MONOCHROME,
+    MFX_CHROMAFORMAT_YUV411     = 4,
+    MFX_CHROMAFORMAT_YUV422H    = MFX_CHROMAFORMAT_YUV422,
+    MFX_CHROMAFORMAT_YUV422V    = 5
+};
+
+enum {
+    MFX_TIMESTAMP_UNKNOWN = -1
+};
+
+enum {
+    MFX_FRAMEORDER_UNKNOWN = -1
+};
+
+/* DataFlag in mfxFrameData */
+enum {
+    MFX_FRAMEDATA_ORIGINAL_TIMESTAMP = 0x0001
+};
+
+/* Corrupted in mfxFrameData */
+enum {
+    MFX_CORRUPTION_MINOR           = 0x0001,
+    MFX_CORRUPTION_MAJOR           = 0x0002,
+    MFX_CORRUPTION_ABSENT_TOP_FIELD           = 0x0004,
+    MFX_CORRUPTION_ABSENT_BOTTOM_FIELD           = 0x0008,
+    MFX_CORRUPTION_REFERENCE_FRAME = 0x0010,
+    MFX_CORRUPTION_REFERENCE_LIST  = 0x0020
+};
+
+/* Frame Data Info */
+typedef struct {
+    union {
+        mfxExtBuffer **ExtParam;
+        mfxU64       reserved2;
+    };
+    mfxU16  NumExtParam;
+
+    mfxU16      reserved[10];
+    mfxU16      PitchHigh;
+
+    mfxU64      TimeStamp;
+    mfxU32      FrameOrder;
+    mfxU16      Locked;
+    union{
+        mfxU16  Pitch;
+        mfxU16  PitchLow;
+    };
+
+    /* color planes */
+    union {
+        mfxU8   *Y;
+        mfxU16  *Y16;
+        mfxU8   *R;
+    };
+    union {
+        mfxU8   *UV;            /* for UV merged formats */
+        mfxU8   *VU;            /* for VU merged formats */
+        mfxU8   *CbCr;          /* for CbCr merged formats */
+        mfxU8   *CrCb;          /* for CrCb merged formats */
+        mfxU8   *Cb;
+        mfxU8   *U;
+        mfxU16  *U16;
+        mfxU8   *G;
+    };
+    union {
+        mfxU8   *Cr;
+        mfxU8   *V;
+        mfxU16  *V16;
+        mfxU8   *B;
+    };
+    mfxU8       *A;
+    mfxMemId    MemId;
+
+    /* Additional Flags */
+    mfxU16  Corrupted;
+    mfxU16  DataFlag;
+} mfxFrameData;
+
+/* Frame Surface */
+typedef struct {
+    mfxU32  reserved[4];
+    mfxFrameInfo    Info;
+    mfxFrameData    Data;
+} mfxFrameSurface1;
+
+enum {
+    MFX_TIMESTAMPCALC_UNKNOWN = 0,
+    MFX_TIMESTAMPCALC_TELECINE = 1,
+};
+
+/* Transcoding Info */
+typedef struct {
+    mfxU32  reserved[7];
+
+    mfxU16  LowPower;
+    mfxU16  BRCParamMultiplier;
+
+    mfxFrameInfo    FrameInfo;
+    mfxU32  CodecId;
+    mfxU16  CodecProfile;
+    mfxU16  CodecLevel;
+    mfxU16  NumThread;
+
+    union {
+        struct {   /* MPEG-2/H.264 Encoding Options */
+            mfxU16  TargetUsage;
+
+            mfxU16  GopPicSize;
+            mfxU16  GopRefDist;
+            mfxU16  GopOptFlag;
+            mfxU16  IdrInterval;
+
+            mfxU16  RateControlMethod;
+            union {
+                mfxU16  InitialDelayInKB;
+                mfxU16  QPI;
+                mfxU16  Accuracy;
+            };
+            mfxU16  BufferSizeInKB;
+            union {
+                mfxU16  TargetKbps;
+                mfxU16  QPP;
+                mfxU16  ICQQuality;
+            };
+            union {
+                mfxU16  MaxKbps;
+                mfxU16  QPB;
+                mfxU16  Convergence;
+            };
+
+            mfxU16  NumSlice;
+            mfxU16  NumRefFrame;
+            mfxU16  EncodedOrder;
+        };
+        struct {   /* H.264, MPEG-2 and VC-1 Decoding Options */
+            mfxU16  DecodedOrder;
+            mfxU16  ExtendedPicStruct;
+            mfxU16  TimeStampCalc;
+            mfxU16  SliceGroupsPresent;
+            mfxU16  MaxDecFrameBuffering;
+            mfxU16  reserved2[8];
+        };
+        struct {   /* JPEG Decoding Options */
+            mfxU16  JPEGChromaFormat;
+            mfxU16  Rotation;
+            mfxU16  JPEGColorFormat;
+            mfxU16  InterleavedDec;
+            mfxU16  reserved3[9];
+        };
+        struct {   /* JPEG Encoding Options */
+            mfxU16  Interleaved;
+            mfxU16  Quality;
+            mfxU16  RestartInterval;
+            mfxU16  reserved5[10];
+        };
+    };
+} mfxInfoMFX;
+
+typedef struct {
+    mfxU32  reserved[8];
+    mfxFrameInfo    In;
+    mfxFrameInfo    Out;
+} mfxInfoVPP;
+
+typedef struct {
+    mfxU32  AllocId;
+    mfxU32  reserved[2];
+    mfxU16  reserved3;
+    mfxU16  AsyncDepth;
+
+    union {
+        mfxInfoMFX  mfx;
+        mfxInfoVPP  vpp;
+    };
+    mfxU16  Protected;
+    mfxU16  IOPattern;
+    mfxExtBuffer** ExtParam;
+    mfxU16  NumExtParam;
+    mfxU16  reserved2;
+} mfxVideoParam;
+
+/* IOPattern */
+enum {
+    MFX_IOPATTERN_IN_VIDEO_MEMORY   = 0x01,
+    MFX_IOPATTERN_IN_SYSTEM_MEMORY  = 0x02,
+    MFX_IOPATTERN_IN_OPAQUE_MEMORY  = 0x04,
+    MFX_IOPATTERN_OUT_VIDEO_MEMORY  = 0x10,
+    MFX_IOPATTERN_OUT_SYSTEM_MEMORY = 0x20,
+    MFX_IOPATTERN_OUT_OPAQUE_MEMORY = 0x40
+};
+
+/* CodecId */
+enum {
+    MFX_CODEC_AVC         =MFX_MAKEFOURCC('A','V','C',' '),
+    MFX_CODEC_HEVC        =MFX_MAKEFOURCC('H','E','V','C'),
+    MFX_CODEC_MPEG2       =MFX_MAKEFOURCC('M','P','G','2'),
+    MFX_CODEC_VC1         =MFX_MAKEFOURCC('V','C','1',' '),
+    MFX_CODEC_CAPTURE     =MFX_MAKEFOURCC('C','A','P','T')
+};
+
+/* CodecProfile, CodecLevel */
+enum {
+    MFX_PROFILE_UNKNOWN                     =0,
+    MFX_LEVEL_UNKNOWN                       =0,
+
+    /* AVC Profiles & Levels */
+    MFX_PROFILE_AVC_CONSTRAINT_SET0     = (0x100 << 0),
+    MFX_PROFILE_AVC_CONSTRAINT_SET1     = (0x100 << 1),
+    MFX_PROFILE_AVC_CONSTRAINT_SET2     = (0x100 << 2),
+    MFX_PROFILE_AVC_CONSTRAINT_SET3     = (0x100 << 3),
+    MFX_PROFILE_AVC_CONSTRAINT_SET4     = (0x100 << 4),
+    MFX_PROFILE_AVC_CONSTRAINT_SET5     = (0x100 << 5),
+
+    MFX_PROFILE_AVC_BASELINE                =66,
+    MFX_PROFILE_AVC_MAIN                    =77,
+    MFX_PROFILE_AVC_EXTENDED                =88,
+    MFX_PROFILE_AVC_HIGH                    =100,
+    MFX_PROFILE_AVC_HIGH_422                =122,
+    MFX_PROFILE_AVC_CONSTRAINED_BASELINE    =MFX_PROFILE_AVC_BASELINE + MFX_PROFILE_AVC_CONSTRAINT_SET1,
+    MFX_PROFILE_AVC_CONSTRAINED_HIGH        =MFX_PROFILE_AVC_HIGH     + MFX_PROFILE_AVC_CONSTRAINT_SET4
+                                                                      + MFX_PROFILE_AVC_CONSTRAINT_SET5,
+    MFX_PROFILE_AVC_PROGRESSIVE_HIGH        =MFX_PROFILE_AVC_HIGH     + MFX_PROFILE_AVC_CONSTRAINT_SET4,
+
+    MFX_LEVEL_AVC_1                         =10,
+    MFX_LEVEL_AVC_1b                        =9,
+    MFX_LEVEL_AVC_11                        =11,
+    MFX_LEVEL_AVC_12                        =12,
+    MFX_LEVEL_AVC_13                        =13,
+    MFX_LEVEL_AVC_2                         =20,
+    MFX_LEVEL_AVC_21                        =21,
+    MFX_LEVEL_AVC_22                        =22,
+    MFX_LEVEL_AVC_3                         =30,
+    MFX_LEVEL_AVC_31                        =31,
+    MFX_LEVEL_AVC_32                        =32,
+    MFX_LEVEL_AVC_4                         =40,
+    MFX_LEVEL_AVC_41                        =41,
+    MFX_LEVEL_AVC_42                        =42,
+    MFX_LEVEL_AVC_5                         =50,
+    MFX_LEVEL_AVC_51                        =51,
+    MFX_LEVEL_AVC_52                        =52,
+
+    /* MPEG-2 Profiles & Levels */
+    MFX_PROFILE_MPEG2_SIMPLE                =0x50,
+    MFX_PROFILE_MPEG2_MAIN                  =0x40,
+    MFX_PROFILE_MPEG2_HIGH                  =0x10,
+
+    MFX_LEVEL_MPEG2_LOW                     =0xA,
+    MFX_LEVEL_MPEG2_MAIN                    =0x8,
+    MFX_LEVEL_MPEG2_HIGH                    =0x4,
+    MFX_LEVEL_MPEG2_HIGH1440                =0x6,
+
+    /* VC1 Profiles & Levels */
+    MFX_PROFILE_VC1_SIMPLE                  =(0+1),
+    MFX_PROFILE_VC1_MAIN                    =(4+1),
+    MFX_PROFILE_VC1_ADVANCED                =(12+1),
+
+    /* VC1 levels for simple & main profiles */
+    MFX_LEVEL_VC1_LOW                       =(0+1),
+    MFX_LEVEL_VC1_MEDIAN                    =(2+1),
+    MFX_LEVEL_VC1_HIGH                      =(4+1),
+
+    /* VC1 levels for the advanced profile */
+    MFX_LEVEL_VC1_0                         =(0x00+1),
+    MFX_LEVEL_VC1_1                         =(0x01+1),
+    MFX_LEVEL_VC1_2                         =(0x02+1),
+    MFX_LEVEL_VC1_3                         =(0x03+1),
+    MFX_LEVEL_VC1_4                         =(0x04+1),
+
+    /* HEVC Profiles & Levels & Tiers */
+    MFX_PROFILE_HEVC_MAIN             =1,
+    MFX_PROFILE_HEVC_MAIN10           =2,
+    MFX_PROFILE_HEVC_MAINSP           =3,
+    MFX_PROFILE_HEVC_REXT             =4,
+
+    MFX_LEVEL_HEVC_1   = 10,
+    MFX_LEVEL_HEVC_2   = 20,
+    MFX_LEVEL_HEVC_21  = 21,
+    MFX_LEVEL_HEVC_3   = 30,
+    MFX_LEVEL_HEVC_31  = 31,
+    MFX_LEVEL_HEVC_4   = 40,
+    MFX_LEVEL_HEVC_41  = 41,
+    MFX_LEVEL_HEVC_5   = 50,
+    MFX_LEVEL_HEVC_51  = 51,
+    MFX_LEVEL_HEVC_52  = 52,
+    MFX_LEVEL_HEVC_6   = 60,
+    MFX_LEVEL_HEVC_61  = 61,
+    MFX_LEVEL_HEVC_62  = 62,
+
+    MFX_TIER_HEVC_MAIN  = 0,
+    MFX_TIER_HEVC_HIGH  = 0x100,
+};
+
+/* GopOptFlag */
+enum {
+    MFX_GOP_CLOSED          =1,
+    MFX_GOP_STRICT          =2
+};
+
+/* TargetUsages: from 1 to 7 inclusive */
+enum {
+    MFX_TARGETUSAGE_1    =1,
+    MFX_TARGETUSAGE_2    =2,
+    MFX_TARGETUSAGE_3    =3,
+    MFX_TARGETUSAGE_4    =4,
+    MFX_TARGETUSAGE_5    =5,
+    MFX_TARGETUSAGE_6    =6,
+    MFX_TARGETUSAGE_7    =7,
+
+    MFX_TARGETUSAGE_UNKNOWN         =0,
+    MFX_TARGETUSAGE_BEST_QUALITY    =MFX_TARGETUSAGE_1,
+    MFX_TARGETUSAGE_BALANCED        =MFX_TARGETUSAGE_4,
+    MFX_TARGETUSAGE_BEST_SPEED      =MFX_TARGETUSAGE_7
+};
+
+/* RateControlMethod */
+enum {
+    MFX_RATECONTROL_CBR       =1,
+    MFX_RATECONTROL_VBR       =2,
+    MFX_RATECONTROL_CQP       =3,
+    MFX_RATECONTROL_AVBR      =4,
+    MFX_RATECONTROL_RESERVED1 =5,
+    MFX_RATECONTROL_RESERVED2 =6,
+    MFX_RATECONTROL_RESERVED3 =100,
+    MFX_RATECONTROL_RESERVED4 =7,
+    MFX_RATECONTROL_LA        =8,
+    MFX_RATECONTROL_ICQ       =9,
+    MFX_RATECONTROL_VCM       =10,
+    MFX_RATECONTROL_LA_ICQ    =11,
+    MFX_RATECONTROL_LA_EXT    =12,
+    MFX_RATECONTROL_LA_HRD    =13,
+    MFX_RATECONTROL_QVBR      =14
+};
+
+/* Trellis control*/
+enum {
+    MFX_TRELLIS_UNKNOWN =0,
+    MFX_TRELLIS_OFF     =0x01,
+    MFX_TRELLIS_I       =0x02,
+    MFX_TRELLIS_P       =0x04,
+    MFX_TRELLIS_B       =0x08
+};
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16      reserved1;
+    mfxU16      RateDistortionOpt;      /* tri-state option */
+    mfxU16      MECostType;
+    mfxU16      MESearchType;
+    mfxI16Pair  MVSearchWindow;
+    mfxU16      EndOfSequence;          /* tri-state option */
+    mfxU16      FramePicture;           /* tri-state option */
+
+    mfxU16      CAVLC;                  /* tri-state option */
+    mfxU16      reserved2[2];
+    mfxU16      RecoveryPointSEI;       /* tri-state option */
+    mfxU16      ViewOutput;             /* tri-state option */
+    mfxU16      NalHrdConformance;      /* tri-state option */
+    mfxU16      SingleSeiNalUnit;       /* tri-state option */
+    mfxU16      VuiVclHrdParameters;    /* tri-state option */
+
+    mfxU16      RefPicListReordering;   /* tri-state option */
+    mfxU16      ResetRefList;           /* tri-state option */
+    mfxU16      RefPicMarkRep;          /* tri-state option */
+    mfxU16      FieldOutput;            /* tri-state option */
+
+    mfxU16      IntraPredBlockSize;
+    mfxU16      InterPredBlockSize;
+    mfxU16      MVPrecision;
+    mfxU16      MaxDecFrameBuffering;
+
+    mfxU16      AUDelimiter;            /* tri-state option */
+    mfxU16      EndOfStream;            /* tri-state option */
+    mfxU16      PicTimingSEI;           /* tri-state option */
+    mfxU16      VuiNalHrdParameters;    /* tri-state option */
+} mfxExtCodingOption;
+
+enum {
+    MFX_B_REF_UNKNOWN = 0,
+    MFX_B_REF_OFF     = 1,
+    MFX_B_REF_PYRAMID = 2
+};
+
+enum {
+    MFX_LOOKAHEAD_DS_UNKNOWN = 0,
+    MFX_LOOKAHEAD_DS_OFF     = 1,
+    MFX_LOOKAHEAD_DS_2x      = 2,
+    MFX_LOOKAHEAD_DS_4x      = 3
+};
+
+enum {
+    MFX_BPSEI_DEFAULT = 0x00,
+    MFX_BPSEI_IFRAME  = 0x01
+};
+
+enum {
+    MFX_SKIPFRAME_NO_SKIP         = 0,
+    MFX_SKIPFRAME_INSERT_DUMMY    = 1,
+    MFX_SKIPFRAME_INSERT_NOTHING  = 2,
+    MFX_SKIPFRAME_BRC_ONLY        = 3,
+};
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16      IntRefType;
+    mfxU16      IntRefCycleSize;
+    mfxI16      IntRefQPDelta;
+
+    mfxU32      MaxFrameSize;
+    mfxU32      MaxSliceSize;
+
+    mfxU16      BitrateLimit;           /* tri-state option */
+    mfxU16      MBBRC;                  /* tri-state option */
+    mfxU16      ExtBRC;                 /* tri-state option */
+    mfxU16      LookAheadDepth;
+    mfxU16      Trellis;
+    mfxU16      RepeatPPS;              /* tri-state option */
+    mfxU16      BRefType;
+    mfxU16      AdaptiveI;              /* tri-state option */
+    mfxU16      AdaptiveB;              /* tri-state option */
+    mfxU16      LookAheadDS;
+    mfxU16      NumMbPerSlice;
+    mfxU16      SkipFrame;
+    mfxU8       MinQPI;                 /* 1..51, 0 = default */
+    mfxU8       MaxQPI;                 /* 1..51, 0 = default */
+    mfxU8       MinQPP;                 /* 1..51, 0 = default */
+    mfxU8       MaxQPP;                 /* 1..51, 0 = default */
+    mfxU8       MinQPB;                 /* 1..51, 0 = default */
+    mfxU8       MaxQPB;                 /* 1..51, 0 = default */
+    mfxU16      FixedFrameRate;         /* tri-state option */
+    mfxU16      DisableDeblockingIdc;
+    mfxU16      DisableVUI;
+    mfxU16      BufferingPeriodSEI;
+    mfxU16      EnableMAD;              /* tri-state option */
+    mfxU16      UseRawRef;              /* tri-state option */
+} mfxExtCodingOption2;
+
+/* WeightedPred */
+enum {
+    MFX_WEIGHTED_PRED_UNKNOWN  = 0,
+    MFX_WEIGHTED_PRED_DEFAULT  = 1,
+    MFX_WEIGHTED_PRED_EXPLICIT = 2,
+    MFX_WEIGHTED_PRED_IMPLICIT = 3
+};
+
+/* ScenarioInfo */
+enum {
+    MFX_SCENARIO_UNKNOWN             = 0,
+    MFX_SCENARIO_DISPLAY_REMOTING    = 1,
+    MFX_SCENARIO_VIDEO_CONFERENCE    = 2,
+    MFX_SCENARIO_ARCHIVE             = 3,
+    MFX_SCENARIO_LIVE_STREAMING      = 4,
+    MFX_SCENARIO_CAMERA_CAPTURE      = 5
+};
+
+/* ContentInfo */
+enum {
+    MFX_CONTENT_UNKNOWN              = 0,
+    MFX_CONTENT_FULL_SCREEN_VIDEO    = 1,
+    MFX_CONTENT_NON_VIDEO_SCREEN     = 2
+};
+
+/* PRefType */
+enum {
+    MFX_P_REF_DEFAULT = 0,
+    MFX_P_REF_SIMPLE  = 1,
+    MFX_P_REF_PYRAMID = 2
+};
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16      NumSliceI;
+    mfxU16      NumSliceP;
+    mfxU16      NumSliceB;
+
+    mfxU16      WinBRCMaxAvgKbps;
+    mfxU16      WinBRCSize;
+
+    mfxU16      QVBRQuality;
+    mfxU16      EnableMBQP;
+    mfxU16      IntRefCycleDist;
+    mfxU16      DirectBiasAdjustment;          /* tri-state option */
+    mfxU16      GlobalMotionBiasAdjustment;    /* tri-state option */
+    mfxU16      MVCostScalingFactor;
+    mfxU16      MBDisableSkipMap;              /* tri-state option */
+
+    mfxU16      WeightedPred;
+    mfxU16      WeightedBiPred;
+
+    mfxU16      AspectRatioInfoPresent;         /* tri-state option */
+    mfxU16      OverscanInfoPresent;            /* tri-state option */
+    mfxU16      OverscanAppropriate;            /* tri-state option */
+    mfxU16      TimingInfoPresent;              /* tri-state option */
+    mfxU16      BitstreamRestriction;           /* tri-state option */
+    mfxU16      reserved1[4];
+
+    mfxU16      ScenarioInfo;
+    mfxU16      ContentInfo;
+
+    mfxU16      PRefType;
+    mfxU16      FadeDetection;            /* tri-state option */
+    mfxU16      reserved[225];
+} mfxExtCodingOption3;
+
+/* IntraPredBlockSize/InterPredBlockSize */
+enum {
+    MFX_BLOCKSIZE_UNKNOWN   = 0,
+    MFX_BLOCKSIZE_MIN_16X16 = 1, /* 16x16              */
+    MFX_BLOCKSIZE_MIN_8X8   = 2, /* 16x16, 8x8         */
+    MFX_BLOCKSIZE_MIN_4X4   = 3  /* 16x16, 8x8, 4x4    */
+};
+
+/* MVPrecision */
+enum {
+    MFX_MVPRECISION_UNKNOWN    = 0,
+    MFX_MVPRECISION_INTEGER    = (1 << 0),
+    MFX_MVPRECISION_HALFPEL    = (1 << 1),
+    MFX_MVPRECISION_QUARTERPEL = (1 << 2)
+};
+
+enum {
+    MFX_CODINGOPTION_UNKNOWN    =0,
+    MFX_CODINGOPTION_ON         =0x10,
+    MFX_CODINGOPTION_OFF        =0x20,
+    MFX_CODINGOPTION_ADAPTIVE   =0x30
+};
+
+/* Data Flag for mfxBitstream*/
+enum {
+    MFX_BITSTREAM_COMPLETE_FRAME    = 0x0001,        /* the bitstream contains a complete frame or field pair of data */
+    MFX_BITSTREAM_EOS               = 0x0002
+};
+
+/* Extended Buffer Ids */
+enum {
+    MFX_EXTBUFF_CODING_OPTION              = MFX_MAKEFOURCC('C','D','O','P'),
+    MFX_EXTBUFF_CODING_OPTION_SPSPPS       = MFX_MAKEFOURCC('C','O','S','P'),
+    MFX_EXTBUFF_VPP_DONOTUSE               = MFX_MAKEFOURCC('N','U','S','E'),
+    MFX_EXTBUFF_VPP_AUXDATA                = MFX_MAKEFOURCC('A','U','X','D'),
+    MFX_EXTBUFF_VPP_DENOISE                = MFX_MAKEFOURCC('D','N','I','S'),
+    MFX_EXTBUFF_VPP_SCENE_ANALYSIS         = MFX_MAKEFOURCC('S','C','L','Y'),
+    MFX_EXTBUFF_VPP_SCENE_CHANGE           = MFX_EXTBUFF_VPP_SCENE_ANALYSIS,
+    MFX_EXTBUFF_VPP_PROCAMP                = MFX_MAKEFOURCC('P','A','M','P'),
+    MFX_EXTBUFF_VPP_DETAIL                 = MFX_MAKEFOURCC('D','E','T',' '),
+    MFX_EXTBUFF_VIDEO_SIGNAL_INFO          = MFX_MAKEFOURCC('V','S','I','N'),
+    MFX_EXTBUFF_VPP_DOUSE                  = MFX_MAKEFOURCC('D','U','S','E'),
+    MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION  = MFX_MAKEFOURCC('O','P','Q','S'),
+    MFX_EXTBUFF_AVC_REFLIST_CTRL           = MFX_MAKEFOURCC('R','L','S','T'),
+    MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION  = MFX_MAKEFOURCC('F','R','C',' '),
+    MFX_EXTBUFF_PICTURE_TIMING_SEI         = MFX_MAKEFOURCC('P','T','S','E'),
+    MFX_EXTBUFF_AVC_TEMPORAL_LAYERS        = MFX_MAKEFOURCC('A','T','M','L'),
+    MFX_EXTBUFF_CODING_OPTION2             = MFX_MAKEFOURCC('C','D','O','2'),
+    MFX_EXTBUFF_VPP_IMAGE_STABILIZATION    = MFX_MAKEFOURCC('I','S','T','B'),
+    MFX_EXTBUFF_VPP_PICSTRUCT_DETECTION    = MFX_MAKEFOURCC('I','D','E','T'),
+    MFX_EXTBUFF_ENCODER_CAPABILITY         = MFX_MAKEFOURCC('E','N','C','P'),
+    MFX_EXTBUFF_ENCODER_RESET_OPTION       = MFX_MAKEFOURCC('E','N','R','O'),
+    MFX_EXTBUFF_ENCODED_FRAME_INFO         = MFX_MAKEFOURCC('E','N','F','I'),
+    MFX_EXTBUFF_VPP_COMPOSITE              = MFX_MAKEFOURCC('V','C','M','P'),
+    MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO      = MFX_MAKEFOURCC('V','V','S','I'),
+    MFX_EXTBUFF_ENCODER_ROI                = MFX_MAKEFOURCC('E','R','O','I'),
+    MFX_EXTBUFF_VPP_DEINTERLACING          = MFX_MAKEFOURCC('V','P','D','I'),
+    MFX_EXTBUFF_AVC_REFLISTS               = MFX_MAKEFOURCC('R','L','T','S'),
+    MFX_EXTBUFF_VPP_FIELD_PROCESSING       = MFX_MAKEFOURCC('F','P','R','O'),
+    MFX_EXTBUFF_CODING_OPTION3             = MFX_MAKEFOURCC('C','D','O','3'),
+    MFX_EXTBUFF_CHROMA_LOC_INFO            = MFX_MAKEFOURCC('C','L','I','N'),
+    MFX_EXTBUFF_MBQP                       = MFX_MAKEFOURCC('M','B','Q','P'),
+    MFX_EXTBUFF_HEVC_TILES                 = MFX_MAKEFOURCC('2','6','5','T'),
+    MFX_EXTBUFF_MB_DISABLE_SKIP_MAP        = MFX_MAKEFOURCC('M','D','S','M'),
+    MFX_EXTBUFF_HEVC_PARAM                 = MFX_MAKEFOURCC('2','6','5','P'),
+    MFX_EXTBUFF_DECODED_FRAME_INFO         = MFX_MAKEFOURCC('D','E','F','I'),
+    MFX_EXTBUFF_TIME_CODE                  = MFX_MAKEFOURCC('T','M','C','D'),
+    MFX_EXTBUFF_HEVC_REGION                = MFX_MAKEFOURCC('2','6','5','R'),
+    MFX_EXTBUFF_PRED_WEIGHT_TABLE          = MFX_MAKEFOURCC('E','P','W','T'),
+    MFX_EXTBUFF_DIRTY_RECTANGLES           = MFX_MAKEFOURCC('D','R','O','I'),
+    MFX_EXTBUFF_MOVING_RECTANGLES          = MFX_MAKEFOURCC('M','R','O','I'),
+    MFX_EXTBUFF_CODING_OPTION_VPS          = MFX_MAKEFOURCC('C','O','V','P'),
+    MFX_EXTBUFF_VPP_ROTATION               = MFX_MAKEFOURCC('R','O','T',' ')
+};
+
+/* VPP Conf: Do not use certain algorithms  */
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU32          NumAlg;
+    mfxU32*         AlgList;
+} mfxExtVPPDoNotUse;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16  DenoiseFactor;
+} mfxExtVPPDenoise;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16  DetailFactor;
+} mfxExtVPPDetail;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxF64   Brightness;
+    mfxF64   Contrast;
+    mfxF64   Hue;
+    mfxF64   Saturation;
+} mfxExtVPPProcAmp;
+
+/* statistics collected for decode, encode and vpp */
+typedef struct {
+    mfxU32  reserved[16];
+    mfxU32  NumFrame;
+    mfxU64  NumBit;
+    mfxU32  NumCachedFrame;
+} mfxEncodeStat;
+
+typedef struct {
+    mfxU32  reserved[16];
+    mfxU32  NumFrame;
+    mfxU32  NumSkippedFrame;
+    mfxU32  NumError;
+    mfxU32  NumCachedFrame;
+} mfxDecodeStat;
+
+typedef struct {
+    mfxU32  reserved[16];
+    mfxU32  NumFrame;
+    mfxU32  NumCachedFrame;
+} mfxVPPStat;
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    union{
+        struct{
+            mfxU32  SpatialComplexity;
+            mfxU32  TemporalComplexity;
+        };
+        struct{
+            mfxU16  PicStruct;
+            mfxU16  reserved[3];
+        };
+    };
+    mfxU16          SceneChangeRate;
+    mfxU16          RepeatedFrame;
+} mfxExtVppAuxData;
+
+typedef struct {
+    mfxU32      reserved[4];
+    mfxU8       *Data;      /* buffer pointer */
+    mfxU32      NumBit;     /* number of bits */
+    mfxU16      Type;       /* SEI message type in H.264 or user data start_code in MPEG-2 */
+    mfxU16      BufSize;    /* payload buffer size in bytes */
+} mfxPayload;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU32  reserved[5];
+    mfxU16  SkipFrame;
+
+    mfxU16  QP; /* per frame QP */
+
+    mfxU16  FrameType;
+    mfxU16  NumExtParam;
+    mfxU16  NumPayload;     /* MPEG-2 user data or H.264 SEI message(s) */
+    mfxU16  reserved2;
+
+    mfxExtBuffer    **ExtParam;
+    mfxPayload      **Payload;      /* for field pair, first field uses even payloads and second field uses odd payloads */
+} mfxEncodeCtrl;
+
+/* Buffer Memory Types */
+enum {
+    /* Buffer types */
+    MFX_MEMTYPE_PERSISTENT_MEMORY   =0x0002
+};
+
+/* Frame Memory Types */
+#define MFX_MEMTYPE_BASE(x) (0xf0ff & (x))
+
+enum {
+    MFX_MEMTYPE_DXVA2_DECODER_TARGET       =0x0010,
+    MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET     =0x0020,
+    MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET   = MFX_MEMTYPE_DXVA2_DECODER_TARGET,
+    MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET = MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET,
+    MFX_MEMTYPE_SYSTEM_MEMORY              =0x0040,
+    MFX_MEMTYPE_RESERVED1                  =0x0080,
+
+    MFX_MEMTYPE_FROM_ENCODE     = 0x0100,
+    MFX_MEMTYPE_FROM_DECODE     = 0x0200,
+    MFX_MEMTYPE_FROM_VPPIN      = 0x0400,
+    MFX_MEMTYPE_FROM_VPPOUT     = 0x0800,
+
+    MFX_MEMTYPE_INTERNAL_FRAME  = 0x0001,
+    MFX_MEMTYPE_EXTERNAL_FRAME  = 0x0002,
+    MFX_MEMTYPE_OPAQUE_FRAME    = 0x0004,
+    MFX_MEMTYPE_EXPORT_FRAME    = 0x0008,
+
+    MFX_MEMTYPE_RESERVED2       = 0x1000
+};
+
+typedef struct {
+    union {
+        mfxU32  AllocId;
+        mfxU32  reserved[1];
+    };
+    mfxU32  reserved3[3];
+    mfxFrameInfo    Info;
+    mfxU16  Type;   /* decoder or processor render targets */
+    mfxU16  NumFrameMin;
+    mfxU16  NumFrameSuggested;
+    mfxU16  reserved2;
+} mfxFrameAllocRequest;
+
+typedef struct {
+    mfxU32      AllocId;
+    mfxU32      reserved[3];
+    mfxMemId    *mids;      /* the array allocated by application */
+    mfxU16      NumFrameActual;
+    mfxU16      reserved2;
+} mfxFrameAllocResponse;
+
+/* FrameType */
+enum {
+    MFX_FRAMETYPE_UNKNOWN       =0x0000,
+
+    MFX_FRAMETYPE_I             =0x0001,
+    MFX_FRAMETYPE_P             =0x0002,
+    MFX_FRAMETYPE_B             =0x0004,
+    MFX_FRAMETYPE_S             =0x0008,
+
+    MFX_FRAMETYPE_REF           =0x0040,
+    MFX_FRAMETYPE_IDR           =0x0080,
+
+    MFX_FRAMETYPE_xI            =0x0100,
+    MFX_FRAMETYPE_xP            =0x0200,
+    MFX_FRAMETYPE_xB            =0x0400,
+    MFX_FRAMETYPE_xS            =0x0800,
+
+    MFX_FRAMETYPE_xREF          =0x4000,
+    MFX_FRAMETYPE_xIDR          =0x8000
+};
+
+typedef enum {
+    MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9         =1,      /* IDirect3DDeviceManager9      */
+    MFX_HANDLE_D3D9_DEVICE_MANAGER              = MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9,
+    MFX_HANDLE_RESERVED1                        = 2,
+    MFX_HANDLE_D3D11_DEVICE                     = 3,
+    MFX_HANDLE_VA_DISPLAY                       = 4,
+    MFX_HANDLE_RESERVED3                        = 5
+} mfxHandleType;
+
+typedef enum {
+    MFX_SKIPMODE_NOSKIP=0,
+    MFX_SKIPMODE_MORE=1,
+    MFX_SKIPMODE_LESS=2
+} mfxSkipMode;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU8           *SPSBuffer;
+    mfxU8           *PPSBuffer;
+    mfxU16          SPSBufSize;
+    mfxU16          PPSBufSize;
+    mfxU16          SPSId;
+    mfxU16          PPSId;
+} mfxExtCodingOptionSPSPPS;
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    union {
+        mfxU8       *VPSBuffer;
+        mfxU64      reserved1;
+    };
+    mfxU16          VPSBufSize;
+    mfxU16          VPSId;
+
+    mfxU16          reserved[6];
+} mfxExtCodingOptionVPS;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16          VideoFormat;
+    mfxU16          VideoFullRange;
+    mfxU16          ColourDescriptionPresent;
+    mfxU16          ColourPrimaries;
+    mfxU16          TransferCharacteristics;
+    mfxU16          MatrixCoefficients;
+} mfxExtVideoSignalInfo;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU32          NumAlg;
+    mfxU32          *AlgList;
+} mfxExtVPPDoUse;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU32      reserved1[2];
+    struct {
+        mfxFrameSurface1 **Surfaces;
+        mfxU32  reserved2[5];
+        mfxU16  Type;
+        mfxU16  NumSurface;
+    } In, Out;
+} mfxExtOpaqueSurfaceAlloc;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16          NumRefIdxL0Active;
+    mfxU16          NumRefIdxL1Active;
+
+    struct {
+        mfxU32      FrameOrder;
+        mfxU16      PicStruct;
+        mfxU16      ViewId;
+        mfxU16      LongTermIdx;
+        mfxU16      reserved[3];
+    } PreferredRefList[32], RejectedRefList[16], LongTermRefList[16];
+
+    mfxU16      ApplyLongTermIdx;
+    mfxU16      reserved[15];
+} mfxExtAVCRefListCtrl;
+
+enum {
+    MFX_FRCALGM_PRESERVE_TIMESTAMP    = 0x0001,
+    MFX_FRCALGM_DISTRIBUTED_TIMESTAMP = 0x0002,
+    MFX_FRCALGM_FRAME_INTERPOLATION   = 0x0004
+};
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16      Algorithm;
+    mfxU16      reserved;
+    mfxU32      reserved2[15];
+} mfxExtVPPFrameRateConversion;
+
+enum {
+    MFX_IMAGESTAB_MODE_UPSCALE = 0x0001,
+    MFX_IMAGESTAB_MODE_BOXING  = 0x0002
+};
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16  Mode;
+    mfxU16  reserved[11];
+} mfxExtVPPImageStab;
+
+typedef struct {
+  mfxExtBuffer    Header;
+  mfxU32      reserved[14];
+
+  struct {
+      mfxU16    ClockTimestampFlag;
+      mfxU16    CtType;
+      mfxU16    NuitFieldBasedFlag;
+      mfxU16    CountingType;
+      mfxU16    FullTimestampFlag;
+      mfxU16    DiscontinuityFlag;
+      mfxU16    CntDroppedFlag;
+      mfxU16    NFrames;
+      mfxU16    SecondsFlag;
+      mfxU16    MinutesFlag;
+      mfxU16    HoursFlag;
+      mfxU16    SecondsValue;
+      mfxU16    MinutesValue;
+      mfxU16    HoursValue;
+      mfxU32    TimeOffset;
+  } TimeStamp[3];
+} mfxExtPictureTimingSEI;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU32          reserved1[4];
+    mfxU16          reserved2;
+    mfxU16          BaseLayerPID;
+
+    struct {
+        mfxU16 Scale;
+        mfxU16 reserved[3];
+    }Layer[8];
+} mfxExtAvcTemporalLayers;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU32      MBPerSec;
+    mfxU16      reserved[58];
+} mfxExtEncoderCapability;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16      StartNewSequence;
+    mfxU16      reserved[11];
+} mfxExtEncoderResetOption;
+
+/*LongTermIdx*/
+enum {
+    MFX_LONGTERM_IDX_NO_IDX = 0xFFFF
+};
+
+typedef struct {
+    mfxExtBuffer    Header; 
+
+    mfxU32          FrameOrder;
+    mfxU16          PicStruct;
+    mfxU16          LongTermIdx;
+    mfxU32          MAD;
+    mfxU16          BRCPanicMode;
+    mfxU16          QP;
+    mfxU32          SecondFieldOffset;
+    mfxU16          reserved[2];
+
+    struct {
+            mfxU32      FrameOrder;
+            mfxU16      PicStruct;
+            mfxU16      LongTermIdx;
+            mfxU16      reserved[4];
+    } UsedRefListL0[32], UsedRefListL1[32];
+} mfxExtAVCEncodedFrameInfo;
+
+typedef struct mfxVPPCompInputStream {
+        mfxU32  DstX;
+        mfxU32  DstY;
+        mfxU32  DstW;
+        mfxU32  DstH;
+
+        mfxU16  LumaKeyEnable;
+        mfxU16  LumaKeyMin;
+        mfxU16  LumaKeyMax;
+
+        mfxU16  GlobalAlphaEnable;
+        mfxU16  GlobalAlpha;
+
+        mfxU16 PixelAlphaEnable;
+
+        mfxU16  reserved2[18];
+} mfxVPPCompInputStream;     
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    /* background color*/
+    union {
+        mfxU16   Y;
+        mfxU16   R;
+    };
+    union {
+        mfxU16   U;
+        mfxU16   G;
+    };
+    union {
+        mfxU16   V;
+        mfxU16   B;
+    };
+
+    mfxU16      reserved1[24];
+
+    mfxU16      NumInputStream;
+    mfxVPPCompInputStream *InputStream;     
+} mfxExtVPPComposite;
+
+/* TransferMatrix */
+enum {
+    MFX_TRANSFERMATRIX_UNKNOWN = 0,
+    MFX_TRANSFERMATRIX_BT709   = 1,
+    MFX_TRANSFERMATRIX_BT601   = 2
+};
+
+/* NominalRange */
+enum {
+    MFX_NOMINALRANGE_UNKNOWN   = 0,
+    MFX_NOMINALRANGE_0_255     = 1,
+    MFX_NOMINALRANGE_16_235    = 2
+};
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16          reserved1[4];
+
+    struct  {
+        mfxU16  TransferMatrix;
+        mfxU16  NominalRange;
+        mfxU16  reserved2[6];
+    } In, Out;
+} mfxExtVPPVideoSignalInfo;
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU16  NumROI;
+    mfxU16  reserved1[11];
+
+    struct  {
+        mfxU32  Left;
+        mfxU32  Top;
+        mfxU32  Right;
+        mfxU32  Bottom;
+
+        mfxI16  Priority;
+        mfxU16  reserved2[7];
+    } ROI[256];
+} mfxExtEncoderROI;
+
+/*Deinterlacing Mode*/
+enum {
+    MFX_DEINTERLACING_BOB                    =  1,
+    MFX_DEINTERLACING_ADVANCED               =  2,
+    MFX_DEINTERLACING_AUTO_DOUBLE            =  3,
+    MFX_DEINTERLACING_AUTO_SINGLE            =  4,
+    MFX_DEINTERLACING_FULL_FR_OUT            =  5,
+    MFX_DEINTERLACING_HALF_FR_OUT            =  6,
+    MFX_DEINTERLACING_24FPS_OUT              =  7,
+    MFX_DEINTERLACING_FIXED_TELECINE_PATTERN =  8,
+    MFX_DEINTERLACING_30FPS_OUT              =  9,
+    MFX_DEINTERLACING_DETECT_INTERLACE       = 10,
+    MFX_DEINTERLACING_ADVANCED_NOREF         = 11
+};
+
+/*TelecinePattern*/
+enum {
+    MFX_TELECINE_PATTERN_32           = 0,
+    MFX_TELECINE_PATTERN_2332         = 1,
+    MFX_TELECINE_PATTERN_FRAME_REPEAT = 2,
+    MFX_TELECINE_PATTERN_41           = 3,
+    MFX_TELECINE_POSITION_PROVIDED    = 4
+};
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16  Mode;
+    mfxU16  TelecinePattern;
+    mfxU16  TelecineLocation;
+    mfxU16  reserved[9];
+} mfxExtVPPDeinterlacing;
+
+typedef struct {
+    mfxExtBuffer    Header;
+    mfxU16          NumRefIdxL0Active;
+    mfxU16          NumRefIdxL1Active;
+    mfxU16          reserved[2];
+
+    struct mfxRefPic{
+        mfxU32      FrameOrder;
+        mfxU16      PicStruct;
+        mfxU16      reserved[5];
+    } RefPicList0[32], RefPicList1[32];
+
+}mfxExtAVCRefLists;
+
+enum {
+    MFX_VPP_COPY_FRAME      =0x01,
+    MFX_VPP_COPY_FIELD      =0x02,
+    MFX_VPP_SWAP_FIELDS     =0x03
+};
+
+/*PicType*/
+enum {
+    MFX_PICTYPE_UNKNOWN     =0x00,
+    MFX_PICTYPE_FRAME       =0x01,
+    MFX_PICTYPE_TOPFIELD    =0x02,
+    MFX_PICTYPE_BOTTOMFIELD =0x04
+};
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU16          Mode;
+    mfxU16          InField;
+    mfxU16          OutField;
+    mfxU16          reserved[25];
+} mfxExtVPPFieldProcessing;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16       ChromaLocInfoPresentFlag;
+    mfxU16       ChromaSampleLocTypeTopField;
+    mfxU16       ChromaSampleLocTypeBottomField;
+    mfxU16       reserved[9];
+} mfxExtChromaLocInfo;
+
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU32 reserved[11];
+    mfxU32 NumQPAlloc;
+    union {
+        mfxU8  *QP;
+        mfxU64 reserved2;
+    };
+} mfxExtMBQP;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16 NumTileRows;
+    mfxU16 NumTileColumns;
+    mfxU16 reserved[74];
+}mfxExtHEVCTiles;
+
+typedef struct {
+    mfxExtBuffer Header;
+    
+    mfxU32 reserved[11];
+    mfxU32 MapSize;
+    union {
+        mfxU8  *Map;
+        mfxU64  reserved2;
+    };
+} mfxExtMBDisableSkipMap;
+
+/*GeneralConstraintFlags*/
+enum {
+    /* REXT Profile constraint flags*/
+    MFX_HEVC_CONSTR_REXT_MAX_12BIT          = (1 << 0),
+    MFX_HEVC_CONSTR_REXT_MAX_10BIT          = (1 << 1),
+    MFX_HEVC_CONSTR_REXT_MAX_8BIT           = (1 << 2),
+    MFX_HEVC_CONSTR_REXT_MAX_422CHROMA      = (1 << 3),
+    MFX_HEVC_CONSTR_REXT_MAX_420CHROMA      = (1 << 4),
+    MFX_HEVC_CONSTR_REXT_MAX_MONOCHROME     = (1 << 5),
+    MFX_HEVC_CONSTR_REXT_INTRA              = (1 << 6),
+    MFX_HEVC_CONSTR_REXT_ONE_PICTURE_ONLY   = (1 << 7),
+    MFX_HEVC_CONSTR_REXT_LOWER_BIT_RATE     = (1 << 8)
+};
+
+#pragma pack(push, 4)
+typedef struct {
+    mfxExtBuffer    Header;
+
+    mfxU16          PicWidthInLumaSamples;
+    mfxU16          PicHeightInLumaSamples;
+    mfxU64          GeneralConstraintFlags;
+    mfxU16          reserved[118];
+} mfxExtHEVCParam;
+#pragma pack(pop)
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16       FrameType;
+    mfxU16       reserved[59];
+} mfxExtDecodedFrameInfo;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16       DropFrameFlag;
+    mfxU16       TimeCodeHours;
+    mfxU16       TimeCodeMinutes;
+    mfxU16       TimeCodeSeconds;
+    mfxU16       TimeCodePictures;
+    mfxU16       reserved[7];
+} mfxExtTimeCode;
+
+/*RegionType*/
+enum {
+    MFX_HEVC_REGION_SLICE = 0
+};
+
+/*RegionEncoding*/
+enum {
+    MFX_HEVC_REGION_ENCODING_ON  = 0,
+    MFX_HEVC_REGION_ENCODING_OFF = 1
+};
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU32       RegionId;
+    mfxU16       RegionType;
+    mfxU16       RegionEncoding;
+    mfxU16       reserved[24];
+} mfxExtHEVCRegion;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16       LumaLog2WeightDenom;       // 0..7
+    mfxU16       ChromaLog2WeightDenom;     // 0..7
+    mfxU16       LumaWeightFlag[2][32];     // [list] 0,1
+    mfxU16       ChromaWeightFlag[2][32];   // [list] 0,1
+    mfxI16       Weights[2][32][3][2];      // [list][list entry][Y, Cb, Cr][weight, offset]
+    mfxU16       reserved[58];
+} mfxExtPredWeightTable;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16  NumRect;
+    mfxU16  reserved1[11];
+
+    struct {
+        mfxU32  Left;
+        mfxU32  Top;
+        mfxU32  Right;
+        mfxU32  Bottom;
+
+        mfxU16  reserved2[8];
+    } Rect[256];
+} mfxExtDirtyRect;
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16  NumRect;
+    mfxU16  reserved1[11];
+
+    struct {
+        mfxU32  DestLeft;
+        mfxU32  DestTop;
+        mfxU32  DestRight;
+        mfxU32  DestBottom;
+
+        mfxU32  SourceLeft;
+        mfxU32  SourceTop;
+        mfxU16  reserved2[4];
+    } Rect[256];
+} mfxExtMoveRect;
+
+/* Angle */
+enum {
+    MFX_ANGLE_0     =   0,
+    MFX_ANGLE_90    =  90,
+    MFX_ANGLE_180   = 180,
+    MFX_ANGLE_270   = 270
+};
+
+typedef struct {
+    mfxExtBuffer Header;
+
+    mfxU16 Angle;
+    mfxU16 reserved[11];
+} mfxExtVPPRotation;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
+

+ 197 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo++.h

@@ -0,0 +1,197 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2007-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+File Name: mfxvideo++.h
+
+\* ****************************************************************************** */
+
+#ifndef __MFXVIDEOPLUSPLUS_H
+#define __MFXVIDEOPLUSPLUS_H
+
+#include "mfxvideo.h"
+#include "mfxenc.h"
+#include "mfxpak.h"
+
+class MFXVideoSession
+{
+public:
+    MFXVideoSession(void) { m_session = (mfxSession) 0; }
+    virtual ~MFXVideoSession(void) { Close(); }
+
+    virtual mfxStatus Init(mfxIMPL impl, mfxVersion *ver) { return MFXInit(impl, ver, &m_session); }
+    virtual mfxStatus InitEx(mfxInitParam par) { return MFXInitEx(par, &m_session); }
+    virtual mfxStatus Close(void)
+    {
+        mfxStatus mfxRes;
+        mfxRes = MFXClose(m_session); m_session = (mfxSession) 0;
+        return mfxRes;
+    }
+
+    virtual mfxStatus QueryIMPL(mfxIMPL *impl) { return MFXQueryIMPL(m_session, impl); }
+    virtual mfxStatus QueryVersion(mfxVersion *version) { return MFXQueryVersion(m_session, version); }
+
+    virtual mfxStatus JoinSession(mfxSession child_session) { return MFXJoinSession(m_session, child_session);}
+    virtual mfxStatus DisjoinSession( ) { return MFXDisjoinSession(m_session);}
+    virtual mfxStatus CloneSession( mfxSession *clone) { return MFXCloneSession(m_session, clone);}
+    virtual mfxStatus SetPriority( mfxPriority priority) { return MFXSetPriority(m_session, priority);}
+    virtual mfxStatus GetPriority( mfxPriority *priority) { return MFXGetPriority(m_session, priority);}
+
+    virtual mfxStatus SetBufferAllocator(mfxBufferAllocator *allocator) { return MFXVideoCORE_SetBufferAllocator(m_session, allocator); }
+    virtual mfxStatus SetFrameAllocator(mfxFrameAllocator *allocator) { return MFXVideoCORE_SetFrameAllocator(m_session, allocator); }
+    virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl) { return MFXVideoCORE_SetHandle(m_session, type, hdl); }
+    virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *hdl) { return MFXVideoCORE_GetHandle(m_session, type, hdl); }
+
+    virtual mfxStatus SyncOperation(mfxSyncPoint syncp, mfxU32 wait) { return MFXVideoCORE_SyncOperation(m_session, syncp, wait); }
+
+    virtual mfxStatus DoWork() { return MFXDoWork(m_session); }
+
+    virtual operator mfxSession (void) { return m_session; }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+private:
+    MFXVideoSession(const MFXVideoSession &);
+    void operator=(MFXVideoSession &);
+};
+
+class MFXVideoENCODE
+{
+public:
+
+    MFXVideoENCODE(mfxSession session) { m_session = session; }
+    virtual ~MFXVideoENCODE(void) { Close(); }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoENCODE_Query(m_session, in, out); }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoENCODE_QueryIOSurf(m_session, par, request); }
+    virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoENCODE_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoENCODE_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXVideoENCODE_Close(m_session); }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoENCODE_GetVideoParam(m_session, par); }
+    virtual mfxStatus GetEncodeStat(mfxEncodeStat *stat) { return MFXVideoENCODE_GetEncodeStat(m_session, stat); }
+
+    virtual mfxStatus EncodeFrameAsync(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp) { return MFXVideoENCODE_EncodeFrameAsync(m_session, ctrl, surface, bs, syncp); }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+class MFXVideoDECODE
+{
+public:
+
+    MFXVideoDECODE(mfxSession session) { m_session = session; }
+    virtual ~MFXVideoDECODE(void) { Close(); }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoDECODE_Query(m_session, in, out); }
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) { return MFXVideoDECODE_DecodeHeader(m_session, bs, par); }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoDECODE_QueryIOSurf(m_session, par, request); }
+    virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoDECODE_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoDECODE_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXVideoDECODE_Close(m_session); }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoDECODE_GetVideoParam(m_session, par); }
+
+    virtual mfxStatus GetDecodeStat(mfxDecodeStat *stat) { return MFXVideoDECODE_GetDecodeStat(m_session, stat); }
+    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) {return MFXVideoDECODE_GetPayload(m_session, ts, payload); }
+    virtual mfxStatus SetSkipMode(mfxSkipMode mode) { return MFXVideoDECODE_SetSkipMode(m_session, mode); }
+    virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp) { return MFXVideoDECODE_DecodeFrameAsync(m_session, bs, surface_work, surface_out, syncp); }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+class MFXVideoVPP
+{
+public:
+
+    MFXVideoVPP(mfxSession session) { m_session = session; }
+    virtual ~MFXVideoVPP(void) { Close(); }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoVPP_Query(m_session, in, out); }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest request[2]) { return MFXVideoVPP_QueryIOSurf(m_session, par, request); }
+    virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoVPP_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoVPP_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXVideoVPP_Close(m_session); }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoVPP_GetVideoParam(m_session, par); }
+    virtual mfxStatus GetVPPStat(mfxVPPStat *stat) { return MFXVideoVPP_GetVPPStat(m_session, stat); }
+    virtual mfxStatus RunFrameVPPAsync(mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp) { return MFXVideoVPP_RunFrameVPPAsync(m_session, in, out, aux, syncp); }
+    virtual mfxStatus RunFrameVPPAsyncEx(mfxFrameSurface1 *in, mfxFrameSurface1 *work, mfxFrameSurface1 **out, mfxSyncPoint *syncp) {return MFXVideoVPP_RunFrameVPPAsyncEx(m_session, in, work, out, syncp); }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+class MFXVideoENC
+{
+public:
+
+    MFXVideoENC(mfxSession session) { m_session = session; }
+    virtual ~MFXVideoENC(void) { Close(); }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoENC_Query(m_session, in, out); }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoENC_QueryIOSurf(m_session, par, request); }
+    virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoENC_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoENC_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXVideoENC_Close(m_session); }
+
+    virtual mfxStatus ProcessFrameAsync(mfxENCInput *in, mfxENCOutput *out, mfxSyncPoint *syncp) { return MFXVideoENC_ProcessFrameAsync(m_session, in, out, syncp); }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+class MFXVideoPAK
+{
+public:
+
+    MFXVideoPAK(mfxSession session) { m_session = session; }
+    virtual ~MFXVideoPAK(void) { Close(); }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoPAK_Query(m_session, in, out); }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoPAK_QueryIOSurf(m_session, par, request); }
+    virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoPAK_Init(m_session, par); }
+    virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoPAK_Reset(m_session, par); }
+    virtual mfxStatus Close(void) { return MFXVideoPAK_Close(m_session); }
+
+    //virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoENCODE_GetVideoParam(m_session, par); }
+    //virtual mfxStatus GetEncodeStat(mfxEncodeStat *stat) { return MFXVideoENCODE_GetEncodeStat(m_session, stat); }
+
+    virtual mfxStatus ProcessFrameAsync(mfxPAKInput *in, mfxPAKOutput *out, mfxSyncPoint *syncp) { return MFXVideoPAK_ProcessFrameAsync(m_session, in, out, syncp); }
+
+protected:
+
+    mfxSession m_session;                                       // (mfxSession) handle to the owning session
+};
+
+#endif // __MFXVIDEOPLUSPLUS_H

+ 112 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo.h

@@ -0,0 +1,112 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2007-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxvideo.h
+
+\* ****************************************************************************** */
+#ifndef __MFXVIDEO_H__
+#define __MFXVIDEO_H__
+#include "mfxsession.h"
+#include "mfxvstructures.h"
+
+#define MFX_VERSION_MAJOR 1
+#define MFX_VERSION_MINOR 17
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* MFXVideoCORE */
+typedef struct {
+    mfxU32      reserved[4];
+    mfxHDL      pthis;
+    mfxStatus  (MFX_CDECL *Alloc)    (mfxHDL pthis, mfxU32 nbytes, mfxU16 type, mfxMemId *mid);
+    mfxStatus  (MFX_CDECL *Lock)     (mfxHDL pthis, mfxMemId mid, mfxU8 **ptr);
+    mfxStatus  (MFX_CDECL *Unlock)   (mfxHDL pthis, mfxMemId mid);
+    mfxStatus  (MFX_CDECL *Free)     (mfxHDL pthis, mfxMemId mid);
+} mfxBufferAllocator;
+
+typedef struct {
+    mfxU32      reserved[4];
+    mfxHDL      pthis;
+
+    mfxStatus  (MFX_CDECL  *Alloc)    (mfxHDL pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response);
+    mfxStatus  (MFX_CDECL  *Lock)     (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
+    mfxStatus  (MFX_CDECL  *Unlock)   (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
+    mfxStatus  (MFX_CDECL  *GetHDL)   (mfxHDL pthis, mfxMemId mid, mfxHDL *handle);
+    mfxStatus  (MFX_CDECL  *Free)     (mfxHDL pthis, mfxFrameAllocResponse *response);
+} mfxFrameAllocator;
+
+/* VideoCORE */
+mfxStatus MFX_CDECL MFXVideoCORE_SetBufferAllocator(mfxSession session, mfxBufferAllocator *allocator);
+mfxStatus MFX_CDECL MFXVideoCORE_SetFrameAllocator(mfxSession session, mfxFrameAllocator *allocator);
+mfxStatus MFX_CDECL MFXVideoCORE_SetHandle(mfxSession session, mfxHandleType type, mfxHDL hdl);
+mfxStatus MFX_CDECL MFXVideoCORE_GetHandle(mfxSession session, mfxHandleType type, mfxHDL *hdl);
+mfxStatus MFX_CDECL MFXVideoCORE_SyncOperation(mfxSession session, mfxSyncPoint syncp, mfxU32 wait);
+
+/* VideoENCODE */
+mfxStatus MFX_CDECL MFXVideoENCODE_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+mfxStatus MFX_CDECL MFXVideoENCODE_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request);
+mfxStatus MFX_CDECL MFXVideoENCODE_Init(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoENCODE_Reset(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoENCODE_Close(mfxSession session);
+
+mfxStatus MFX_CDECL MFXVideoENCODE_GetVideoParam(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoENCODE_GetEncodeStat(mfxSession session, mfxEncodeStat *stat);
+mfxStatus MFX_CDECL MFXVideoENCODE_EncodeFrameAsync(mfxSession session, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp);
+
+/* VideoDECODE */
+mfxStatus MFX_CDECL MFXVideoDECODE_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+mfxStatus MFX_CDECL MFXVideoDECODE_DecodeHeader(mfxSession session, mfxBitstream *bs, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoDECODE_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request);
+mfxStatus MFX_CDECL MFXVideoDECODE_Init(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoDECODE_Reset(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoDECODE_Close(mfxSession session);
+
+mfxStatus MFX_CDECL MFXVideoDECODE_GetVideoParam(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoDECODE_GetDecodeStat(mfxSession session, mfxDecodeStat *stat);
+mfxStatus MFX_CDECL MFXVideoDECODE_SetSkipMode(mfxSession session, mfxSkipMode mode);
+mfxStatus MFX_CDECL MFXVideoDECODE_GetPayload(mfxSession session, mfxU64 *ts, mfxPayload *payload);
+mfxStatus MFX_CDECL MFXVideoDECODE_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp);
+
+/* VideoVPP */
+mfxStatus MFX_CDECL MFXVideoVPP_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+mfxStatus MFX_CDECL MFXVideoVPP_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest request[2]);
+mfxStatus MFX_CDECL MFXVideoVPP_Init(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoVPP_Reset(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoVPP_Close(mfxSession session);
+
+mfxStatus MFX_CDECL MFXVideoVPP_GetVideoParam(mfxSession session, mfxVideoParam *par);
+mfxStatus MFX_CDECL MFXVideoVPP_GetVPPStat(mfxSession session, mfxVPPStat *stat);
+mfxStatus MFX_CDECL MFXVideoVPP_RunFrameVPPAsync(mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp);
+mfxStatus MFX_CDECL MFXVideoVPP_RunFrameVPPAsyncEx(mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif

+ 32 - 0
plugins/obs-qsv11/libmfx/include/msdk/include/mfxvstructures.h

@@ -0,0 +1,32 @@
+/*******************************************************************************
+
+Copyright (C) 2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfxvstructures.h
+
+*******************************************************************************/
+#include "mfxstructures.h"
+
+

+ 937 - 0
plugins/obs-qsv11/libmfx/src/main.cpp

@@ -0,0 +1,937 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: main.cpp
+
+\* ****************************************************************************** */
+
+#include "mfx_dispatcher.h"
+#include "mfx_load_dll.h"
+#include "mfx_dispatcher_log.h"
+#include "mfx_library_iterator.h"
+#include "mfx_critical_section.h"
+
+#include <string.h> /* for memset on Linux */
+#include <memory>
+#include <stdlib.h> /* for qsort on Linux */
+#include "mfx_load_plugin.h"
+#include "mfx_plugin_hive.h"
+
+// module-local definitions
+namespace
+{
+
+    const
+    struct
+    {
+        // instance implementation type
+        eMfxImplType implType;
+        // real implementation
+        mfxIMPL impl;
+        // adapter numbers
+        mfxU32 adapterID;
+
+    } implTypes[] =
+    {
+        // MFX_IMPL_AUTO case
+        {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE,  0},
+        {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE,  0},
+
+        // MFX_IMPL_ANY case
+        {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE,  0},
+        {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE2, 1},
+        {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE3, 2},
+        {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE4, 3},
+        {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE,  0},
+        {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE | MFX_IMPL_AUDIO,  0}
+    };
+
+    const
+    struct
+    {
+        // start index in implTypes table for specified implementation
+        mfxU32 minIndex;
+        // last index in implTypes table for specified implementation
+        mfxU32 maxIndex;
+
+    } implTypesRange[] =
+    {    
+        {0, 1},  // MFX_IMPL_AUTO    
+        {1, 1},  // MFX_IMPL_SOFTWARE    
+        {0, 0},  // MFX_IMPL_HARDWARE    
+        {2, 6},  // MFX_IMPL_AUTO_ANY    
+        {2, 5},  // MFX_IMPL_HARDWARE_ANY    
+        {3, 3},  // MFX_IMPL_HARDWARE2    
+        {4, 4},  // MFX_IMPL_HARDWARE3    
+        {5, 5},  // MFX_IMPL_HARDWARE4
+        {2, 6},  // MFX_IMPL_RUNTIME, same as MFX_IMPL_HARDWARE_ANY
+        {7, 7}   // MFX_IMPL_AUDIO
+    };
+
+    MFX::mfxCriticalSection dispGuard = 0;
+
+} // namespace
+
+using namespace MFX;
+//
+// Implement DLL exposed functions. MFXInit and MFXClose have to do
+// slightly more than other. They require to be implemented explicitly.
+// All other functions are implemented implicitly.
+//
+
+typedef MFXVector<MFX_DISP_HANDLE*> HandleVector;
+typedef MFXVector<mfxStatus>        StatusVector;
+
+struct VectorHandleGuard
+{
+    VectorHandleGuard(HandleVector& aVector): m_vector(aVector) {}
+    ~VectorHandleGuard()
+    {
+        HandleVector::iterator it = m_vector.begin(), 
+                               et = m_vector.end();
+        for ( ; it != et; ++it)
+        {
+            delete *it;
+        }
+    }
+
+    HandleVector& m_vector;
+private:
+    void operator=(const VectorHandleGuard&);
+};
+
+
+int HandleSort (const void * plhs, const void * prhs)
+{
+    const MFX_DISP_HANDLE * lhs = *(const MFX_DISP_HANDLE **)plhs;
+    const MFX_DISP_HANDLE * rhs = *(const MFX_DISP_HANDLE **)prhs;
+
+    if (lhs->actualApiVersion < rhs->actualApiVersion) 
+    {
+        return -1;
+    }
+    if (rhs->actualApiVersion < lhs->actualApiVersion) 
+    {
+        return 1;
+    }
+
+    // if versions are equal prefer library with HW 
+    if (lhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION && rhs->loadStatus == MFX_ERR_NONE)
+    {
+        return 1;
+    }
+    if (lhs->loadStatus == MFX_ERR_NONE && rhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION)
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+mfxStatus MFXInit(mfxIMPL impl, mfxVersion *pVer, mfxSession *session)
+{
+    mfxInitParam par = {};
+
+    par.Implementation = impl;
+    if (pVer)
+    {
+        par.Version = *pVer;
+    }
+    else
+    {
+        par.Version.Major = DEFAULT_API_VERSION_MAJOR;
+        par.Version.Minor = DEFAULT_API_VERSION_MINOR;
+    }
+    par.ExternalThreads = 0;
+
+    return MFXInitEx(par, session);
+}
+
+mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session)
+{
+    MFX::MFXAutomaticCriticalSection guard(&dispGuard);
+
+    DISPATCHER_LOG_BLOCK( ("MFXInitEx (impl=%s, pVer=%d.%d, ExternalThreads=%d session=0x%p\n"
+        , DispatcherLog_GetMFXImplString(par.Implementation).c_str()
+        , par.Version.Major
+        , par.Version.Minor
+        , par.ExternalThreads
+        , session));
+
+    mfxStatus mfxRes;
+    HandleVector allocatedHandle;
+    VectorHandleGuard handleGuard(allocatedHandle);
+
+    MFX_DISP_HANDLE *pHandle;
+    msdk_disp_char dllName[MFX_MAX_DLL_PATH];
+    MFX::MFXLibraryIterator libIterator;
+    // there iterators are used only if the caller specified implicit type like AUTO
+    mfxU32 curImplIdx, maxImplIdx;
+    // particular implementation value
+    mfxIMPL curImpl;
+    // implementation method masked from the input parameter
+    // special case for audio library
+    const mfxIMPL implMethod = (par.Implementation & MFX_IMPL_AUDIO) ? (sizeof(implTypesRange) / sizeof(implTypesRange[0]) - 1) : (par.Implementation & (MFX_IMPL_VIA_ANY - 1));
+
+    // implementation interface masked from the input parameter
+    mfxIMPL implInterface = par.Implementation & -MFX_IMPL_VIA_ANY;
+    mfxIMPL implInterfaceOrig = implInterface;
+    mfxVersion requiredVersion = {{MFX_VERSION_MINOR, MFX_VERSION_MAJOR}};
+
+    // check error(s)
+    if (NULL == session)
+    {
+        return MFX_ERR_NULL_PTR;
+    }
+    if (((MFX_IMPL_AUTO > implMethod) || (MFX_IMPL_RUNTIME < implMethod)) && !(par.Implementation & MFX_IMPL_AUDIO))
+    {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // set the minimal required version
+    requiredVersion = par.Version;
+
+    try
+    {
+        // reset the session value
+        *session = 0;
+
+        // allocate the dispatching handle and call-table
+        pHandle = new MFX_DISP_HANDLE(requiredVersion);
+    }
+    catch(...)
+    {
+        return MFX_ERR_MEMORY_ALLOC;
+    }
+
+    DISPATCHER_LOG_INFO((("Required API version is %u.%u\n"), requiredVersion.Major, requiredVersion.Minor));
+
+    // Load HW library or RT from system location
+    curImplIdx = implTypesRange[implMethod].minIndex;
+    maxImplIdx = implTypesRange[implMethod].maxIndex;
+    mfxU32 hwImplIdx = 0;
+    do
+    {
+        int currentStorage = MFX::MFX_STORAGE_ID_FIRST;
+        implInterface = implInterfaceOrig;
+        do
+        {
+            // initialize the library iterator
+            mfxRes = libIterator.Init(implTypes[curImplIdx].implType, 
+                implInterface,
+                implTypes[curImplIdx].adapterID,
+                currentStorage);
+
+            // look through the list of installed SDK version,
+            // looking for a suitable library with higher merit value.
+            if (MFX_ERR_NONE == mfxRes)
+            {
+
+                if (
+                    MFX_LIB_HARDWARE == implTypes[curImplIdx].implType
+                    && (!implInterface 
+                    || MFX_IMPL_VIA_ANY == implInterface))
+                {
+                    implInterface = libIterator.GetImplementationType();
+                }
+
+                do
+                {
+                    eMfxImplType implType;
+
+                    // select a desired DLL
+                    mfxRes = libIterator.SelectDLLVersion(dllName,
+                        sizeof(dllName) / sizeof(dllName[0]),
+                        &implType,
+                        pHandle->apiVersion);
+                    if (MFX_ERR_NONE != mfxRes)
+                    {
+                        break;
+                    }
+                    DISPATCHER_LOG_INFO((("loading library %S\n"), MSDK2WIDE(dllName)));
+                    if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType)
+                        hwImplIdx = curImplIdx;
+                    // try to load the selected DLL
+                    curImpl = implTypes[curImplIdx].impl;
+                    mfxRes = pHandle->LoadSelectedDLL(dllName, implType, curImpl, implInterface, par);
+                    // unload the failed DLL
+                    if (MFX_ERR_NONE != mfxRes)
+                    {
+                        pHandle->Close();
+                    }
+                    else
+                    {
+                        libIterator.GetSubKeyName(pHandle->subkeyName, sizeof(pHandle->subkeyName)/sizeof(pHandle->subkeyName[0])) ;
+                        pHandle->storageID = libIterator.GetStorageID();
+                        allocatedHandle.push_back(pHandle);
+                        pHandle = new MFX_DISP_HANDLE(requiredVersion);
+                    }
+
+                } while (MFX_ERR_NONE != mfxRes);
+            }
+
+            // select another registry key
+            currentStorage += 1;
+
+        } while ((MFX_ERR_NONE != mfxRes) && (MFX::MFX_STORAGE_ID_LAST >= currentStorage));
+
+    } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
+
+
+    curImplIdx = implTypesRange[implMethod].minIndex;
+    maxImplIdx = implTypesRange[implMethod].maxIndex;
+
+    // Load RT from app folder (libmfxsw64 with API >= 1.10)
+    do
+    {
+        implInterface = implInterfaceOrig;
+        // initialize the library iterator
+        mfxRes = libIterator.Init(implTypes[curImplIdx].implType, 
+            implInterface,
+            implTypes[curImplIdx].adapterID,
+            MFX::MFX_APP_FOLDER);
+
+        if (MFX_ERR_NONE == mfxRes)
+        {
+
+            if (
+                MFX_LIB_HARDWARE == implTypes[curImplIdx].implType
+                && (!implInterface 
+                || MFX_IMPL_VIA_ANY == implInterface))
+            {
+                implInterface = libIterator.GetImplementationType();
+            }
+
+            do
+            {
+                eMfxImplType implType;
+
+                // select a desired DLL
+                mfxRes = libIterator.SelectDLLVersion(dllName,
+                    sizeof(dllName) / sizeof(dllName[0]),
+                    &implType,
+                    pHandle->apiVersion);
+                if (MFX_ERR_NONE != mfxRes)
+                {
+                    break;
+                }
+                DISPATCHER_LOG_INFO((("loading library %S\n"), MSDK2WIDE(dllName)));
+
+                // try to load the selected DLL
+                curImpl = implTypes[curImplIdx].impl;
+                mfxRes = pHandle->LoadSelectedDLL(dllName, implType, curImpl, implInterface, par);
+                // unload the failed DLL
+                if (MFX_ERR_NONE != mfxRes)
+                {
+                    pHandle->Close();
+                }
+                else
+                {
+                    if (pHandle->actualApiVersion.Major == 1 && pHandle->actualApiVersion.Minor <= 9)
+                    {
+                        // this is not RT, skip it
+                        mfxRes = MFX_ERR_ABORTED;
+                        break;
+                    }
+                    pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
+                    allocatedHandle.push_back(pHandle);
+                    pHandle = new MFX_DISP_HANDLE(requiredVersion);
+                }
+
+            } while (MFX_ERR_NONE != mfxRes);
+        }
+    } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
+
+    // Load HW and SW libraries using legacy default DLL search mechanism
+    // set current library index again
+    curImplIdx = implTypesRange[implMethod].minIndex;
+    do
+    {
+        mfxU32 backupIdx = curImplIdx;
+        if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType)
+        {
+            curImplIdx = hwImplIdx;
+        }
+        implInterface = implInterfaceOrig;
+            
+        if (par.Implementation & MFX_IMPL_AUDIO)
+        {
+            mfxRes = MFX::mfx_get_default_audio_dll_name(dllName,
+                sizeof(dllName) / sizeof(dllName[0]),
+                implTypes[curImplIdx].implType);
+        }
+        else
+        {
+            mfxRes = MFX::mfx_get_default_dll_name(dllName,
+                sizeof(dllName) / sizeof(dllName[0]),
+                implTypes[curImplIdx].implType);
+        }
+
+        if (MFX_ERR_NONE == mfxRes)
+        {
+            DISPATCHER_LOG_INFO((("loading default library %S\n"), MSDK2WIDE(dllName)))
+
+                // try to load the selected DLL using default DLL search mechanism
+                if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType)
+                {
+                    if (!implInterface) 
+                    {
+                        implInterface = MFX_IMPL_VIA_ANY;
+                    }
+                    mfxRes = MFX::SelectImplementationType(implTypes[curImplIdx].adapterID, &implInterface, NULL, NULL);
+                }
+                if (MFX_ERR_NONE == mfxRes)
+                {
+                    // try to load the selected DLL using default DLL search mechanism
+                    mfxRes = pHandle->LoadSelectedDLL(dllName,
+                        implTypes[curImplIdx].implType,
+                        implTypes[curImplIdx].impl,
+                        implInterface,
+                        par);
+                }
+                // unload the failed DLL
+                if ((MFX_ERR_NONE != mfxRes) &&
+                    (MFX_WRN_PARTIAL_ACCELERATION != mfxRes))
+                {
+                    pHandle->Close();
+                }
+                else
+                {                    
+                    pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
+                    allocatedHandle.push_back(pHandle);
+                    pHandle = new MFX_DISP_HANDLE(requiredVersion);
+                }
+        }
+        curImplIdx = backupIdx;
+    }
+    while ((MFX_ERR_NONE > mfxRes) && (++curImplIdx <= maxImplIdx));
+    delete pHandle;
+
+    if (allocatedHandle.size() == 0)
+        return MFX_ERR_UNSUPPORTED;
+
+    bool NeedSort = false;
+    HandleVector::iterator first = allocatedHandle.begin(),
+                           it = allocatedHandle.begin(),
+                           et = allocatedHandle.end();
+    for (it++; it != et; ++it)
+        if (HandleSort(&(*first), &(*it)) != 0)
+            NeedSort = true;
+
+    // select dll with version with lowest version number still greater or equal to requested
+    if (NeedSort)
+        qsort(&(*allocatedHandle.begin()), allocatedHandle.size(), sizeof(MFX_DISP_HANDLE*), &HandleSort);
+
+    HandleVector::iterator candidate = allocatedHandle.begin();
+    // check the final result of loading
+    try 
+    {
+        pHandle = *candidate;
+        //pulling up current mediasdk version, that required to match plugin version
+        mfxVersion apiVerActual;
+        mfxStatus stsQueryVersion;
+        stsQueryVersion = MFXQueryVersion((mfxSession)pHandle, &apiVerActual);
+        if (MFX_ERR_NONE !=  stsQueryVersion) 
+        {
+            DISPATCHER_LOG_ERROR((("MFXQueryVersion returned: %d, cannot load plugins\n"), mfxRes))
+        }
+        else
+        {
+            MFX::MFXPluginStorage & hive = pHandle->pluginHive;
+
+            HandleVector::iterator it = allocatedHandle.begin(),
+                                   et = allocatedHandle.end();
+            for (; it != et; ++it)
+            {
+                // Registering default plugins set
+                MFX::MFXDefaultPlugins defaultPugins(apiVerActual, *it, (*it)->implType);
+                hive.insert(hive.end(), defaultPugins.begin(), defaultPugins.end());
+
+                if ((*it)->storageID != MFX::MFX_UNKNOWN_KEY)
+                {
+                    // Scan HW plugins in subkeys of registry library
+                    MFX::MFXPluginsInHive plgsInHive((*it)->storageID, (*it)->subkeyName, apiVerActual);
+                    hive.insert(hive.end(), plgsInHive.begin(), plgsInHive.end());
+                }
+            }
+
+            //setting up plugins records
+            for(int i = MFX::MFX_STORAGE_ID_FIRST; i <= MFX::MFX_STORAGE_ID_LAST; i++) 
+            {
+                MFX::MFXPluginsInHive plgsInHive(i, NULL, apiVerActual);
+                hive.insert(hive.end(), plgsInHive.begin(), plgsInHive.end());
+            }
+
+            MFX::MFXPluginsInFS plgsInFS(apiVerActual);
+            hive.insert(hive.end(), plgsInFS.begin(), plgsInFS.end());
+        }
+    }
+    catch(...)
+    {
+        DISPATCHER_LOG_ERROR((("unknown exception while loading plugins\n")))
+    }
+
+    // everything is OK. Save pointers to the output variable
+    *candidate = 0; // keep this one safe from guard destructor 
+    *((MFX_DISP_HANDLE **) session) = pHandle;
+
+    return pHandle->loadStatus;
+
+} // mfxStatus MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
+
+mfxStatus MFXClose(mfxSession session)
+{
+    MFX::MFXAutomaticCriticalSection guard(&dispGuard);
+
+    mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session;
+
+    // check error(s)
+    if (pHandle)
+    {
+        try
+        {
+            // unload the DLL library
+            mfxRes = pHandle->Close();
+
+            // it is possible, that there is an active child session.
+            // can't unload library in that case.
+            if (MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes)
+            {
+                // release the handle
+                delete pHandle;
+            }
+        }
+        catch(...)
+        {
+            mfxRes = MFX_ERR_INVALID_HANDLE;
+        }
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFXClose(mfxSession session)
+
+mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session)
+{
+    mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session;
+    MFX_DISP_HANDLE *pChildHandle = (MFX_DISP_HANDLE *) child_session;
+
+    // get the function's address and make a call
+    if ((pHandle) && (pChildHandle) && (pHandle->apiVersion == pChildHandle->apiVersion))
+    {
+        /* check whether it is audio session or video */
+        int tableIndex = eMFXJoinSession; 
+        mfxFunctionPointer pFunc;
+        if (pHandle->impl & MFX_IMPL_AUDIO) 
+        { 
+            pFunc = pHandle->callAudioTable[tableIndex];
+        }
+        else
+        {
+            pFunc = pHandle->callTable[tableIndex];
+        }
+
+        if (pFunc)
+        {
+            // pass down the call
+            mfxRes = (*(mfxStatus (MFX_CDECL *) (mfxSession, mfxSession)) pFunc) (pHandle->session, 
+                pChildHandle->session);
+        }
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session)
+
+mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone)
+{
+    mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session;
+    mfxVersion apiVersion;
+    mfxIMPL impl;
+
+    // check error(s)
+    if (pHandle)
+    {
+        // initialize the clone session
+        apiVersion = pHandle->apiVersion;
+        impl = pHandle->impl | pHandle->implInterface;
+        mfxRes = MFXInit(impl, &apiVersion, clone);
+        if (MFX_ERR_NONE != mfxRes)
+        {
+            return mfxRes;
+        }
+
+        // join the sessions
+        mfxRes = MFXJoinSession(session, *clone);
+        if (MFX_ERR_NONE != mfxRes)
+        {
+            MFXClose(*clone);
+            *clone = NULL;
+            return mfxRes;
+        }
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone)
+
+
+mfxStatus MFXVideoUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version)
+{
+    mfxStatus sts = MFX_ERR_NONE;
+    bool ErrFlag = false;
+    MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session;
+    if (!&pHandle)
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: session=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    if (!uid)
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: uid=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    DISPATCHER_LOG_INFO((("MFXVideoUSER_Load: uid="MFXGUIDTYPE()" version=%d\n")
+        , MFXGUIDTOHEX(uid)
+        , version))
+        size_t pluginsChecked = 0;
+
+    for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++)
+    {
+        if (i->PluginUID != *uid)
+        {
+            continue;
+        }
+        //check rest in records
+        if (i->PluginVersion < version)
+        {
+            DISPATCHER_LOG_INFO((("MFXVideoUSER_Load: registered \"Plugin Version\" for GUID="MFXGUIDTYPE()" is %d, that is smaller that requested\n")
+                , MFXGUIDTOHEX(uid)
+                , i->PluginVersion))
+                continue;
+        }
+        try
+        {
+            sts = pHandle.pluginFactory.Create(*i);
+            if( MFX_ERR_NONE != sts)
+            {
+                ErrFlag = (ErrFlag || (sts == MFX_ERR_UNDEFINED_BEHAVIOR));
+                continue;
+            }
+            return MFX_ERR_NONE;
+        }
+        catch(...)
+        {
+            continue;
+        }
+    }
+
+    // Specified UID was not found among individually registed plugins, now try load it from default sets if any
+    for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++)
+    {
+        if (!i->Default)
+            continue;
+
+        i->PluginUID = *uid;
+        i->PluginVersion = (mfxU16)version;
+        try
+        {
+            sts = pHandle.pluginFactory.Create(*i);
+            if( MFX_ERR_NONE != sts)
+            {
+                ErrFlag = (ErrFlag || (sts == MFX_ERR_UNDEFINED_BEHAVIOR));
+                continue;
+            }
+            return MFX_ERR_NONE;
+        }
+        catch(...)
+        {
+            continue;
+        }
+    }
+
+    DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: cannot find registered plugin with requested UID, total plugins available=%d\n"), pHandle.pluginHive.size()));
+    if (ErrFlag)
+        return MFX_ERR_UNDEFINED_BEHAVIOR;
+    else
+        return MFX_ERR_NOT_FOUND;
+}
+
+
+mfxStatus MFXVideoUSER_LoadByPath(mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len)
+{
+    MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session;
+    if (!&pHandle)
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: session=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    if (!uid)
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: uid=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+
+    DISPATCHER_LOG_INFO((("MFXVideoUSER_LoadByPath: %S uid="MFXGUIDTYPE()" version=%d\n")
+        , MSDK2WIDE(path)
+        , MFXGUIDTOHEX(uid)
+        , version))
+
+    PluginDescriptionRecord record;
+    record.sName[0] = 0;
+
+#ifdef _WIN32
+    msdk_disp_char wPath[MAX_PLUGIN_PATH];
+    int res = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, len, wPath, MAX_PLUGIN_PATH);
+    if (!res)
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: cant convert UTF-8 path to UTF-16\n")));
+        return MFX_ERR_NOT_FOUND;
+    }
+    msdk_disp_char_cpy_s(record.sPath, res < MAX_PLUGIN_PATH ? res : MAX_PLUGIN_PATH, wPath);
+#else // Linux/Android 
+    msdk_disp_char_cpy_s(record.sPath, len < MAX_PLUGIN_PATH ? len : MAX_PLUGIN_PATH, path);
+#endif
+    
+    record.PluginUID = *uid; 
+    record.PluginVersion = (mfxU16)version;
+    record.Default = true;
+
+    try
+    {
+        return pHandle.pluginFactory.Create(record);
+    }
+    catch(...)
+    {
+        return MFX_ERR_NOT_FOUND;
+    }
+}
+
+
+mfxStatus MFXVideoUSER_UnLoad(mfxSession session, const mfxPluginUID *uid)
+{
+    MFX_DISP_HANDLE &rHandle = *(MFX_DISP_HANDLE *) session;
+    if (!&rHandle) 
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad: session=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    if (!uid)
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: uid=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+
+    bool bDestroyed = rHandle.pluginFactory.Destroy(*uid);
+    if (bDestroyed) 
+    {
+        DISPATCHER_LOG_INFO((("MFXVideoUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" unloaded\n"), MFXGUIDTOHEX(uid)));
+    } else 
+    {
+        DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" not found\n"), MFXGUIDTOHEX(uid)));
+    }
+
+    return bDestroyed ? MFX_ERR_NONE : MFX_ERR_NOT_FOUND;
+}
+
+mfxStatus MFXAudioUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version)
+{
+    MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session;
+    if (!&pHandle)
+    {
+        DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: session=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    if (!uid)
+    {
+        DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: uid=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    DISPATCHER_LOG_INFO((("MFXAudioUSER_Load: uid="MFXGUIDTYPE()" version=%d\n")
+        , MFXGUIDTOHEX(uid)
+        , version))
+        size_t pluginsChecked = 0;
+    PluginDescriptionRecord defaultPluginRecord;
+    for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++)
+    {
+        if (i->PluginUID != *uid)
+        {
+            if (i->Default) // PluginUID == 0 for default set
+            {
+                defaultPluginRecord = *i;
+            }
+            continue;
+        }
+        //check rest in records
+        if (i->PluginVersion < version)
+        {
+            DISPATCHER_LOG_INFO((("MFXAudioUSER_Load: registered \"Plugin Version\" for GUID="MFXGUIDTYPE()" is %d, that is smaller that requested\n")
+                , MFXGUIDTOHEX(uid)
+                , i->PluginVersion))
+                continue;
+        }
+        try {
+            return pHandle.pluginFactory.Create(*i);
+        }
+        catch(...) {
+            return MFX_ERR_UNKNOWN;
+        }
+    }
+
+    // Specified UID was not found among individually registed plugins, now try load it from default set if any
+    if (defaultPluginRecord.Default)
+    {
+        defaultPluginRecord.PluginUID = *uid;
+        defaultPluginRecord.onlyVersionRegistered = true;
+        defaultPluginRecord.PluginVersion = (mfxU16)version;
+        try {
+            return pHandle.pluginFactory.Create(defaultPluginRecord);
+        }
+        catch(...) {
+            return MFX_ERR_UNKNOWN;
+        }
+    }
+
+    DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: cannot find registered plugin with requested UID, total plugins available=%d\n"), pHandle.pluginHive.size()));
+    return MFX_ERR_NOT_FOUND;
+}
+
+mfxStatus MFXAudioUSER_UnLoad(mfxSession session, const mfxPluginUID *uid)
+{
+    MFX_DISP_HANDLE &rHandle = *(MFX_DISP_HANDLE *) session;
+    if (!&rHandle) 
+    {
+        DISPATCHER_LOG_ERROR((("MFXAudioUSER_UnLoad: session=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+    if (!uid)
+    {
+        DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: uid=NULL\n")));
+        return MFX_ERR_NULL_PTR;
+    }
+
+    bool bDestroyed = rHandle.pluginFactory.Destroy(*uid);
+    if (bDestroyed) 
+    {
+        DISPATCHER_LOG_INFO((("MFXAudioUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" unloaded\n"), MFXGUIDTOHEX(uid)));
+    } else 
+    {
+        DISPATCHER_LOG_ERROR((("MFXAudioUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" not found\n"), MFXGUIDTOHEX(uid)));
+    }
+
+    return bDestroyed ? MFX_ERR_NONE : MFX_ERR_NOT_FOUND;
+}
+
+//
+// implement all other calling functions.
+// They just call a procedure of DLL library from the table.
+//
+
+// define for common functions (from mfxsession.h)
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    return_value func_name formal_param_list \
+{ \
+    mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; \
+    /* get the function's address and make a call */ \
+    if (pHandle) \
+{ \
+    /* check whether it is audio session or video */ \
+    int tableIndex = e##func_name; \
+    mfxFunctionPointer pFunc; \
+    if (pHandle->impl & MFX_IMPL_AUDIO) \
+{ \
+    pFunc = pHandle->callAudioTable[tableIndex]; \
+} \
+        else \
+{ \
+    pFunc = pHandle->callTable[tableIndex]; \
+} \
+    if (pFunc) \
+{ \
+    /* get the real session pointer */ \
+    session = pHandle->session; \
+    /* pass down the call */ \
+    mfxRes = (*(mfxStatus (MFX_CDECL  *) formal_param_list) pFunc) actual_param_list; \
+} \
+} \
+    return mfxRes; \
+}
+
+FUNCTION(mfxStatus, MFXQueryIMPL, (mfxSession session, mfxIMPL *impl), (session, impl))
+FUNCTION(mfxStatus, MFXQueryVersion, (mfxSession session, mfxVersion *version), (session, version))
+FUNCTION(mfxStatus, MFXDisjoinSession, (mfxSession session), (session))
+FUNCTION(mfxStatus, MFXSetPriority, (mfxSession session, mfxPriority priority), (session, priority))
+FUNCTION(mfxStatus, MFXGetPriority, (mfxSession session, mfxPriority *priority), (session, priority))
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    return_value func_name formal_param_list \
+{ \
+    mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; \
+    /* get the function's address and make a call */ \
+    if (pHandle) \
+{ \
+    mfxFunctionPointer pFunc = pHandle->callTable[e##func_name]; \
+    if (pFunc) \
+{ \
+    /* get the real session pointer */ \
+    session = pHandle->session; \
+    /* pass down the call */ \
+    mfxRes = (*(mfxStatus (MFX_CDECL  *) formal_param_list) pFunc) actual_param_list; \
+} \
+} \
+    return mfxRes; \
+}
+
+#include "mfx_exposed_functions_list.h"
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    return_value func_name formal_param_list \
+{ \
+    mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; \
+    /* get the function's address and make a call */ \
+    if (pHandle) \
+{ \
+    mfxFunctionPointer pFunc = pHandle->callAudioTable[e##func_name]; \
+    if (pFunc) \
+{ \
+    /* get the real session pointer */ \
+    session = pHandle->session; \
+    /* pass down the call */ \
+    mfxRes = (*(mfxStatus (MFX_CDECL  *) formal_param_list) pFunc) actual_param_list; \
+} \
+} \
+    return mfxRes; \
+}
+
+#include "mfxaudio_exposed_functions_list.h"

+ 88 - 0
plugins/obs-qsv11/libmfx/src/mfx_critical_section.cpp

@@ -0,0 +1,88 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2013 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_critical_section.cpp
+
+\* ****************************************************************************** */
+
+#include "mfx_critical_section.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#include <windows.h>
+// SDK re-declares the following functions with different call declarator.
+// We don't need them. Just redefine them to nothing.
+#define _interlockedbittestandset fake_set
+#define _interlockedbittestandreset fake_reset
+#define _interlockedbittestandset64 fake_set64
+#define _interlockedbittestandreset64 fake_reset64
+#include <intrin.h>
+
+#define MFX_WAIT() SwitchToThread()
+
+// static section of the file
+namespace
+{
+
+enum
+{
+    MFX_SC_IS_FREE = 0,
+    MFX_SC_IS_TAKEN = 1
+};
+
+} // namespace
+
+namespace MFX
+{
+
+mfxU32 mfxInterlockedCas32(mfxCriticalSection *pCSection, mfxU32 value_to_exchange, mfxU32 value_to_compare)
+{
+    return _InterlockedCompareExchange(pCSection, value_to_exchange, value_to_compare);
+}
+
+mfxU32 mfxInterlockedXchg32(mfxCriticalSection *pCSection, mfxU32 value)  
+{ 
+    return _InterlockedExchange(pCSection, value);
+}
+
+void mfxEnterCriticalSection(mfxCriticalSection *pCSection)
+{
+    while (MFX_SC_IS_TAKEN == mfxInterlockedCas32(pCSection,
+                                                  MFX_SC_IS_TAKEN,
+                                                  MFX_SC_IS_FREE))
+    {
+        MFX_WAIT();
+    }
+} // void mfxEnterCriticalSection(mfxCriticalSection *pCSection)
+
+void mfxLeaveCriticalSection(mfxCriticalSection *pCSection)
+{
+    mfxInterlockedXchg32(pCSection, MFX_SC_IS_FREE);
+} // void mfxLeaveCriticalSection(mfxCriticalSection *pCSection)
+
+} // namespace MFX
+
+#endif // #if defined(_WIN32) || defined(_WIN64)

+ 349 - 0
plugins/obs-qsv11/libmfx/src/mfx_dispatcher.cpp

@@ -0,0 +1,349 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dispatcher.cpp
+
+\* ****************************************************************************** */
+
+#include "mfx_dispatcher.h"
+#include "mfx_dispatcher_log.h"
+#include "mfx_load_dll.h"
+
+#include <string.h>
+#if defined(_WIN32) || defined(_WIN64)
+    #include <windows.h>
+    #pragma warning(disable:4355)
+#else
+
+#include <dlfcn.h>
+#include <iostream>
+
+#endif // defined(_WIN32) || defined(_WIN64)
+
+MFX_DISP_HANDLE::MFX_DISP_HANDLE(const mfxVersion requiredVersion) :
+    apiVersion(requiredVersion),
+    pluginFactory((mfxSession)this)
+{
+    actualApiVersion.Version = 0;
+    implType = MFX_LIB_SOFTWARE;
+    impl = MFX_IMPL_SOFTWARE;
+    loadStatus = MFX_ERR_NOT_FOUND;
+    dispVersion.Major = MFX_DISPATCHER_VERSION_MAJOR;
+    dispVersion.Minor = MFX_DISPATCHER_VERSION_MINOR;
+    session = (mfxSession) 0;
+
+    hModule = (mfxModuleHandle) 0;
+
+    memset(callTable, 0, sizeof(callTable));
+    memset(callAudioTable, 0, sizeof(callAudioTable));
+
+} // MFX_DISP_HANDLE::MFX_DISP_HANDLE(const mfxVersion requiredVersion)
+
+MFX_DISP_HANDLE::~MFX_DISP_HANDLE(void)
+{
+    Close();
+
+} // MFX_DISP_HANDLE::~MFX_DISP_HANDLE(void)
+
+mfxStatus MFX_DISP_HANDLE::Close(void)
+{
+    mfxStatus mfxRes;
+
+    mfxRes = UnLoadSelectedDLL();
+
+    // the library wasn't unloaded
+    if (MFX_ERR_NONE == mfxRes)
+    {
+        implType = MFX_LIB_SOFTWARE;
+        impl = MFX_IMPL_SOFTWARE;
+        loadStatus = MFX_ERR_NOT_FOUND;
+        dispVersion.Major = MFX_DISPATCHER_VERSION_MAJOR;
+        dispVersion.Minor = MFX_DISPATCHER_VERSION_MINOR;
+        session = (mfxSession) 0;
+
+        hModule = (mfxModuleHandle) 0;
+
+        memset(callTable, 0, sizeof(callTable));
+        memset(callAudioTable, 0, sizeof(callAudioTable));
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFX_DISP_HANDLE::Close(void)
+
+mfxStatus MFX_DISP_HANDLE::LoadSelectedDLL(const msdk_disp_char *pPath, eMfxImplType implType,
+                                           mfxIMPL impl, mfxIMPL implInterface, mfxInitParam &par)
+{
+    mfxStatus mfxRes = MFX_ERR_NONE;
+
+    // check error(s)
+    if ((MFX_LIB_SOFTWARE != implType) &&
+        (MFX_LIB_HARDWARE != implType))
+    {
+        DISPATCHER_LOG_ERROR((("implType == %s, should be either MFX_LIB_SOFTWARE ot MFX_LIB_HARDWARE\n"), DispatcherLog_GetMFXImplString(implType).c_str()));
+        loadStatus = MFX_ERR_ABORTED;
+        return loadStatus;
+    }
+    // only exact types of implementation is allowed
+    if (!(impl & MFX_IMPL_AUDIO) &&
+        (MFX_IMPL_SOFTWARE != impl) &&
+        (MFX_IMPL_HARDWARE != impl) &&
+        (MFX_IMPL_HARDWARE2 != impl) &&
+        (MFX_IMPL_HARDWARE3 != impl) &&
+        (MFX_IMPL_HARDWARE4 != impl))
+    {
+        DISPATCHER_LOG_ERROR((("invalid implementation impl == %s\n"), DispatcherLog_GetMFXImplString(impl).c_str()));
+        loadStatus = MFX_ERR_ABORTED;
+        return loadStatus;
+    }
+    // only mfxExtThreadsParam is allowed
+    if (par.NumExtParam)
+    {
+        if ((par.NumExtParam > 1) || !par.ExtParam)
+        {
+            loadStatus = MFX_ERR_ABORTED;
+            return loadStatus;
+        }
+        if ((par.ExtParam[0]->BufferId != MFX_EXTBUFF_THREADS_PARAM) ||
+            (par.ExtParam[0]->BufferSz != sizeof(mfxExtThreadsParam)))
+        {
+            loadStatus = MFX_ERR_ABORTED;
+            return loadStatus;
+        }
+    }
+
+    // close the handle before initialization
+    Close();
+
+    // save the library's type
+    this->implType = implType;
+    this->impl = impl;
+    this->implInterface = implInterface;
+
+    {
+        DISPATCHER_LOG_BLOCK(("invoking LoadLibrary(%S)\n", MSDK2WIDE(pPath)));
+        // load the DLL into the memory
+        hModule = MFX::mfx_dll_load(pPath);
+        
+        if (hModule)
+        {
+            int i;
+
+            DISPATCHER_LOG_OPERATION({
+                msdk_disp_char modulePath[1024];
+                GetModuleFileNameW((HMODULE)hModule, modulePath, sizeof(modulePath)/sizeof(modulePath[0]));
+                DISPATCHER_LOG_INFO((("loaded module %S\n"), MSDK2WIDE(modulePath)))
+            });
+
+            if (impl & MFX_IMPL_AUDIO)
+            {
+                // load audio functions: pointers to exposed functions
+                for (i = 0; i < eAudioFuncTotal; i += 1)
+                {
+                    // construct correct name of the function - remove "_a" postfix
+
+                    mfxFunctionPointer pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIAudioFunc[i].pName);
+    #ifdef ANDROID
+                    // on Android very first call to dlsym may fail
+                    if (!pProc) pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIAudioFunc[i].pName);
+    #endif
+                    if (pProc)
+                    {
+                        // function exists in the library,
+                        // save the pointer.
+                        callAudioTable[i] = pProc;
+                    }
+                    else
+                    {
+                        // The library doesn't contain the function
+                        DISPATCHER_LOG_WRN((("Can't find API function \"%s\"\n"), APIAudioFunc[i].pName));
+                        if (apiVersion.Version >= APIAudioFunc[i].apiVersion.Version)
+                        {
+                            DISPATCHER_LOG_ERROR((("\"%s\" is required for API %u.%u\n"), APIAudioFunc[i].pName, apiVersion.Major, apiVersion.Minor));
+                            mfxRes = MFX_ERR_UNSUPPORTED;
+                            break;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                // load video functions: pointers to exposed functions
+                for (i = 0; i < eVideoFuncTotal; i += 1)
+                {
+                    mfxFunctionPointer pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIFunc[i].pName);
+    #ifdef ANDROID
+                    // on Android very first call to dlsym may fail
+                    if (!pProc) pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIFunc[i].pName);
+    #endif
+                    if (pProc)
+                    {
+                        // function exists in the library,
+                        // save the pointer.
+                        callTable[i] = pProc;
+                    }
+                    else
+                    {
+                        // The library doesn't contain the function
+                        DISPATCHER_LOG_WRN((("Can't find API function \"%s\"\n"), APIFunc[i].pName));
+                        if (apiVersion.Version >= APIFunc[i].apiVersion.Version)
+                        {
+                            DISPATCHER_LOG_ERROR((("\"%s\" is required for API %u.%u\n"), APIFunc[i].pName, apiVersion.Major, apiVersion.Minor));
+                            mfxRes = MFX_ERR_UNSUPPORTED;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+#if defined(_WIN32) || defined(_WIN64)
+            DISPATCHER_LOG_WRN((("can't find DLL: GetLastErr()=0x%x\n"), GetLastError()))
+#else
+            DISPATCHER_LOG_WRN((("can't find DLL: dlerror() = \"%s\"\n"), dlerror()));
+#endif
+            mfxRes = MFX_ERR_UNSUPPORTED;
+        }
+    }
+
+    // initialize the loaded DLL
+    if (MFX_ERR_NONE == mfxRes)
+    {
+        mfxVersion version(apiVersion);
+
+        /* check whether it is audio session or video */
+        mfxFunctionPointer *actualTable = (impl & MFX_IMPL_AUDIO) ? callAudioTable : callTable;
+
+        // Call old-style MFXInit init for older libraries and audio library
+        bool callOldInit = (impl & MFX_IMPL_AUDIO) || !actualTable[eMFXInitEx]; // if true call eMFXInit, if false - eMFXInitEx
+        int tableIndex = (callOldInit) ? eMFXInit : eMFXInitEx;
+
+        mfxFunctionPointer pFunc = actualTable[tableIndex];
+
+        {
+            if (callOldInit)
+            {
+                DISPATCHER_LOG_BLOCK(("MFXInit(%s,ver=%u.%u,session=0x%p)\n"
+                                     , DispatcherLog_GetMFXImplString(impl | implInterface).c_str()
+                                     , apiVersion.Major
+                                     , apiVersion.Minor
+                                     , &session));
+
+                mfxRes = (*(mfxStatus(MFX_CDECL *) (mfxIMPL, mfxVersion *, mfxSession *)) pFunc) (impl | implInterface, &version, &session);
+            }
+            else
+            {
+                DISPATCHER_LOG_BLOCK(("MFXInitEx(%s,ver=%u.%u,ExtThreads=%d,session=0x%p)\n"
+                                     , DispatcherLog_GetMFXImplString(impl | implInterface).c_str()
+                                     , apiVersion.Major
+                                     , apiVersion.Minor
+                                     , par.ExternalThreads
+                                     , &session));
+
+                mfxInitParam initPar = par;
+                // adjusting user parameters
+                initPar.Implementation = impl | implInterface;
+                initPar.Version = version;
+                mfxRes = (*(mfxStatus(MFX_CDECL *) (mfxInitParam, mfxSession *)) pFunc) (initPar, &session);
+            }
+        }
+
+        if (MFX_ERR_NONE != mfxRes)
+        {
+            DISPATCHER_LOG_WRN((("library can't be load. MFXInit returned %s \n"), DispatcherLog_GetMFXStatusString(mfxRes)))
+        }
+        else
+        {
+            mfxRes = MFXQueryVersion((mfxSession) this, &actualApiVersion);
+            
+            if (MFX_ERR_NONE != mfxRes)
+            {
+                DISPATCHER_LOG_ERROR((("MFXQueryVersion returned: %d, skiped this library\n"), mfxRes))
+            }
+            else
+            {
+                DISPATCHER_LOG_INFO((("MFXQueryVersion returned API: %d.%d\n"), actualApiVersion.Major, actualApiVersion.Minor))
+                //special hook for applications that uses sink api to get loaded library path
+                DISPATCHER_LOG_LIBRARY(("%p" , hModule));
+                DISPATCHER_LOG_INFO(("library loaded succesfully\n"))
+            }
+        }
+    }
+
+    loadStatus = mfxRes;
+    return mfxRes;
+
+} // mfxStatus MFX_DISP_HANDLE::LoadSelectedDLL(const msdk_disp_char *pPath, eMfxImplType implType, mfxIMPL impl)
+
+mfxStatus MFX_DISP_HANDLE::UnLoadSelectedDLL(void)
+{
+    mfxStatus mfxRes = MFX_ERR_NONE;
+
+    //unregistered plugins if any
+    pluginFactory.Close();
+
+    // close the loaded DLL
+    if (session)
+    {
+        /* check whether it is audio session or video */
+        int tableIndex = eMFXClose; 
+        mfxFunctionPointer pFunc;
+        if (impl & MFX_IMPL_AUDIO) 
+        { 
+            pFunc = callAudioTable[tableIndex];
+        } 
+        else
+        {
+            pFunc = callTable[tableIndex];
+        }
+
+        mfxRes = (*(mfxStatus (MFX_CDECL *) (mfxSession)) pFunc) (session);
+        if (MFX_ERR_NONE == mfxRes)
+        {
+            session = (mfxSession) 0;
+        }
+
+        DISPATCHER_LOG_INFO((("MFXClose(0x%x) returned %d\n"), session, mfxRes));
+        // actually, the return value is required to pass outside only.
+    }
+
+    // it is possible, that there is an active child session.
+    // can't unload library in that case.
+    if ((MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes) &&
+        (hModule))
+    {
+        // unload the library.
+        if (!MFX::mfx_dll_free(hModule))
+        {
+            mfxRes = MFX_ERR_UNDEFINED_BEHAVIOR;
+        }
+        hModule = (mfxModuleHandle) 0;
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFX_DISP_HANDLE::UnLoadSelectedDLL(void)

+ 449 - 0
plugins/obs-qsv11/libmfx/src/mfx_dispatcher_log.cpp

@@ -0,0 +1,449 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dispatcher_log.h
+
+\* ****************************************************************************** */
+
+#if defined(MFX_DISPATCHER_LOG)
+
+#include "mfx_dispatcher_log.h"
+#include "mfxstructures.h"
+#if defined(_WIN32) || defined(_WIN64)
+#include <windows.h>
+#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+#include <evntprov.h>
+#include <winmeta.h>
+#endif
+#endif // #if defined(_WIN32) || defined(_WIN64)
+#include <stdarg.h>
+#include <algorithm>
+#include <string>
+#include <sstream>
+
+struct CodeStringTable
+{
+    int code;
+    const char *string;
+} LevelStrings []= 
+{
+    {DL_INFO,  "INFO:   "},
+    {DL_WRN,   "WARNING:"},
+    {DL_ERROR, "ERROR:  "}
+};
+
+#define DEFINE_CODE(code)\
+    {code, #code}
+
+static CodeStringTable StringsOfImpl[] = {
+    DEFINE_CODE(MFX_IMPL_AUTO),       
+    DEFINE_CODE(MFX_IMPL_SOFTWARE),
+    DEFINE_CODE(MFX_IMPL_HARDWARE),     
+    DEFINE_CODE(MFX_IMPL_AUTO_ANY),     
+    DEFINE_CODE(MFX_IMPL_HARDWARE_ANY), 
+    DEFINE_CODE(MFX_IMPL_HARDWARE2), 
+    DEFINE_CODE(MFX_IMPL_HARDWARE3), 
+    DEFINE_CODE(MFX_IMPL_HARDWARE4), 
+
+    DEFINE_CODE(MFX_IMPL_UNSUPPORTED)
+};
+
+static CodeStringTable StringsOfImplVIA[] = {
+    DEFINE_CODE(MFX_IMPL_VIA_ANY),
+    DEFINE_CODE(MFX_IMPL_VIA_D3D9),
+    DEFINE_CODE(MFX_IMPL_VIA_D3D11),
+};
+
+static CodeStringTable StringsOfStatus[] =
+{
+    DEFINE_CODE(MFX_ERR_NONE                    ),
+    DEFINE_CODE(MFX_ERR_UNKNOWN                 ),
+    DEFINE_CODE(MFX_ERR_NULL_PTR                ),
+    DEFINE_CODE(MFX_ERR_UNSUPPORTED             ),
+    DEFINE_CODE(MFX_ERR_MEMORY_ALLOC            ),
+    DEFINE_CODE(MFX_ERR_NOT_ENOUGH_BUFFER       ),
+    DEFINE_CODE(MFX_ERR_INVALID_HANDLE          ),
+    DEFINE_CODE(MFX_ERR_LOCK_MEMORY             ),
+    DEFINE_CODE(MFX_ERR_NOT_INITIALIZED         ),
+    DEFINE_CODE(MFX_ERR_NOT_FOUND               ),
+    DEFINE_CODE(MFX_ERR_MORE_DATA               ),
+    DEFINE_CODE(MFX_ERR_MORE_SURFACE            ),
+    DEFINE_CODE(MFX_ERR_ABORTED                 ),
+    DEFINE_CODE(MFX_ERR_DEVICE_LOST             ),
+    DEFINE_CODE(MFX_ERR_INCOMPATIBLE_VIDEO_PARAM),
+    DEFINE_CODE(MFX_ERR_INVALID_VIDEO_PARAM     ),
+    DEFINE_CODE(MFX_ERR_UNDEFINED_BEHAVIOR      ),
+    DEFINE_CODE(MFX_ERR_DEVICE_FAILED           ),
+    DEFINE_CODE(MFX_WRN_IN_EXECUTION            ),
+    DEFINE_CODE(MFX_WRN_DEVICE_BUSY             ),
+    DEFINE_CODE(MFX_WRN_VIDEO_PARAM_CHANGED     ),
+    DEFINE_CODE(MFX_WRN_PARTIAL_ACCELERATION    ),
+    DEFINE_CODE(MFX_WRN_INCOMPATIBLE_VIDEO_PARAM),
+    DEFINE_CODE(MFX_WRN_VALUE_NOT_CHANGED       ),
+    DEFINE_CODE(MFX_WRN_OUT_OF_RANGE            ),
+    
+};
+
+#define CODE_TO_STRING(code,  array)\
+    CodeToString(code, array, sizeof(array)/sizeof(array[0]))
+
+const char* CodeToString(int code, CodeStringTable array[], int len )
+{
+    for (int i = 0 ; i < len; i++)
+    {
+        if (array[i].code == code)
+            return array[i].string;
+    }
+    return "undef";
+}
+
+std::string DispatcherLog_GetMFXImplString(int impl)
+{
+    std::string str1 = CODE_TO_STRING(impl & ~(-MFX_IMPL_VIA_ANY), StringsOfImpl);
+    std::string str2 = CODE_TO_STRING(impl & (-MFX_IMPL_VIA_ANY), StringsOfImplVIA);
+
+    return str1 + (str2 == "undef" ? "" : "|"+str2);
+}
+
+const char *DispatcherLog_GetMFXStatusString(int sts)
+{
+    return CODE_TO_STRING(sts, StringsOfStatus);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+
+void DispatcherLogBracketsHelper::Write(const char * str, ...)
+{
+    va_list argsptr;
+    va_start(argsptr, str);
+    DispatchLog::get().Write(m_level, m_opcode, str, argsptr);
+    va_end(argsptr);
+}
+
+void DispatchLogBlockHelper::Write(const char * str, ...)
+{
+    va_list argsptr;
+    va_start(argsptr, str);
+    DispatchLog::get().Write(m_level, DL_EVENT_START, str, argsptr);
+    va_end(argsptr);
+}
+
+DispatchLogBlockHelper::~DispatchLogBlockHelper()
+{
+    DispatchLog::get().Write(m_level, DL_EVENT_STOP, NULL, NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+DispatchLog::DispatchLog()
+ : m_DispatcherLogSink(DL_SINK_PRINTF)
+{
+
+}
+
+void   DispatchLog::SetSink(int nSink, IMsgHandler * pHandler)
+{
+    DetachAllSinks();
+    AttachSink(nSink, pHandler);
+}
+
+void   DispatchLog::AttachSink(int nsink, IMsgHandler *pHandler)
+{
+    m_DispatcherLogSink |= nsink;
+    if (NULL != pHandler)
+        m_Recepients.push_back(pHandler);
+}
+
+void   DispatchLog::DetachSink(int nsink, IMsgHandler *pHandler)
+{
+    if (nsink & DL_SINK_IMsgHandler)
+    {
+        m_Recepients.remove(pHandler);
+    }
+
+    m_DispatcherLogSink &= ~nsink;
+}
+
+void   DispatchLog::ExchangeSink(int nsink, IMsgHandler *oldHdl, IMsgHandler *newHdl)
+{
+    if (nsink & DL_SINK_IMsgHandler)
+    {
+        std::list<IMsgHandler*> :: iterator it = std::find(m_Recepients.begin(), m_Recepients.end(), oldHdl);
+        
+        //cannot exchange in that case
+        if (m_Recepients.end() == it)
+            return;
+
+        *it = newHdl;
+    }
+}
+
+
+void   DispatchLog::DetachAllSinks()
+{
+    m_Recepients.clear();
+    m_DispatcherLogSink = DL_SINK_NULL;
+}
+
+void   DispatchLog::Write(int level, int opcode, const char * msg, va_list argptr)
+{
+    int sinkTable[] =
+    {
+        DL_SINK_PRINTF,
+        DL_SINK_IMsgHandler,
+    };
+
+    for (size_t i = 0; i < sizeof(sinkTable) / sizeof(sinkTable[0]); i++)
+    {
+        switch(m_DispatcherLogSink & sinkTable[i])
+        {
+            case  DL_SINK_NULL:
+                break;
+            
+            case DL_SINK_PRINTF:
+            {
+                char msg_formated[8048] = {0};
+
+                if (NULL != msg && level != DL_LOADED_LIBRARY)
+                {
+#if _MSC_VER >= 1400
+                    vsprintf_s(msg_formated, sizeof(msg_formated)/sizeof(msg_formated[0]), msg, argptr);
+#else
+                    vsnprintf(msg_formated, sizeof(msg_formated)/sizeof(msg_formated[0]), msg, argptr);
+#endif
+                    //TODO: improve this , add opcode handling
+                    printf("%s %s", CODE_TO_STRING(level, LevelStrings), msg_formated);
+                }
+                break;
+            }
+
+            case DL_SINK_IMsgHandler:
+            {
+                std::list<IMsgHandler*>::iterator it;
+
+                for (it = m_Recepients.begin(); it != m_Recepients.end(); ++it)
+                {
+                    (*it)->Write(level, opcode, msg, argptr);
+                }
+                break;
+            }
+        }
+    }
+}
+
+#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+class ETWHandler : public IMsgHandler
+{
+public:
+    ETWHandler(const wchar_t * guid_str)
+      : m_bUseFormatter(DISPATCHER_LOG_USE_FORMATING)
+      , m_EventHandle()
+      , m_bProviderEnable()
+    {
+        GUID rguid = GUID_NULL;
+        if (FAILED(CLSIDFromString(guid_str, &rguid)))
+        {
+            return;
+        }
+        
+        EventRegister(&rguid, NULL, NULL, &m_EventHandle);
+
+        m_bProviderEnable = 0 != EventProviderEnabled(m_EventHandle, 1,0);
+    }
+
+    ~ETWHandler()
+    {
+        if (m_EventHandle)
+        {
+            EventUnregister(m_EventHandle);
+        }
+    }
+
+    virtual void Write(int level, int opcode, const char * msg, va_list argptr)
+    {
+        //event not registered
+        if (0==m_EventHandle)
+        {
+            return;
+        }
+        if (!m_bProviderEnable)
+        {
+            return;
+        }
+        if (level == DL_LOADED_LIBRARY)
+        {
+            return;
+        }
+
+        char msg_formated[1024];
+        EVENT_DESCRIPTOR descriptor;
+        EVENT_DATA_DESCRIPTOR data_descriptor;
+
+        EventDescZero(&descriptor);
+        
+        descriptor.Opcode = (UCHAR)opcode; 
+        descriptor.Level  = (UCHAR)level;
+        
+        if (m_bUseFormatter)
+        {
+            if (NULL != msg)
+            {
+#if _MSC_VER >= 1400
+                vsprintf_s(msg_formated, sizeof (msg_formated) / sizeof (msg_formated[0]), msg, argptr);
+#else
+                vsnprintf(msg_formated, sizeof (msg_formated) / sizeof (msg_formated[0]), msg, argptr);
+#endif
+                EventDataDescCreate(&data_descriptor, msg_formated, (ULONG)(strlen(msg_formated) + 1));
+            }else
+            {
+                EventDataDescCreate(&data_descriptor, NULL, 0);
+            }
+        }else
+        {
+            //TODO: non formated events supports under zbb 
+        }
+
+        EventWrite(m_EventHandle, &descriptor, 1, &data_descriptor);
+    }
+
+protected:
+
+    //we may not use formatter in some cases described in dispatch_log macro
+    //it significantly increases performance by eliminating any vsprintf operations
+    bool      m_bUseFormatter;
+    //consumer is attached, dispatcher trace to reduce formating overhead 
+    //submits event only if consumer attached
+    bool      m_bProviderEnable;
+    REGHANDLE m_EventHandle;
+};
+//
+
+
+IMsgHandler *ETWHandlerFactory::GetSink(const wchar_t* sguid)
+{
+    _storage_type::iterator it;
+    it = m_storage.find(sguid);
+    if (it == m_storage.end())
+    {
+        ETWHandler * handler = new ETWHandler(sguid);
+        _storage_type::_Pairib it_bool = m_storage.insert(_storage_type::value_type(sguid, handler));
+        it = it_bool.first;
+    }
+
+   return it->second;
+}
+
+ETWHandlerFactory::~ETWHandlerFactory()
+{
+    for each(_storage_type::value_type val in m_storage)
+    {
+        delete val.second;
+    }
+}
+
+class EventRegistrator : public IMsgHandler
+{
+    const wchar_t * m_sguid;
+public:
+    EventRegistrator(const wchar_t* sguid = DISPATCHER_LOG_EVENT_GUID)
+        :m_sguid(sguid)
+    {
+        DispatchLog::get().AttachSink( DL_SINK_IMsgHandler
+                                      , this);
+    }
+
+    virtual void Write(int level, int opcode, const char * msg, va_list argptr)
+    {
+        //we cannot call attach sink since we may have been called from iteration
+        //we axchanging preserve that placeholding
+        IMsgHandler * pSink = NULL;
+        DispatchLog::get().ExchangeSink(DL_SINK_IMsgHandler,
+                                        this,
+                                        pSink = ETWHandlerFactory::get().GetSink(m_sguid));
+        //need to call only once here all next calls will be done inside dispatcherlog
+        if (NULL != pSink)
+        {
+            pSink->Write(level, opcode, msg, argptr);
+        }
+    }
+};
+#endif
+
+template <class TSink>
+class SinkRegistrator
+{
+};
+
+#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+template <>
+class SinkRegistrator<ETWHandlerFactory>
+{
+public:
+    SinkRegistrator(const wchar_t* sguid = DISPATCHER_LOG_EVENT_GUID)
+    {
+        DispatchLog::get().AttachSink( DL_SINK_IMsgHandler
+                                      , ETWHandlerFactory::get().GetSink(sguid));
+    }
+};
+#endif
+
+#if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER)
+template <>
+class SinkRegistrator<FileSink>
+{
+public:
+    SinkRegistrator()
+    {
+        DispatchLog::get().AttachSink( DL_SINK_IMsgHandler, &FileSink::get(DISPACTHER_LOG_FW_PATH));
+    }
+};
+
+void FileSink::Write(int level, int /*opcode*/, const char * msg, va_list argptr)
+{
+    if (NULL != m_hdl && NULL != msg)
+    {
+        fprintf(m_hdl, "%s", CODE_TO_STRING(level, LevelStrings));
+        vfprintf(m_hdl, msg, argptr);
+    }
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+//singletons initialization section
+
+
+#ifdef  DISPATCHER_LOG_REGISTER_EVENT_PROVIDER
+    static SinkRegistrator<ETWHandlerFactory> g_registrator1;
+#endif
+
+
+#ifdef DISPATCHER_LOG_REGISTER_FILE_WRITER
+    static SinkRegistrator<FileSink> g_registrator2;
+#endif
+
+
+#endif//(MFX_DISPATCHER_LOG)

+ 558 - 0
plugins/obs-qsv11/libmfx/src/mfx_dxva2_device.cpp

@@ -0,0 +1,558 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_dxva2_device.cpp
+
+\* ****************************************************************************** */
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#define INITGUID
+#include <d3d9.h>
+#include <dxgi.h>
+
+#include "mfx_dxva2_device.h"
+
+
+using namespace MFX;
+
+
+DXDevice::DXDevice(void)
+{
+    m_hModule = (HMODULE) 0;
+
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+    m_driverVersion = 0;
+    m_luid = 0;
+
+} // DXDevice::DXDevice(void)
+
+DXDevice::~DXDevice(void)
+{
+    Close();
+
+    // free DX library only when device is destroyed
+    UnloadDLLModule();
+
+} // DXDevice::~DXDevice(void)
+
+mfxU32 DXDevice::GetVendorID(void) const
+{
+    return m_vendorID;
+
+} // mfxU32 DXDevice::GetVendorID(void) const
+
+mfxU32 DXDevice::GetDeviceID(void) const
+{
+    return m_deviceID;
+
+} // mfxU32 DXDevice::GetDeviceID(void) const
+
+mfxU64 DXDevice::GetDriverVersion(void) const
+{
+    return m_driverVersion;
+    
+}// mfxU64 DXDevice::GetDriverVersion(void) const
+
+mfxU64 DXDevice::GetLUID(void) const
+{
+    return m_luid;
+
+} // mfxU64 DXDevice::GetLUID(void) const
+
+mfxU32 DXDevice::GetAdapterCount(void) const
+{
+    return m_numAdapters;
+
+} // mfxU32 DXDevice::GetAdapterCount(void) const
+
+void DXDevice::Close(void)
+{
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+    m_luid = 0;
+
+} // void DXDevice::Close(void)
+
+void DXDevice::LoadDLLModule(const wchar_t *pModuleName)
+{
+    DWORD prevErrorMode = 0;
+
+    // unload the module if it is required
+    UnloadDLLModule();
+
+    // set the silent error mode
+#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__)
+    SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode); 
+#else
+    prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+    // load specified library
+	m_hModule = LoadLibraryExW(pModuleName, NULL, 0);
+
+    // set the previous error mode
+#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__)
+    SetThreadErrorMode(prevErrorMode, NULL);
+#else
+    SetErrorMode(prevErrorMode);
+#endif
+
+} // void LoadDLLModule(const wchar_t *pModuleName)
+
+void DXDevice::UnloadDLLModule(void)
+{
+    if (m_hModule)
+    {
+        FreeLibrary(m_hModule);
+        m_hModule = (HMODULE) 0;
+    }
+
+} // void DXDevice::UnloaDLLdModule(void)
+
+
+D3D9Device::D3D9Device(void)
+{
+    m_pD3D9 = (void *) 0;
+    m_pD3D9Ex = (void *) 0;
+
+} // D3D9Device::D3D9Device(void)
+
+D3D9Device::~D3D9Device(void)
+{
+    Close();
+
+} // D3D9Device::~D3D9Device(void)
+
+void D3D9Device::Close(void)
+{
+    // release the interfaces
+    if (m_pD3D9Ex)
+    {
+        ((IDirect3D9Ex *) m_pD3D9Ex)->Release();
+    }
+
+    // release the interfaces
+    if (m_pD3D9)
+    {
+        ((IDirect3D9 *) m_pD3D9)->Release();
+    }
+
+    m_pD3D9 = (void *) 0;
+    m_pD3D9Ex = (void *) 0;
+
+} // void D3D9Device::Close(void)
+
+typedef
+    IDirect3D9 * (WINAPI *D3DCreateFunctionPtr_t) (UINT);
+
+typedef
+    HRESULT (WINAPI *D3DExCreateFunctionPtr_t) (UINT, IDirect3D9Ex **);
+
+bool D3D9Device::Init(const mfxU32 adapterNum)
+{
+    // close the device before initialization
+    Close();
+
+    // load the library
+    if (NULL == m_hModule)
+    {
+        LoadDLLModule(L"d3d9.dll");
+    }
+
+    if (m_hModule)
+    {
+        D3DCreateFunctionPtr_t pFunc;
+
+        // load address of procedure to create D3D device
+        pFunc = (D3DCreateFunctionPtr_t) GetProcAddress(m_hModule, "Direct3DCreate9");
+        if (pFunc)
+        {
+            D3DADAPTER_IDENTIFIER9 adapterIdent;
+            IDirect3D9 *pD3D9;
+            HRESULT hRes;
+
+            // create D3D object
+            m_pD3D9 = pFunc(D3D_SDK_VERSION);
+
+            if (NULL == m_pD3D9)
+            {
+                DXVA2DEVICE_TRACE(("FAIL: Direct3DCreate9(%d) : GetLastError()=0x%x", D3D_SDK_VERSION, GetLastError()));
+                return false;
+            }
+
+            // cast the interface
+            pD3D9 = (IDirect3D9 *) m_pD3D9;
+
+            m_numAdapters = pD3D9->GetAdapterCount();
+            if (adapterNum >= m_numAdapters)
+            {
+                return false;
+            }
+
+            // get the card's parameters
+            hRes = pD3D9->GetAdapterIdentifier(adapterNum, 0, &adapterIdent);
+            if (D3D_OK != hRes)
+            {
+                DXVA2DEVICE_TRACE(("FAIL: GetAdapterIdentifier(%d) = 0x%x \n", adapterNum, hRes)); 
+                return false;
+            }
+
+            m_vendorID = adapterIdent.VendorId;
+            m_deviceID = adapterIdent.DeviceId;
+            m_driverVersion = (mfxU64)adapterIdent.DriverVersion.QuadPart;
+
+            // load LUID
+            IDirect3D9Ex *pD3D9Ex;
+            D3DExCreateFunctionPtr_t pFuncEx;
+            LUID d3d9LUID;
+
+            // find the appropriate function
+            pFuncEx = (D3DExCreateFunctionPtr_t) GetProcAddress(m_hModule, "Direct3DCreate9Ex");
+            if (NULL == pFuncEx)
+            {
+                // the extended interface is not supported
+                return true;
+            }
+
+            // create extended interface
+            hRes = pFuncEx(D3D_SDK_VERSION, &pD3D9Ex);
+            if (FAILED(hRes))
+            {
+                // can't create extended interface
+                return true;
+            }
+            m_pD3D9Ex = pD3D9Ex;
+
+            // obtain D3D9 device LUID
+            hRes = pD3D9Ex->GetAdapterLUID(adapterNum, &d3d9LUID);
+            if (FAILED(hRes))
+            {
+                // can't get LUID
+                return true;
+            }
+            // copy the LUID
+            *((LUID *) &m_luid) = d3d9LUID;
+        }
+        else
+        {
+            DXVA2DEVICE_TRACE_OPERATION({
+                wchar_t path[1024]; 
+                DWORD lastErr = GetLastError();
+                GetModuleFileNameW(m_hModule, path, sizeof(path)/sizeof(path[0]));
+                DXVA2DEVICE_TRACE(("FAIL: invoking GetProcAddress(Direct3DCreate9) in %S : GetLastError()==0x%x\n", path, lastErr)); });
+                return false;
+        }
+    }
+    else
+    {
+        DXVA2DEVICE_TRACE(("FAIL: invoking LoadLibrary(\"d3d9.dll\") : GetLastError()==0x%x\n", GetLastError())); 
+        return false;
+    }
+
+    return true;
+
+} // bool D3D9Device::Init(const mfxU32 adapterNum)
+
+typedef
+HRESULT (WINAPI *DXGICreateFactoryFunc) (REFIID riid, void **ppFactory);
+
+DXGI1Device::DXGI1Device(void)
+{
+    m_pDXGIFactory1 = (void *) 0;
+    m_pDXGIAdapter1 = (void *) 0;
+
+} // DXGI1Device::DXGI1Device(void)
+
+DXGI1Device::~DXGI1Device(void)
+{
+    Close();
+
+} // DXGI1Device::~DXGI1Device(void)
+
+void DXGI1Device::Close(void)
+{
+    // release the interfaces
+    if (m_pDXGIAdapter1)
+    {
+        ((IDXGIAdapter1 *) m_pDXGIAdapter1)->Release();
+    }
+
+    if (m_pDXGIFactory1)
+    {
+        ((IDXGIFactory1 *) m_pDXGIFactory1)->Release();
+    }
+
+    m_pDXGIFactory1 = (void *) 0;
+    m_pDXGIAdapter1 = (void *) 0;
+
+} // void DXGI1Device::Close(void)
+
+bool DXGI1Device::Init(const mfxU32 adapterNum)
+{
+    // release the object before initialization
+    Close();
+
+    // load up the library if it is not loaded
+    if (NULL == m_hModule)
+    {
+        LoadDLLModule(L"dxgi.dll");
+    }
+
+    if (m_hModule)
+    {
+        DXGICreateFactoryFunc pFunc;
+        IDXGIFactory1 *pFactory;
+        IDXGIAdapter1 *pAdapter;
+        DXGI_ADAPTER_DESC1 desc;
+        mfxU32 curAdapter, maxAdapters;
+        HRESULT hRes;
+
+        // load address of procedure to create DXGI 1.1 factory
+        pFunc = (DXGICreateFactoryFunc) GetProcAddress(m_hModule, "CreateDXGIFactory1");
+        if (NULL == pFunc)
+        {
+            return false;
+        }
+
+        // create the factory
+#if _MSC_VER >= 1400
+        hRes = pFunc(__uuidof(IDXGIFactory1), (void**) (&pFactory));
+#else
+        hRes = pFunc(IID_IDXGIFactory1, (void**) (&pFactory));
+#endif
+        if (FAILED(hRes))
+        {
+            return false;
+        }
+        m_pDXGIFactory1 = pFactory;
+
+        // get the number of adapters
+        curAdapter = 0;
+        maxAdapters = 0;
+        do
+        {
+            // get the required adapted
+            hRes = pFactory->EnumAdapters1(curAdapter, &pAdapter);
+            if (FAILED(hRes))
+            {
+                break;
+            }
+
+            // if it is the required adapter, save the interface
+            if (curAdapter == adapterNum)
+            {
+                m_pDXGIAdapter1 = pAdapter;
+            }
+            else
+            {
+                pAdapter->Release();
+            }
+
+            // get the next adapter
+            curAdapter += 1;
+
+        } while (SUCCEEDED(hRes));
+        maxAdapters = curAdapter;
+
+        // there is no required adapter
+        if (adapterNum >= maxAdapters)
+        {
+            return false;
+        }
+        pAdapter = (IDXGIAdapter1 *) m_pDXGIAdapter1;
+
+        // get the adapter's parameters
+        hRes = pAdapter->GetDesc1(&desc);
+        if (FAILED(hRes))
+        {
+            return false;
+        }
+
+        // save the parameters
+        m_vendorID = desc.VendorId;
+        m_deviceID = desc.DeviceId;
+        *((LUID *) &m_luid) = desc.AdapterLuid;
+    }
+
+    return true;
+
+} // bool DXGI1Device::Init(const mfxU32 adapterNum)
+
+DXVA2Device::DXVA2Device(void)
+{
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+} // DXVA2Device::DXVA2Device(void)
+
+DXVA2Device::~DXVA2Device(void)
+{
+    Close();
+
+} // DXVA2Device::~DXVA2Device(void)
+
+void DXVA2Device::Close(void)
+{
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+} // void DXVA2Device::Close(void)
+
+bool DXVA2Device::InitD3D9(const mfxU32 adapterNum)
+{
+    D3D9Device d3d9Device;
+    bool bRes;
+
+    // release the object before initialization
+    Close();
+
+    // create 'old fashion' device
+    bRes = d3d9Device.Init(adapterNum);
+    if (false == bRes)
+    {
+        return false;
+    }
+
+    m_numAdapters = d3d9Device.GetAdapterCount();
+
+    // check if the application is under Remote Desktop
+    if ((0 == d3d9Device.GetVendorID()) || (0 == d3d9Device.GetDeviceID()))
+    {
+        // get the required parameters alternative way and ...
+        UseAlternativeWay(&d3d9Device);
+    }
+    else
+    {
+        // save the parameters and ...
+        m_vendorID = d3d9Device.GetVendorID();
+        m_deviceID = d3d9Device.GetDeviceID();
+        m_driverVersion = d3d9Device.GetDriverVersion();
+    }
+
+    // ... say goodbye
+    return true;
+} // bool InitD3D9(const mfxU32 adapterNum)
+
+bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum)
+{
+    DXGI1Device dxgi1Device;
+    bool bRes;
+
+    // release the object before initialization
+    Close();
+
+    // create modern DXGI device
+    bRes = dxgi1Device.Init(adapterNum);
+    if (false == bRes)
+    {
+        return false;
+    }
+
+    // save the parameters and ...
+    m_vendorID = dxgi1Device.GetVendorID();
+    m_deviceID = dxgi1Device.GetDeviceID();
+    m_numAdapters = dxgi1Device.GetAdapterCount();
+
+    // ... say goodbye
+    return true;
+
+} // bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum)
+
+void DXVA2Device::UseAlternativeWay(const D3D9Device *pD3D9Device)
+{
+    mfxU64 d3d9LUID = pD3D9Device->GetLUID();
+
+    // work only with valid LUIDs
+    if (0 == d3d9LUID)
+    {
+        return;
+    }
+
+    DXGI1Device dxgi1Device;
+    mfxU32 curDevice = 0;
+    bool bRes = false;
+
+    do
+    {
+        // initialize the next DXGI1 or DXGI device
+        bRes = dxgi1Device.Init(curDevice);
+        if (false == bRes)
+        {
+            // there is no more devices
+            break;
+        }
+
+        // is it required device ?
+        if (d3d9LUID == dxgi1Device.GetLUID())
+        {
+            m_vendorID = dxgi1Device.GetVendorID();
+            m_deviceID = dxgi1Device.GetDeviceID();
+            m_driverVersion = dxgi1Device.GetDriverVersion();
+            return ;
+        }
+
+        // get the next device
+        curDevice += 1;
+
+    } while (bRes);
+
+    dxgi1Device.Close();
+    // we need to match a DXGI(1) device to the D3D9 device
+
+} // void DXVA2Device::UseAlternativeWay(const D3D9Device *pD3D9Device)
+
+mfxU32 DXVA2Device::GetVendorID(void) const
+{
+    return m_vendorID;
+
+} // mfxU32 DXVA2Device::GetVendorID(void) const
+
+mfxU32 DXVA2Device::GetDeviceID(void) const
+{
+    return m_deviceID;
+
+} // mfxU32 DXVA2Device::GetDeviceID(void) const
+
+mfxU64 DXVA2Device::GetDriverVersion(void) const
+{
+    return m_driverVersion;
+}// mfxU64 DXVA2Device::GetDriverVersion(void) const
+
+mfxU32 DXVA2Device::GetAdapterCount(void) const
+{
+    return m_numAdapters;
+
+} // mfxU32 DXVA2Device::GetAdapterCount(void) const
+#endif

+ 143 - 0
plugins/obs-qsv11/libmfx/src/mfx_function_table.cpp

@@ -0,0 +1,143 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_function_table.cpp
+
+\* ****************************************************************************** */
+
+#include "mfx_dispatcher.h"
+
+//
+// implement a table with functions names
+//
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    {#func_name, API_VERSION},
+
+const
+FUNCTION_DESCRIPTION APIFunc[eVideoFuncTotal] =
+{
+    {"MFXInit", {{0, 1}}},
+    {"MFXClose", {{0, 1}}},
+    {"MFXQueryIMPL", {{0, 1}}},
+    {"MFXQueryVersion", {{0, 1}}},
+
+    {"MFXJoinSession", {{1, 1}}},
+    {"MFXDisjoinSession", {{1, 1}}},
+    {"MFXCloneSession", {{1, 1}}},
+    {"MFXSetPriority", {{1, 1}}},
+    {"MFXGetPriority", {{1, 1}}},
+    
+    {"MFXInitEx", {{1, 14}}},
+
+#include "mfx_exposed_functions_list.h"
+};
+
+const
+FUNCTION_DESCRIPTION APIAudioFunc[eAudioFuncTotal] =
+{
+    {"MFXInit", {{8, 1}}},
+    {"MFXClose", {{8, 1}}},
+    {"MFXQueryIMPL", {{8, 1}}},
+    {"MFXQueryVersion", {{8, 1}}},
+
+    {"MFXJoinSession", {{8, 1}}},
+    {"MFXDisjoinSession", {{8, 1}}},
+    {"MFXCloneSession", {{8, 1}}},
+    {"MFXSetPriority", {{8, 1}}},
+    {"MFXGetPriority", {{8, 1}}},
+
+#include "mfxaudio_exposed_functions_list.h"
+};
+
+// static section of the file
+namespace
+{
+
+//
+// declare pseudo-functions.
+// they are used as default values for call-tables.
+//
+
+mfxStatus pseudoMFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
+{
+    // touch unreferenced parameters
+    impl = impl;
+    ver = ver;
+    session = session;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
+
+mfxStatus pseudoMFXClose(mfxSession session)
+{
+    // touch unreferenced parameters
+    session = session;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXClose(mfxSession session)
+
+mfxStatus pseudoMFXJoinSession(mfxSession session, mfxSession child_session)
+{
+    // touch unreferenced parameters
+    session = session;
+    child_session = child_session;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXJoinSession(mfxSession session, mfxSession child_session)
+
+mfxStatus pseudoMFXCloneSession(mfxSession session, mfxSession *clone)
+{
+    // touch unreferenced parameters
+    session = session;
+    clone = clone;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXCloneSession(mfxSession session, mfxSession *clone)
+
+void SuppressWarnings(...)
+{
+    // this functions is suppose to suppress warnings.
+    // Actually it does nothing.
+
+} // void SuppressWarnings(...)
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+return_value pseudo##func_name formal_param_list \
+{ \
+    SuppressWarnings actual_param_list; \
+    return MFX_ERR_UNKNOWN; \
+}
+
+#include "mfx_exposed_functions_list.h"
+
+} // namespace

+ 475 - 0
plugins/obs-qsv11/libmfx/src/mfx_library_iterator.cpp

@@ -0,0 +1,475 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2015 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_library_iterator.cpp
+
+\* ****************************************************************************** */
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#include "mfx_library_iterator.h"
+
+#include "mfx_dispatcher.h"
+#include "mfx_dispatcher_log.h"
+
+#include "mfx_dxva2_device.h"
+#include "mfx_load_dll.h"
+
+#include <tchar.h>
+#include <windows.h>
+
+namespace MFX
+{
+
+enum
+{
+    MFX_MAX_MERIT               = 0x7fffffff
+};
+
+//
+// declare registry keys
+//
+
+const
+wchar_t rootDispPath[] = L"Software\\Intel\\MediaSDK\\Dispatch";
+const
+wchar_t vendorIDKeyName[] = L"VendorID";
+const
+wchar_t deviceIDKeyName[] = L"DeviceID";
+const
+wchar_t meritKeyName[] = L"Merit";
+const
+wchar_t pathKeyName[] = L"Path";
+const
+wchar_t apiVersionName[] = L"APIVersion";
+
+mfxStatus SelectImplementationType(const mfxU32 adapterNum, mfxIMPL *pImplInterface, mfxU32 *pVendorID, mfxU32 *pDeviceID)
+{
+    if (NULL == pImplInterface)
+    {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    DXVA2Device dxvaDevice;
+    if (MFX_IMPL_VIA_D3D9 == *pImplInterface)
+    {
+        // try to create the Direct3D 9 device and find right adapter
+        if (!dxvaDevice.InitD3D9(adapterNum))
+        {
+            DISPATCHER_LOG_INFO((("dxvaDevice.InitD3D9(%d) Failed "), adapterNum ));
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else if (MFX_IMPL_VIA_D3D11 == *pImplInterface)
+    {
+        // try to open DXGI 1.1 device to get hardware ID
+        if (!dxvaDevice.InitDXGI1(adapterNum))
+        {
+            DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed "), adapterNum ));
+            return MFX_ERR_UNSUPPORTED;
+        }
+    } 
+    else if (MFX_IMPL_VIA_ANY == *pImplInterface)
+    {
+        // try the Direct3D 9 device
+        if (dxvaDevice.InitD3D9(adapterNum))
+        {
+            *pImplInterface = MFX_IMPL_VIA_D3D9; // store value for GetImplementationType() call
+        }
+        // else try to open DXGI 1.1 device to get hardware ID
+        else if (dxvaDevice.InitDXGI1(adapterNum))
+        {
+            *pImplInterface = MFX_IMPL_VIA_D3D11; // store value for GetImplementationType() call
+        }
+        else
+        {
+            DISPATCHER_LOG_INFO((("Unsupported adapter %d "), adapterNum ));
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else
+    {
+        DISPATCHER_LOG_ERROR((("Unknown implementation type %d "), *pImplInterface ));
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // obtain card's parameters
+    if (pVendorID && pDeviceID)
+    {
+        *pVendorID = dxvaDevice.GetVendorID();
+        *pDeviceID = dxvaDevice.GetDeviceID();
+    }
+
+    return MFX_ERR_NONE;
+}
+
+MFXLibraryIterator::MFXLibraryIterator(void)
+{
+    m_implType = MFX_LIB_PSEUDO;
+    m_implInterface = MFX_IMPL_UNSUPPORTED;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+    m_lastLibIndex = 0;
+    m_lastLibMerit = MFX_MAX_MERIT;
+
+    m_bIsSubKeyValid = 0;
+    m_StorageID = 0;
+
+    m_SubKeyName[0] = 0;
+} // MFXLibraryIterator::MFXLibraryIterator(void)
+
+MFXLibraryIterator::~MFXLibraryIterator(void)
+{
+    Release();
+
+} // MFXLibraryIterator::~MFXLibraryIterator(void)
+
+void MFXLibraryIterator::Release(void)
+{
+    m_implType = MFX_LIB_PSEUDO;
+    m_implInterface = MFX_IMPL_UNSUPPORTED;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+    m_lastLibIndex = 0;
+    m_lastLibMerit = MFX_MAX_MERIT;
+    m_SubKeyName[0] = 0;
+
+} // void MFXLibraryIterator::Release(void)
+
+mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID)
+{
+    // check error(s)
+    if ((MFX_LIB_SOFTWARE != implType) &&
+        (MFX_LIB_HARDWARE != implType))
+    {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // release the object before initialization
+    Release();
+    m_StorageID = storageID;
+    m_lastLibIndex = 0;
+
+    if (storageID == MFX_CURRENT_USER_KEY || storageID == MFX_LOCAL_MACHINE_KEY)
+    {
+        return InitRegistry(implType, implInterface, adapterNum, storageID);
+    }
+    else if (storageID == MFX_APP_FOLDER)
+    {
+        msdk_disp_char path[_MAX_PATH] = {};
+
+        ::GetModuleFileNameW(0, path, _MAX_PATH);
+        msdk_disp_char * dirSeparator = wcsrchr(path, L'\\');
+        if (dirSeparator < (path + _MAX_PATH))
+        {
+            *++dirSeparator = 0;
+        }        
+        
+        return InitFolder(implType, implInterface, adapterNum, path);
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+} // mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID)
+
+mfxStatus MFXLibraryIterator::InitRegistry(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID)
+{
+    HKEY rootHKey;
+    bool bRes;
+
+    // open required registry key
+    rootHKey = (MFX_LOCAL_MACHINE_KEY == storageID) ? (HKEY_LOCAL_MACHINE) : (HKEY_CURRENT_USER);
+    bRes = m_baseRegKey.Open(rootHKey, rootDispPath, KEY_READ);
+    if (false == bRes)
+    {
+        DISPATCHER_LOG_WRN((("Can't open %s\\%S : RegOpenKeyExA()==0x%x\n"),
+            (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
+            rootDispPath, GetLastError()))
+            return MFX_ERR_UNKNOWN;
+    }
+
+    // set the required library's implementation type
+    m_implType = implType;
+    m_implInterface = implInterface != 0 
+        ? implInterface
+        : MFX_IMPL_VIA_ANY;
+
+    //deviceID and vendorID are not actual for SW library loading
+    if (m_implType != MFX_LIB_SOFTWARE)
+    {
+        mfxStatus mfxRes = MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID);
+        if (MFX_ERR_NONE != mfxRes)
+        {
+            return mfxRes;
+        }
+    }
+
+    DISPATCHER_LOG_INFO((("Inspecting %s\\%S\n"),
+        (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
+        rootDispPath))
+
+    return MFX_ERR_NONE;
+} // mfxStatus MFXLibraryIterator::InitRegistry(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID)
+
+mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, const msdk_disp_char * path)
+{
+     const int maxPathLen = sizeof(m_path)/sizeof(m_path[0]);
+     m_path[0] = 0;
+     msdk_disp_char_cpy_s(m_path, maxPathLen, path);
+     size_t pathLen = wcslen(m_path);
+
+     // we looking for runtime in application folder, it should be named libmfxsw64 or libmfxsw32
+     mfx_get_default_dll_name(m_path + pathLen, maxPathLen - pathLen,  MFX_LIB_SOFTWARE);
+
+     // set the required library's implementation type
+     m_implType = implType;
+     m_implInterface = implInterface != 0 
+         ? implInterface
+         : MFX_IMPL_VIA_ANY;
+
+     //deviceID and vendorID are not actual for SW library loading
+     if (m_implType != MFX_LIB_SOFTWARE)
+     {
+         mfxStatus mfxRes = MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID);
+         if (MFX_ERR_NONE != mfxRes)
+         {
+             return mfxRes;
+         }
+     }
+     return MFX_ERR_NONE;
+} // mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, const msdk_disp_char * path)
+
+mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath
+                                             , size_t pathSize
+                                             , eMfxImplType *pImplType, mfxVersion minVersion)
+{
+    UNREFERENCED_PARAMETER(minVersion);
+
+    if (m_StorageID == MFX_APP_FOLDER)
+    {
+        if (m_lastLibIndex != 0)
+            return MFX_ERR_NOT_FOUND;
+
+        m_lastLibIndex = 1;
+        msdk_disp_char_cpy_s(pPath, pathSize, m_path);
+        *pImplType = MFX_LIB_SOFTWARE;
+        return MFX_ERR_NONE;
+    }
+
+    wchar_t libPath[MFX_MAX_DLL_PATH] = L"";
+    DWORD libIndex = 0;
+    DWORD libMerit = 0;
+    DWORD index;
+    bool enumRes;
+
+    // main query cycle
+    index = 0;
+    m_bIsSubKeyValid = false;
+    do
+    {
+        WinRegKey subKey;
+        wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME];
+        DWORD subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]);
+
+        // query next value name
+        enumRes = m_baseRegKey.EnumKey(index, subKeyName, &subKeyNameSize);
+        if (!enumRes)
+        {
+            DISPATCHER_LOG_WRN((("no more subkeys : RegEnumKeyExA()==0x%x\n"), GetLastError()))
+        }
+        else
+        {
+            DISPATCHER_LOG_INFO((("found subkey: %S\n"), subKeyName))
+
+            bool bRes;
+
+            // open the sub key
+            bRes = subKey.Open(m_baseRegKey, subKeyName, KEY_READ);
+            if (!bRes)
+            {
+                DISPATCHER_LOG_WRN((("error opening key %S :RegOpenKeyExA()==0x%x\n"), subKeyName, GetLastError()));
+            }
+            else
+            {
+                DISPATCHER_LOG_INFO((("opened key: %S\n"), subKeyName));
+
+                mfxU32 vendorID = 0, deviceID = 0, merit = 0;
+                DWORD size;
+
+                // query vendor and device IDs
+                size = sizeof(vendorID);
+                bRes = subKey.Query(vendorIDKeyName, REG_DWORD, (LPBYTE) &vendorID, &size);
+                DISPATCHER_LOG_OPERATION({
+                    if (bRes)
+                    {
+                        DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), vendorIDKeyName, vendorID));
+                    }
+                    else
+                    {
+                        DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), vendorIDKeyName, GetLastError()));
+                    }
+                })
+
+                if (bRes)
+                {
+                    size = sizeof(deviceID);
+                    bRes = subKey.Query(deviceIDKeyName, REG_DWORD, (LPBYTE) &deviceID, &size);
+                    DISPATCHER_LOG_OPERATION({
+                        if (bRes)
+                        {
+                            DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), deviceIDKeyName, deviceID));
+                        }
+                        else
+                        {
+                            DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), deviceIDKeyName, GetLastError()));
+                        }
+                    })
+                }
+                // query merit value
+                if (bRes)
+                {
+                    size = sizeof(merit);
+                    bRes = subKey.Query(meritKeyName, REG_DWORD, (LPBYTE) &merit, &size);
+                    DISPATCHER_LOG_OPERATION({
+                        if (bRes)
+                        {
+                            DISPATCHER_LOG_INFO((("loaded %S : %d\n"), meritKeyName, merit));
+                        }
+                        else
+                        {
+                            DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), meritKeyName, GetLastError()));
+                        }
+                    })
+                }
+
+                // if the library fits required parameters,
+                // query the library's path
+                if (bRes)
+                {
+                    // compare device's and library's IDs
+                    if (MFX_LIB_HARDWARE == m_implType)
+                    {
+                        if (m_vendorID != vendorID) 
+                        {
+                            bRes = false;
+                            DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), vendorIDKeyName, m_vendorID, vendorID));
+                        }
+                        if (bRes && m_deviceID != deviceID)
+                        {
+                            bRes = false;
+                            DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), deviceIDKeyName, m_deviceID, deviceID));
+                        }
+                    }
+
+                    DISPATCHER_LOG_OPERATION({
+                    if (bRes)
+                    {
+                        if (!(((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
+                             (libMerit < merit)))
+                        {
+                            DISPATCHER_LOG_WRN((("merit conflict: lastMerit = 0x%x, requiredMerit = 0x%x, libraryMerit = 0x%x, lastindex = %d, index = %d\n")
+                                        , m_lastLibMerit, merit, libMerit, m_lastLibIndex, index));
+                        }
+                    }})
+
+                    if ((bRes) &&
+                        ((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
+                        (libMerit < merit))
+                    {
+                        wchar_t tmpPath[MFX_MAX_DLL_PATH];
+                        DWORD tmpPathSize = sizeof(tmpPath);
+
+                        bRes = subKey.Query(pathKeyName, REG_SZ, (LPBYTE) tmpPath, &tmpPathSize);
+                        if (!bRes)
+                        {
+                            DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
+                        }
+                        else
+                        {
+                            DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, tmpPath));
+
+                            msdk_disp_char_cpy_s(libPath, sizeof(libPath) / sizeof(libPath[0]), tmpPath);
+                            msdk_disp_char_cpy_s(m_SubKeyName, sizeof(m_SubKeyName) / sizeof(m_SubKeyName[0]), subKeyName);
+
+                            libMerit = merit;
+                            libIndex = index;
+
+                            // set the library's type
+                            if ((0 == vendorID) || (0 == deviceID))
+                            {
+                                *pImplType = MFX_LIB_SOFTWARE;
+                                
+                                DISPATCHER_LOG_INFO((("Library type is MFX_LIB_SOFTWARE\n")));
+                            }
+                            else
+                            {
+                                *pImplType = MFX_LIB_HARDWARE;
+                                DISPATCHER_LOG_INFO((("Library type is MFX_LIB_HARDWARE\n")));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // advance key index
+        index += 1;
+
+    } while (enumRes);
+
+    // if the library's path was successfully read,
+    // the merit variable holds valid value
+    if (0 == libMerit)
+    {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    msdk_disp_char_cpy_s(pPath, pathSize, libPath);
+
+    m_lastLibIndex = libIndex;
+    m_lastLibMerit = libMerit;
+    m_bIsSubKeyValid = true;
+
+    return MFX_ERR_NONE;
+
+} // mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion)
+
+mfxIMPL MFXLibraryIterator::GetImplementationType()
+{
+    return m_implInterface;
+} // mfxIMPL MFXLibraryIterator::GetImplementationType()
+
+bool MFXLibraryIterator::GetSubKeyName(msdk_disp_char *subKeyName, size_t length) const
+{
+    msdk_disp_char_cpy_s(subKeyName, length, m_SubKeyName);
+    return m_bIsSubKeyValid;
+}
+} // namespace MFX
+#endif // #if defined(_WIN32) || defined(_WIN64)
+

+ 241 - 0
plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp

@@ -0,0 +1,241 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_load_dll.cpp
+
+\* ****************************************************************************** */
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#include "mfx_dispatcher.h"
+#include "mfx_load_dll.h"
+
+#include <wchar.h>
+#include <string.h>
+#include <windows.h>
+
+#if !defined(_DEBUG)
+
+#if defined(_WIN64)
+const
+wchar_t * const defaultDLLName[2] = {L"libmfxhw64.dll",
+                                     L"libmfxsw64.dll"};
+const
+wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw64.dll",
+                                          L"libmfxaudiosw64.dll"};
+
+const 
+wchar_t  * const defaultPluginDLLName[2] = {L"mfxplugin64_hw.dll",
+                                            L"mfxplugin64_sw.dll"};
+
+#elif defined(_WIN32)
+const
+wchar_t * const defaultDLLName[2] = {L"libmfxhw32.dll",
+                                     L"libmfxsw32.dll"};
+
+const
+wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw32.dll",
+                                          L"libmfxaudiosw32.dll"};
+
+const 
+wchar_t  * const defaultPluginDLLName[2] = {L"mfxplugin32_hw.dll",
+                                            L"mfxplugin32_sw.dll"};
+
+#endif // (defined(_WIN64))
+
+#else // defined(_DEBUG)
+
+#if defined(_WIN64)
+const
+wchar_t * const defaultDLLName[2] = {L"libmfxhw64_d.dll",
+                                     L"libmfxsw64_d.dll"};
+const
+wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw64_d.dll",
+                                          L"libmfxaudiosw64_d.dll"};
+
+const 
+wchar_t  * const defaultPluginDLLName[2] = {L"mfxplugin64_hw_d.dll",
+                                            L"mfxplugin64_sw_d.dll"};
+
+#elif defined(WIN32)
+const
+wchar_t * const defaultDLLName[2] = {L"libmfxhw32_d.dll",
+                                     L"libmfxsw32_d.dll"};
+
+
+const
+wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw32_d.dll",
+                                          L"libmfxaudiosw32_d.dll"};
+
+const 
+wchar_t  * const defaultPluginDLLName[2] = {L"mfxplugin32_hw_d.dll",
+                                            L"mfxplugin32_sw_d.dll"};
+
+#endif // (defined(_WIN64))
+
+#endif // !defined(_DEBUG)
+
+namespace MFX
+{
+
+
+mfxStatus mfx_get_default_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType)
+{
+    if (!pPath)
+    {
+        return MFX_ERR_NULL_PTR;
+    }
+    
+
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultDLLName[implType & 1])
+        ? MFX_ERR_NONE : MFX_ERR_UNKNOWN;
+#else    
+    wcscpy(pPath, defaultDLLName[implType & 1]);
+    return MFX_ERR_NONE;
+#endif
+} // mfxStatus mfx_get_default_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType)
+
+mfxStatus mfx_get_default_plugin_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType)
+{
+    if (!pPath)
+    {
+        return MFX_ERR_NULL_PTR;
+    }
+
+
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultPluginDLLName[implType & 1])
+        ? MFX_ERR_NONE : MFX_ERR_UNKNOWN;
+#else    
+    wcscpy(pPath, defaultPluginDLLName[implType & 1]);
+    return MFX_ERR_NONE;
+#endif
+}
+
+mfxStatus mfx_get_default_audio_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType)
+{
+    if (!pPath)
+    {
+        return MFX_ERR_NULL_PTR;
+    }
+    
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultAudioDLLName[implType & 1])
+        ? MFX_ERR_NONE : MFX_ERR_UNKNOWN;
+#else    
+    wcscpy(pPath, defaultAudioDLLName[implType & 1]);
+    return MFX_ERR_NONE;
+#endif
+} // mfxStatus mfx_get_default_audio_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType)
+
+mfxModuleHandle mfx_dll_load(const msdk_disp_char *pFileName)
+{
+    mfxModuleHandle hModule = (mfxModuleHandle) 0;
+
+    // check error(s)
+    if (NULL == pFileName)
+    {
+        return NULL;
+    }
+
+    // set the silent error mode
+    DWORD prevErrorMode = 0;
+#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__)
+    SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode);
+#else
+    prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+    // load the library's module
+    hModule = LoadLibraryExW(pFileName,NULL,0);
+    // set the previous error mode
+#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__)
+    SetThreadErrorMode(prevErrorMode, NULL);
+#else
+    SetErrorMode(prevErrorMode);
+#endif
+
+    return hModule;
+
+} // mfxModuleHandle mfx_dll_load(const wchar_t *pFileName)
+
+mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *pFunctionName)
+{
+    if (NULL == handle)
+    {
+        return NULL;
+    }
+
+    return (mfxFunctionPointer) GetProcAddress((HMODULE) handle, pFunctionName);
+} // mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *pFunctionName)
+
+bool mfx_dll_free(mfxModuleHandle handle)
+{
+    if (NULL == handle)
+    {
+        return true;
+    }
+
+    BOOL bRes = FreeLibrary((HMODULE)handle);
+
+    return !!bRes;
+} // bool mfx_dll_free(mfxModuleHandle handle)
+
+mfxModuleHandle mfx_get_dll_handle(const msdk_disp_char *pFileName)
+{
+    mfxModuleHandle hModule = (mfxModuleHandle) 0;
+
+    // check error(s)
+    if (NULL == pFileName)
+    {
+        return NULL;
+    }
+
+    // set the silent error mode
+    DWORD prevErrorMode = 0;
+#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__)
+    SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode); 
+#else
+    prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+    // load the library's module
+    GetModuleHandleExW(0, pFileName, (HMODULE*) &hModule);
+    // set the previous error mode
+#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__)
+    SetThreadErrorMode(prevErrorMode, NULL);
+#else
+    SetErrorMode(prevErrorMode);
+#endif
+    return hModule;
+}
+
+
+} // namespace MFX
+
+#endif // #if defined(_WIN32) || defined(_WIN64)

+ 458 - 0
plugins/obs-qsv11/libmfx/src/mfx_load_plugin.cpp

@@ -0,0 +1,458 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_load_plugin.h
+
+\* ****************************************************************************** */
+
+#include "mfx_load_plugin.h"
+#include "mfx_load_dll.h"
+#include "mfx_dispatcher_log.h"
+
+#define TRACE_PLUGIN_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[PLUGIN]: "str), __VA_ARGS__))
+#define TRACE_PLUGIN_INFO(str, ...) DISPATCHER_LOG_INFO((("[PLUGIN]: "str), __VA_ARGS__))
+
+#define CREATE_PLUGIN_FNC "CreatePlugin"
+
+MFX::PluginModule::PluginModule()
+    : mHmodule()
+    , mCreatePluginPtr() 
+    , mPath()
+{
+}
+
+MFX::PluginModule::PluginModule(const PluginModule & that) 
+    : mHmodule(mfx_dll_load(that.mPath))
+    , mCreatePluginPtr(that.mCreatePluginPtr) 
+{
+    msdk_disp_char_cpy_s(mPath, sizeof(mPath) / sizeof(*mPath), that.mPath);
+}
+
+MFX::PluginModule & MFX::PluginModule::operator = (const MFX::PluginModule & that) 
+{
+    if (this != &that) 
+    {
+        Tidy();
+        mHmodule = mfx_dll_load(that.mPath);
+        mCreatePluginPtr = that.mCreatePluginPtr;
+        msdk_disp_char_cpy_s(mPath, sizeof(mPath) / sizeof(*mPath), that.mPath);
+    }
+    return *this;
+}
+
+MFX::PluginModule::PluginModule(const msdk_disp_char * path)
+    : mCreatePluginPtr() 
+{
+    mHmodule = mfx_dll_load(path);
+    if (NULL == mHmodule) {
+        TRACE_PLUGIN_ERROR("Cannot load module: %S\n", MSDK2WIDE(path));
+        return ;
+    }
+    TRACE_PLUGIN_INFO("Plugin loaded at: %S\n", MSDK2WIDE(path));
+    
+    mCreatePluginPtr = (CreatePluginPtr_t)mfx_dll_get_addr(mHmodule, CREATE_PLUGIN_FNC);
+    if (NULL == mCreatePluginPtr) {
+        TRACE_PLUGIN_ERROR("Cannot get procedure address: %s\n", CREATE_PLUGIN_FNC);
+        return ;
+    }
+    
+    msdk_disp_char_cpy_s(mPath, sizeof(mPath) / sizeof(*mPath), path);
+}
+
+bool MFX::PluginModule::Create( mfxPluginUID uid, mfxPlugin& plg) 
+{
+    bool result = false;
+    if (mCreatePluginPtr) 
+    {
+        mfxStatus mfxResult = mCreatePluginPtr(uid, &plg);
+        result = (MFX_ERR_NONE == mfxResult);
+        if (!result) {
+            TRACE_PLUGIN_ERROR("\"%S::%s\" returned %d\n", MSDK2WIDE(mPath), CREATE_PLUGIN_FNC, mfxResult);
+        } else {
+            TRACE_PLUGIN_INFO("\"%S::%s\" SUCCEED\n", MSDK2WIDE(mPath), CREATE_PLUGIN_FNC);
+        }
+    }
+    return result;
+}
+
+void MFX::PluginModule::Tidy()
+{
+    mfx_dll_free(mHmodule);
+    mCreatePluginPtr = NULL;
+    mHmodule = NULL;
+}
+
+MFX::PluginModule::~PluginModule(void) 
+{
+    Tidy();
+}
+
+bool MFX::MFXPluginFactory::RunVerification( const mfxPlugin & plg, const PluginDescriptionRecord &dsc, mfxPluginParam &pluginParams)
+{
+    if (plg.PluginInit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->PluginInit = 0\n", 0);
+        return false;
+    }
+    if (plg.PluginClose == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->PluginClose = 0\n", 0);
+        return false;
+    }
+    if (plg.GetPluginParam == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->GetPluginParam = 0\n", 0);
+        return false;
+    }
+    
+    if (plg.Execute == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->Execute = 0\n", 0);
+        return false;
+    }
+    if (plg.FreeResources == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->FreeResources = 0\n", 0);
+        return false;
+    }
+
+    mfxStatus sts = plg.GetPluginParam(plg.pthis, &pluginParams);
+    if (sts != MFX_ERR_NONE)
+    {
+        TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned %d\n", sts);
+        return false;
+    }
+
+    if (dsc.Default)
+    {
+        // for default plugins there is no description, dsc.APIVersion, dsc.PluginVersion and dsc.PluginUID were set by dispatcher
+        // dsc.PluginVersion == requested plugin version (parameter of MFXVideoUSER_Load); dsc.APIVersion == loaded library API
+        if (dsc.PluginVersion > pluginParams.PluginVersion)
+        {
+            TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned PluginVersion=%d, but it is smaller than requested : %d\n", pluginParams.PluginVersion, dsc.PluginVersion);
+            return false;
+        }
+    }
+    else
+    {
+        if (!dsc.onlyVersionRegistered && pluginParams.CodecId != dsc.CodecId) 
+        {
+            TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned CodecId="MFXFOURCCTYPE()", but registration has CodecId="MFXFOURCCTYPE()"\n"
+                , MFXU32TOFOURCC(pluginParams.CodecId), MFXU32TOFOURCC(dsc.CodecId));
+            return false;
+        }
+
+        if (!dsc.onlyVersionRegistered && pluginParams.Type != dsc.Type) 
+        {
+            TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned Type=%d, but registration has Type=%d\n", pluginParams.Type, dsc.Type);
+            return false;
+        }
+
+        if (pluginParams.PluginUID !=  dsc.PluginUID) 
+        {
+            TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned UID="MFXGUIDTYPE()", but registration has UID="MFXGUIDTYPE()"\n"
+                , MFXGUIDTOHEX(&pluginParams.PluginUID), MFXGUIDTOHEX(&dsc.PluginUID));
+            return false;
+        }
+
+        if (pluginParams.PluginVersion != dsc.PluginVersion) 
+        {
+            TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned PluginVersion=%d, but registration has PlgVer=%d\n", pluginParams.PluginVersion, dsc.PluginVersion);
+            return false;
+        }
+
+        if (pluginParams.APIVersion.Version != dsc.APIVersion.Version)
+        {
+            TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned APIVersion=%d.%d, but registration has APIVer=%d.%d\n"
+                , pluginParams.APIVersion.Major, pluginParams.APIVersion.Minor
+                , dsc.APIVersion.Major, dsc.APIVersion.Minor);
+            return false;
+        }
+    }
+
+    switch(pluginParams.Type) 
+    {
+        case MFX_PLUGINTYPE_VIDEO_DECODE: 
+        case MFX_PLUGINTYPE_VIDEO_ENCODE: 
+        case MFX_PLUGINTYPE_VIDEO_VPP: 
+        {
+            TRACE_PLUGIN_INFO("plugin type= %d\n", pluginParams.Type);
+            if (plg.Video == 0) 
+            {
+                TRACE_PLUGIN_ERROR("plg->Video = 0\n", 0);
+                return false;
+            }
+
+            if (!VerifyCodecCommon(*plg.Video))
+                return false;
+            break;
+        }
+    }
+
+    switch(pluginParams.Type) 
+    {
+        case MFX_PLUGINTYPE_VIDEO_DECODE: 
+            return VerifyDecoder(*plg.Video);
+        case MFX_PLUGINTYPE_AUDIO_DECODE: 
+            return VerifyAudioDecoder(*plg.Audio);
+        case MFX_PLUGINTYPE_VIDEO_ENCODE:        
+            return VerifyEncoder(*plg.Video);
+        case MFX_PLUGINTYPE_AUDIO_ENCODE:        
+            return VerifyAudioEncoder(*plg.Audio);
+        case MFX_PLUGINTYPE_VIDEO_VPP: 
+            return VerifyVpp(*plg.Video); 
+        case MFX_PLUGINTYPE_VIDEO_ENC:
+            return VerifyEnc(*plg.Video);
+        default: 
+        {
+            TRACE_PLUGIN_ERROR("unsupported plugin type: %d\n", pluginParams.Type);
+            return false;
+        }
+    }
+}
+
+bool MFX::MFXPluginFactory::VerifyVpp( const mfxVideoCodecPlugin &vpp ) 
+{
+    if (vpp.VPPFrameSubmit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->VPPFrameSubmit = 0\n", 0);
+        return false;
+    }
+
+    return true;
+
+}
+
+bool MFX::MFXPluginFactory::VerifyEncoder( const mfxVideoCodecPlugin &encoder )
+{
+    if (encoder.EncodeFrameSubmit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->EncodeFrameSubmit = 0\n", 0);
+        return false;
+    }
+    
+    return true;
+}
+
+bool MFX::MFXPluginFactory::VerifyAudioEncoder( const mfxAudioCodecPlugin &encoder )
+{
+    if (encoder.EncodeFrameSubmit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Audio->EncodeFrameSubmit = 0\n", 0);
+        return false;
+    }
+    
+    return true;
+}
+
+bool MFX::MFXPluginFactory::VerifyEnc( const mfxVideoCodecPlugin &videoEnc )
+{
+    if (videoEnc.ENCFrameSubmit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->EncodeFrameSubmit = 0\n", 0);
+        return false;
+    }
+
+    return true;
+}
+
+bool MFX::MFXPluginFactory::VerifyDecoder( const mfxVideoCodecPlugin &decoder )
+{
+    if (decoder.DecodeHeader == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->DecodeHeader = 0\n", 0);
+        return false;
+    }
+    if (decoder.GetPayload == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->GetPayload = 0\n", 0);
+        return false;
+    }
+    if (decoder.DecodeFrameSubmit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->DecodeFrameSubmit = 0\n", 0);
+        return false;
+    }
+
+    return true;
+}
+
+bool MFX::MFXPluginFactory::VerifyAudioDecoder( const mfxAudioCodecPlugin &decoder )
+{
+    if (decoder.DecodeHeader == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->Audio->DecodeHeader = 0\n", 0);
+        return false;
+    }
+//    if (decoder.GetPayload == 0)
+    {
+  //      TRACE_PLUGIN_ERROR("plg->Audio->GetPayload = 0\n", 0);
+    //    return false;
+    }
+    if (decoder.DecodeFrameSubmit == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Audio->DecodeFrameSubmit = 0\n", 0);
+        return false;
+    }
+
+    return true;
+}
+
+bool MFX::MFXPluginFactory::VerifyCodecCommon( const mfxVideoCodecPlugin & videoCodec )
+{
+    if (videoCodec.Query == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->Query = 0\n", 0);
+        return false;
+    }
+    //todo: remove
+    if (videoCodec.Query == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->Query = 0\n", 0);
+        return false;
+    }
+    if (videoCodec.QueryIOSurf == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->QueryIOSurf = 0\n", 0);
+        return false;
+    }
+    if (videoCodec.Init == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->Init = 0\n", 0);
+        return false;
+    }
+    if (videoCodec.Reset == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->Reset = 0\n", 0);
+        return false;
+    }
+    if (videoCodec.Close == 0) 
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->Close = 0\n", 0);
+        return false;
+    }
+    if (videoCodec.GetVideoParam == 0)
+    {
+        TRACE_PLUGIN_ERROR("plg->Video->GetVideoParam = 0\n", 0);
+        return false;
+    }
+
+    return true;
+}
+
+mfxStatus MFX::MFXPluginFactory::Create(const PluginDescriptionRecord & rec)
+{
+    PluginModule plgModule(rec.sPath);
+    mfxPlugin plg = {};
+    mfxPluginParam plgParams;
+    
+    if (!plgModule.Create(rec.PluginUID, plg)) 
+    {
+        return MFX_ERR_UNKNOWN;
+    }
+    
+    if (!RunVerification(plg, rec, plgParams)) 
+    {
+        //will do not call plugin close since it is not safe to do that until structure is corrected
+        return MFX_ERR_UNKNOWN;
+    }
+
+   
+    if (rec.Type == MFX_PLUGINTYPE_AUDIO_DECODE ||
+        rec.Type == MFX_PLUGINTYPE_AUDIO_ENCODE)
+    {
+        mfxStatus sts = MFXAudioUSER_Register(mSession, plgParams.Type, &plg);
+        if (MFX_ERR_NONE != sts) 
+        {
+            TRACE_PLUGIN_ERROR(" MFXAudioUSER_Register returned %d\n", sts);
+            return sts;
+        }
+    }
+    else
+    {
+        mfxStatus sts = MFXVideoUSER_Register(mSession, plgParams.Type, &plg);
+        if (MFX_ERR_NONE != sts) 
+        {
+            TRACE_PLUGIN_ERROR(" MFXVideoUSER_Register returned %d\n", sts);
+            return sts;
+        }
+    }
+    
+    mPlugins.push_back(FactoryRecord(plgParams, plgModule, plg));
+
+    return MFX_ERR_NONE;
+}
+
+MFX::MFXPluginFactory::~MFXPluginFactory() 
+{
+    Close();
+}
+
+MFX::MFXPluginFactory::MFXPluginFactory( mfxSession session ) 
+{
+    mSession = session;
+}
+
+bool MFX::MFXPluginFactory::Destroy( const mfxPluginUID & uidToDestroy) 
+{
+    for (MFXVector<FactoryRecord >::iterator i = mPlugins.begin(); i!= mPlugins.end(); i++) 
+    {
+        if (i->plgParams.PluginUID == uidToDestroy) 
+        {
+            DestroyPlugin(*i);
+            //dll unload should happen here
+            //todo: check that dll_free fail is traced
+            mPlugins.erase(i);
+            return  true;
+        }
+    }
+    return false;
+}
+
+void MFX::MFXPluginFactory::Close() 
+{
+    for (MFXVector<FactoryRecord>::iterator i = mPlugins.begin(); i!= mPlugins.end(); i++) 
+    {
+        DestroyPlugin(*i);
+    }
+    mPlugins.clear();
+}
+
+void MFX::MFXPluginFactory::DestroyPlugin( FactoryRecord & record)
+{
+    mfxStatus sts;
+    if (record.plgParams.Type == MFX_PLUGINTYPE_AUDIO_DECODE ||
+        record.plgParams.Type == MFX_PLUGINTYPE_AUDIO_ENCODE)
+    {
+        sts = MFXAudioUSER_Unregister(mSession, record.plgParams.Type);
+        TRACE_PLUGIN_INFO(" MFXAudioUSER_Unregister for Type=%d, returned %d\n", record.plgParams.Type, sts);
+    }
+    else
+    {
+        sts = MFXVideoUSER_Unregister(mSession, record.plgParams.Type);
+        TRACE_PLUGIN_INFO(" MFXVideoUSER_Unregister for Type=%d, returned %d\n", record.plgParams.Type, sts);
+    }
+}

+ 500 - 0
plugins/obs-qsv11/libmfx/src/mfx_plugin_hive.cpp

@@ -0,0 +1,500 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2013-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_plugin_hive.cpp
+
+\* ****************************************************************************** */
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#include "mfx_plugin_hive.h"
+#include "mfx_library_iterator.h"
+#include "mfx_dispatcher.h"
+#include "mfx_dispatcher_log.h"
+#include "mfx_load_dll.h"
+
+#define TRACE_HIVE_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[HIVE]: "str), __VA_ARGS__))
+#define TRACE_HIVE_INFO(str, ...) DISPATCHER_LOG_INFO((("[HIVE]: "str), __VA_ARGS__))
+#define TRACE_HIVE_WRN(str, ...) DISPATCHER_LOG_WRN((("[HIVE]: "str), __VA_ARGS__))
+
+namespace 
+{
+    const wchar_t rootPluginPath[] = L"Software\\Intel\\MediaSDK\\Plugin";
+    const wchar_t rootDispatchPath[] = L"Software\\Intel\\MediaSDK\\Dispatch";
+    const wchar_t pluginSubkey[] = L"Plugin";
+    const wchar_t TypeKeyName[] = L"Type";
+    const wchar_t CodecIDKeyName[] = L"CodecID";
+    const wchar_t GUIDKeyName[] = L"GUID";
+    const wchar_t PathKeyName[] = L"Path";
+    const wchar_t DefaultKeyName[] = L"Default";
+    const wchar_t PlgVerKeyName[] = L"PluginVersion";
+    const wchar_t APIVerKeyName[] = L"APIVersion";
+}
+
+namespace 
+{
+#ifdef _WIN64
+    const wchar_t pluginFileName[] = L"FileName64";
+#else
+    const wchar_t pluginFileName[] = L"FileName32";
+#endif // _WIN64
+
+    //do not allow store plugin in different hierarchy
+    const wchar_t pluginFileNameRestrictedCharacters[] = L"\\/";
+    const wchar_t pluginCfgFileName[] = L"plugin.cfg";
+    const wchar_t pluginSearchPattern[] = L"????????????????????????????????";
+    const mfxU32 pluginCfgFileNameLen = 10;
+    const mfxU32 pluginDirNameLen = 32;
+    const mfxU32 defaultPluginNameLen = 25;
+    const mfxU32 charsPermfxU8 = 2;
+    const mfxU32 slashLen = 1;
+    enum 
+    {
+        MAX_PLUGIN_FILE_LINE = 4096
+    };
+
+    #define alignStr() "%-14S"
+}
+
+MFX::MFXPluginsInHive::MFXPluginsInHive(int mfxStorageID, const msdk_disp_char *msdkLibSubKey, mfxVersion currentAPIVersion)
+    : MFXPluginStorageBase(currentAPIVersion)
+{
+    HKEY rootHKey;
+    bool bRes;
+    WinRegKey regKey;
+
+    if (MFX_LOCAL_MACHINE_KEY != mfxStorageID && MFX_CURRENT_USER_KEY != mfxStorageID)
+        return;
+
+    // open required registry key
+    rootHKey = (MFX_LOCAL_MACHINE_KEY == mfxStorageID) ? (HKEY_LOCAL_MACHINE) : (HKEY_CURRENT_USER);
+    if (msdkLibSubKey) {
+        //dispatch/subkey/plugin
+        bRes = regKey.Open(rootHKey, rootDispatchPath, KEY_READ);
+        if (bRes)
+        {
+            bRes = regKey.Open(regKey, msdkLibSubKey, KEY_READ);
+        }
+        if (bRes)
+        {
+            bRes = regKey.Open(regKey, pluginSubkey, KEY_READ);
+        }
+    }
+    else 
+    {
+        bRes = regKey.Open(rootHKey, rootPluginPath, KEY_READ);
+    }
+
+    if (false == bRes) {
+        return;
+    }
+    DWORD index = 0;
+    if (!regKey.QueryInfo(&index)) {
+        return;
+    }
+    try 
+    {
+        resize(index);
+    }
+    catch (...) {
+        TRACE_HIVE_ERROR("new PluginDescriptionRecord[%d] threw an exception: \n", index);
+        return;
+    }
+
+    for(index = 0; ; index++) 
+    {
+        wchar_t   subKeyName[MFX_MAX_REGISTRY_KEY_NAME];
+        DWORD     subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]);
+        WinRegKey subKey;
+
+        // query next value name
+        bool enumRes = regKey.EnumKey(index, subKeyName, &subKeyNameSize);
+        if (!enumRes) {
+            break;
+        }
+
+        // open the sub key
+        bRes = subKey.Open(regKey, subKeyName, KEY_READ);
+        if (!bRes) {
+            continue;
+        }
+
+        if (msdkLibSubKey) 
+        {
+            TRACE_HIVE_INFO("Found Plugin: %s\\%S\\%S\\%S\\%S\n", (MFX_LOCAL_MACHINE_KEY == mfxStorageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
+                rootDispatchPath, msdkLibSubKey, pluginSubkey, subKeyName);
+        }
+        else 
+        {
+            TRACE_HIVE_INFO("Found Plugin: %s\\%S\\%S\n", (MFX_LOCAL_MACHINE_KEY == mfxStorageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
+                rootPluginPath, subKeyName);
+        }
+
+        PluginDescriptionRecord descriptionRecord;
+
+        if (!QueryKey(subKey, TypeKeyName, descriptionRecord.Type)) 
+        {
+            continue;
+        }
+        TRACE_HIVE_INFO(alignStr()" : %d\n", TypeKeyName, descriptionRecord.Type);
+
+        if (QueryKey(subKey, CodecIDKeyName, descriptionRecord.CodecId)) 
+        {
+            TRACE_HIVE_INFO(alignStr()" : "MFXFOURCCTYPE()" \n", CodecIDKeyName, MFXU32TOFOURCC(descriptionRecord.CodecId));
+        }
+        else
+        {
+                TRACE_HIVE_INFO(alignStr()" : \n", CodecIDKeyName, "NOT REGISTERED");
+        }
+
+        if (!QueryKey(subKey, GUIDKeyName, descriptionRecord.PluginUID)) 
+        {
+            continue;
+        }
+        TRACE_HIVE_INFO(alignStr()" : "MFXGUIDTYPE()"\n", GUIDKeyName, MFXGUIDTOHEX(&descriptionRecord.PluginUID));
+
+        mfxU32 nSize = sizeof(descriptionRecord.sPath)/sizeof(*descriptionRecord.sPath);
+        if (!subKey.Query(PathKeyName, descriptionRecord.sPath, nSize)) 
+        {
+            TRACE_HIVE_WRN("no value for : %S\n", PathKeyName);
+            continue;
+        }
+        TRACE_HIVE_INFO(alignStr()" : %S\n", PathKeyName, descriptionRecord.sPath);
+
+        if (!QueryKey(subKey, DefaultKeyName, descriptionRecord.Default)) 
+        {
+            continue;
+        }
+        TRACE_HIVE_INFO(alignStr()" : %s\n", DefaultKeyName, descriptionRecord.Default ? "true" : "false");
+
+        mfxU32 version;
+        if (!QueryKey(subKey, PlgVerKeyName, version)) 
+        {
+            continue;
+        }
+        descriptionRecord.PluginVersion = static_cast<mfxU16>(version);
+        if (0 == version) 
+        {
+            TRACE_HIVE_ERROR(alignStr()" : %d, which is invalid\n", PlgVerKeyName, descriptionRecord.PluginVersion);
+            continue;
+        } 
+        else 
+        { 
+            TRACE_HIVE_INFO(alignStr()" : %d\n", PlgVerKeyName, descriptionRecord.PluginVersion);
+        }
+
+        mfxU32 APIVersion;
+        if (!QueryKey(subKey, APIVerKeyName, APIVersion)) 
+        {
+            continue;
+        }
+        ConvertAPIVersion(APIVersion, descriptionRecord);
+        TRACE_HIVE_INFO(alignStr()" : %d.%d \n", APIVerKeyName, descriptionRecord.APIVersion.Major, descriptionRecord.APIVersion.Minor);
+
+        try 
+        {
+            operator[](index) = descriptionRecord;
+        }
+        catch (...) {
+            TRACE_HIVE_ERROR("operator[](%d) = descriptionRecord; - threw exception \n", index);
+        }
+    }
+}
+
+MFX::MFXPluginsInFS::MFXPluginsInFS( mfxVersion currentAPIVersion ) 
+    : MFXPluginStorageBase(currentAPIVersion)
+    , mIsVersionParsed()
+    , mIsAPIVersionParsed()
+{
+    WIN32_FIND_DATAW find_data;
+    msdk_disp_char currentModuleName[MAX_PLUGIN_PATH];
+    
+    GetModuleFileNameW(NULL, currentModuleName, MAX_PLUGIN_PATH);
+    if (GetLastError() != 0) 
+    {
+        TRACE_HIVE_ERROR("GetModuleFileName() reported an error: %d\n", GetLastError());
+        return;
+    }
+    msdk_disp_char *lastSlashPos = wcsrchr(currentModuleName, L'\\');
+    if (!lastSlashPos) {
+        lastSlashPos = currentModuleName;
+    }
+    mfxU32 executableDirLen = (mfxU32)(lastSlashPos - currentModuleName) + slashLen;
+    if (executableDirLen + pluginDirNameLen + pluginCfgFileNameLen >= MAX_PLUGIN_PATH) 
+    {
+        TRACE_HIVE_ERROR("MAX_PLUGIN_PATH which is %d, not enough to locate plugin path\n", MAX_PLUGIN_PATH);
+        return;
+    }
+    msdk_disp_char_cpy_s(lastSlashPos + slashLen
+        , MAX_PLUGIN_PATH - executableDirLen, pluginSearchPattern);
+
+    HANDLE fileFirst = FindFirstFileW(currentModuleName, &find_data);
+    if (INVALID_HANDLE_VALUE == fileFirst) 
+    {
+        TRACE_HIVE_ERROR("FindFirstFileW() unable to locate any plugins folders\n", 0);
+        return;
+    }
+    do 
+    {
+        if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
+        {
+            continue;
+        }
+        if (pluginDirNameLen != wcslen(find_data.cFileName)) 
+        {
+            continue;
+        }
+        //converting dirname into guid
+        PluginDescriptionRecord descriptionRecord;
+        descriptionRecord.APIVersion = currentAPIVersion;
+        descriptionRecord.onlyVersionRegistered = true;
+
+        mfxU32 i = 0;
+        for(i = 0; i != pluginDirNameLen / charsPermfxU8; i++) 
+        {
+            mfxU32 hexNum = 0;
+            if (1 != swscanf_s(find_data.cFileName + charsPermfxU8 * i, L"%2x", &hexNum)) 
+            {
+                // it is ok to have non-plugin subdirs with length 32
+                //TRACE_HIVE_INFO("folder name \"%S\" is not a valid GUID string\n", find_data.cFileName);
+                break;
+            }
+            if (hexNum == 0 && find_data.cFileName + charsPermfxU8 * i != wcsstr(find_data.cFileName + 2*i, L"00"))
+            {
+                // it is ok to have non-plugin subdirs with length 32
+                //TRACE_HIVE_INFO("folder name \"%S\" is not a valid GUID string\n", find_data.cFileName);
+                break;
+            }
+            descriptionRecord.PluginUID.Data[i] = (mfxU8)hexNum;
+        }
+        if (i != pluginDirNameLen / charsPermfxU8) {
+            continue;
+        }
+
+        msdk_disp_char_cpy_s(currentModuleName + executableDirLen
+            , MAX_PLUGIN_PATH - executableDirLen, find_data.cFileName);
+
+        msdk_disp_char_cpy_s(currentModuleName + executableDirLen + pluginDirNameLen
+            , MAX_PLUGIN_PATH - executableDirLen - pluginDirNameLen, L"\\");
+
+        //this is path to plugin directory
+        msdk_disp_char_cpy_s(descriptionRecord.sPath
+            , sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath), currentModuleName);
+        
+        msdk_disp_char_cpy_s(currentModuleName + executableDirLen + pluginDirNameLen + slashLen
+            , MAX_PLUGIN_PATH - executableDirLen - pluginDirNameLen - slashLen, pluginCfgFileName);
+
+        FILE *pluginCfgFile = 0;
+        _wfopen_s(&pluginCfgFile, currentModuleName, L"r");
+        if (!pluginCfgFile) 
+        {
+            TRACE_HIVE_INFO("in directory \"%S\" no mandatory \"%S\"\n"
+                , find_data.cFileName, pluginCfgFileName);
+            continue;
+        }
+        
+        if (ParseFile(pluginCfgFile, descriptionRecord)) 
+        {
+            try 
+            {
+                push_back(descriptionRecord);
+            }
+            catch (...) {
+                TRACE_HIVE_ERROR("mRecords.push_back(descriptionRecord); - threw exception \n", 0);
+            }            
+        }
+
+        fclose(pluginCfgFile);
+    }while (FindNextFileW(fileFirst, &find_data));
+    FindClose(fileFirst);
+}
+
+bool MFX::MFXPluginsInFS::ParseFile(FILE * f, PluginDescriptionRecord & descriptionRecord) 
+{
+    msdk_disp_char line[MAX_PLUGIN_FILE_LINE];
+    
+    while(NULL != fgetws(line, sizeof(line) / sizeof(*line), f))
+    {
+        msdk_disp_char *delimiter = wcschr(line, L'=');
+        if (0 == delimiter) 
+        {
+            TRACE_HIVE_INFO("plugin.cfg contains line \"%S\" which is not in K=V format, skipping \n", line);
+            continue;
+        }
+        *delimiter = 0;
+        if (!ParseKVPair(line, delimiter + 1, descriptionRecord)) 
+        {
+            return false;
+        }
+    }
+
+    if (!mIsVersionParsed) 
+    {
+        TRACE_HIVE_ERROR("%S : Mandatory  key %S not found\n", pluginCfgFileName, PlgVerKeyName);
+        return false;
+    }
+
+    if (!mIsAPIVersionParsed)
+    {
+        TRACE_HIVE_ERROR("%S : Mandatory  key %S not found\n", pluginCfgFileName, APIVerKeyName);
+        return false;
+    }
+
+    if (!wcslen(descriptionRecord.sPath)) 
+    {
+        TRACE_HIVE_ERROR("%S : Mandatory  key %S not found\n", pluginCfgFileName, pluginFileName);
+        return false;
+    }
+
+    return true;
+}
+
+bool MFX::MFXPluginsInFS::ParseKVPair( msdk_disp_char * key, msdk_disp_char* value, PluginDescriptionRecord & descriptionRecord)
+{
+    if (0 != wcsstr(key, PlgVerKeyName))
+    {
+        mfxU32 version ;
+        if (0 == swscanf_s(value, L"%d", &version)) 
+        {
+            return false;
+        }
+        descriptionRecord.PluginVersion = (mfxU16)version;
+        
+        if (0 == descriptionRecord.PluginVersion) 
+        {
+            TRACE_HIVE_ERROR("%S: %S = %d,  which is invalid\n", pluginCfgFileName, PlgVerKeyName, descriptionRecord.PluginVersion);
+            return false;
+        }
+
+        TRACE_HIVE_INFO("%S: %S = %d \n", pluginCfgFileName, PlgVerKeyName, descriptionRecord.PluginVersion);
+        mIsVersionParsed = true;
+        return true;
+    }
+
+    if (0 != wcsstr(key, APIVerKeyName))
+    {
+        mfxU32 APIversion;
+        if (0 == swscanf_s(value, L"%d", &APIversion)) 
+        {
+            return false;
+        }
+
+        ConvertAPIVersion(APIversion, descriptionRecord);
+        TRACE_HIVE_INFO("%S: %S = %d.%d \n", pluginCfgFileName, APIVerKeyName, descriptionRecord.APIVersion.Major, descriptionRecord.APIVersion.Minor);
+
+        mIsAPIVersionParsed = true;
+        return true;
+    }
+
+
+    if (0!=wcsstr(key, pluginFileName))
+    {
+        msdk_disp_char *startQuoteMark = wcschr(value, L'\"');
+        if (!startQuoteMark)
+        {
+            TRACE_HIVE_ERROR("plugin filename not in quotes : %S\n", value);
+            return false;
+        }
+        msdk_disp_char *endQuoteMark = wcschr(startQuoteMark + 1, L'\"');
+
+        if (!endQuoteMark) 
+        {
+            TRACE_HIVE_ERROR("plugin filename not in quotes : %S\n", value);
+            return false;
+        }
+        *endQuoteMark = 0;
+
+        mfxU32 currentPathLen = (mfxU32)wcslen(descriptionRecord.sPath);
+        if (currentPathLen + wcslen(startQuoteMark + 1) > sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath))
+        {
+            TRACE_HIVE_ERROR("buffer of MAX_PLUGIN_PATH characters which is %d, not enough lo store plugin path: %S%S\n"
+                , MAX_PLUGIN_PATH, descriptionRecord.sPath, startQuoteMark + 1);
+            return false;
+        }
+
+        size_t restrictedCharIdx = wcscspn(startQuoteMark + 1, pluginFileNameRestrictedCharacters);
+        if (restrictedCharIdx != wcslen(startQuoteMark + 1)) 
+        {
+            TRACE_HIVE_ERROR("plugin filename :%S, contains one of restricted characters: %S\n", startQuoteMark + 1, pluginFileNameRestrictedCharacters);
+            return false;
+        }
+
+        msdk_disp_char_cpy_s(descriptionRecord.sPath + currentPathLen
+            , sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath) - currentPathLen, startQuoteMark + 1);
+
+        TRACE_HIVE_INFO("%S: %S = \"%S\" \n", pluginCfgFileName, pluginFileName, startQuoteMark + 1);
+     
+        return true;
+    }
+   
+
+    return true;
+}
+
+MFX::MFXDefaultPlugins::MFXDefaultPlugins(mfxVersion currentAPIVersion, MFX_DISP_HANDLE * hdl, int implType)
+    : MFXPluginStorageBase(currentAPIVersion)
+{
+    msdk_disp_char libModuleName[MAX_PLUGIN_PATH];
+
+    GetModuleFileNameW((HMODULE)hdl->hModule, libModuleName, MAX_PLUGIN_PATH);
+    if (GetLastError() != 0) 
+    {
+        TRACE_HIVE_ERROR("GetModuleFileName() reported an error: %d\n", GetLastError());
+        return;
+    }
+    msdk_disp_char *lastSlashPos = wcsrchr(libModuleName, L'\\');
+    if (!lastSlashPos) {
+        lastSlashPos = libModuleName;
+    }
+    mfxU32 executableDirLen = (mfxU32)(lastSlashPos - libModuleName) + slashLen;
+    if (executableDirLen + defaultPluginNameLen >= MAX_PLUGIN_PATH) 
+    {
+        TRACE_HIVE_ERROR("MAX_PLUGIN_PATH which is %d, not enough to locate default plugin path\n", MAX_PLUGIN_PATH);
+        return;
+    }
+
+    mfx_get_default_plugin_name(lastSlashPos + slashLen, MAX_PLUGIN_PATH - executableDirLen, (eMfxImplType)implType);
+
+    if (-1 != GetFileAttributesW(libModuleName))
+    {
+        // add single default plugin description
+        PluginDescriptionRecord descriptionRecord;
+        descriptionRecord.APIVersion = currentAPIVersion;
+        descriptionRecord.Default = true;
+
+        msdk_disp_char_cpy_s(descriptionRecord.sPath
+            , sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath), libModuleName);
+
+        push_back(descriptionRecord);
+    }
+    else
+    {
+        TRACE_HIVE_INFO("GetFileAttributesW() unable to locate default plugin dll named %S\n", libModuleName);
+    }
+}
+
+
+#endif

+ 228 - 0
plugins/obs-qsv11/libmfx/src/mfx_win_reg_key.cpp

@@ -0,0 +1,228 @@
+/* ****************************************************************************** *\
+
+Copyright (C) 2012-2014 Intel Corporation.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither the name of Intel Corporation nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+File Name: mfx_win_reg_key.cpp
+
+\* ****************************************************************************** */
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#include "mfx_win_reg_key.h"
+#include "mfx_dispatcher_log.h"
+
+#define TRACE_WINREG_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[WINREG]: "str), __VA_ARGS__))
+
+namespace MFX
+{
+
+WinRegKey::WinRegKey(void)
+{
+    m_hKey = (HKEY) 0;
+
+} // WinRegKey::WinRegKey(void)
+
+WinRegKey::~WinRegKey(void)
+{
+    Release();
+
+} // WinRegKey::~WinRegKey(void)
+
+void WinRegKey::Release(void)
+{
+    // close the opened key
+    if (m_hKey)
+    {
+        RegCloseKey(m_hKey);
+    }
+
+    m_hKey = (HKEY) 0;
+
+} // void WinRegKey::Release(void)
+
+bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired)
+{
+    LONG lRes;
+    HKEY hTemp;
+
+    //
+    // All operation are performed in this order by intention.
+    // It makes possible to reopen the keys, using itself as a base.
+    //
+
+    // try to the open registry key
+    lRes = RegOpenKeyExW(hRootKey, pSubKey, 0, samDesired, &hTemp);
+    if (ERROR_SUCCESS != lRes)
+    {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("Opening key \"%s\\%S\" : RegOpenKeyExW()==0x%x\n"
+            , (HKEY_LOCAL_MACHINE == hRootKey) ? ("HKEY_LOCAL_MACHINE") 
+            : (HKEY_CURRENT_USER == hRootKey)  ? ("HKEY_CURRENT_USER") 
+            : "UNSUPPORTED_KEY", pSubKey, GetLastError());
+        return false;
+    }
+
+    // release the object before initialization
+    Release();
+
+    // save the handle
+    m_hKey = hTemp;
+
+    return true;
+
+} // bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired)
+
+bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired)
+{
+    return Open(rootKey.m_hKey, pSubKey, samDesired);
+
+} // bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired)
+
+bool WinRegKey::QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData) {
+    DWORD keyType = type;
+    LONG lRes;
+
+    // query the value
+    lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, 0, pcbData);
+    if (ERROR_SUCCESS != lRes)
+    {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n", pValueName, GetLastError());
+        return false;
+    }
+
+    return true;
+}
+
+bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData)
+{
+    DWORD keyType = type;
+    LONG lRes;
+    DWORD dstSize = (pcbData) ? (*pcbData) : (0);
+
+    // query the value
+    lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, pData, pcbData);
+    if (ERROR_SUCCESS != lRes)
+    {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n", pValueName, GetLastError());
+        return false;
+    }
+
+    // check the type
+    if (keyType != type)
+    {
+        TRACE_WINREG_ERROR("Querying \"%S\" : expectedType=%d, returned=%d\n", pValueName, type, keyType);
+        return false;
+    }
+
+    // terminate the string only if pointers not NULL
+    if ((REG_SZ == type || REG_EXPAND_SZ == type) && NULL != pData && NULL != pcbData)
+    {
+        wchar_t *pString = (wchar_t *) pData;
+        size_t NullEndingSizeBytes = sizeof(wchar_t); // size of string termination null character
+        if (dstSize < NullEndingSizeBytes)
+        {
+            TRACE_WINREG_ERROR("Querying \"%S\" : buffer is too small for null-terminated string", pValueName);
+            return false;
+        }
+        size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes;
+        size_t maxStringIndex = dstSize / sizeof(wchar_t) - 1;
+
+        size_t lastIndex = (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t);
+
+        pString[lastIndex] = (wchar_t) 0;
+    }
+    else if(REG_MULTI_SZ == type && NULL != pData && NULL != pcbData)
+    {
+        wchar_t *pString = (wchar_t *) pData;
+        size_t NullEndingSizeBytes = sizeof(wchar_t)*2; // size of string termination null characters
+        if (dstSize < NullEndingSizeBytes)
+        {
+            TRACE_WINREG_ERROR("Querying \"%S\" : buffer is too small for multi-line null-terminated string", pValueName);
+            return false;
+        }
+        size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes;
+        size_t maxStringIndex = dstSize / sizeof(wchar_t) - 1;
+
+        size_t lastIndex = (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t) + 1;
+
+        // last 2 bytes should be 0 in case of REG_MULTI_SZ
+        pString[lastIndex] = pString[lastIndex - 1] = (wchar_t) 0;
+    }
+
+    return true;
+
+} // bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData)
+
+bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType)
+{
+    LONG lRes;
+
+    // enum the values
+    lRes = RegEnumValueW(m_hKey, index, pValueName, pcchValueName, 0, pType, NULL, NULL);
+    if (ERROR_SUCCESS != lRes)
+    {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        return false;
+    }
+
+    return true;
+
+} // bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType)
+
+bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName)
+{
+    LONG lRes;
+
+    // enum the keys
+    lRes = RegEnumKeyExW(m_hKey, index, pValueName, pcchValueName, NULL, NULL, NULL, NULL);
+    if (ERROR_SUCCESS != lRes)
+    {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("EnumKey with index=%d: RegEnumKeyExW()==0x%x\n", index, GetLastError());
+        return false;
+    }
+
+    return true;
+
+} // bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName)
+
+bool WinRegKey::QueryInfo(LPDWORD lpcSubkeys)
+{
+    LONG lRes;
+
+    lRes = RegQueryInfoKeyW(m_hKey, NULL, 0, 0, lpcSubkeys, 0, 0, 0, 0, 0, 0, 0);
+    if (ERROR_SUCCESS != lRes) {
+        TRACE_WINREG_ERROR("RegQueryInfoKeyW()==0x%x\n", lRes);
+        return false;
+    }
+    return true;
+
+} //bool QueryInfo(LPDWORD lpcSubkeys);
+
+} // namespace MFX
+
+#endif // #if defined(_WIN32) || defined(_WIN64)

+ 86 - 0
plugins/obs-qsv11/obs-qsv11-plugin-main.c

@@ -0,0 +1,86 @@
+/*
+
+This file is provided under a dual BSD/GPLv2 license.  When using or
+redistributing this file, you may do so under either license.
+
+GPL LICENSE SUMMARY
+
+Copyright(c) Oct. 2015 Intel Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+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.
+
+Contact Information:
+
+Seung-Woo Kim, [email protected]
+705 5th Ave S #500, Seattle, WA 98104
+
+BSD LICENSE
+
+Copyright(c) <date> Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Intel Corporation nor the names of its
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <obs-module.h>
+#include "mfxsession.h"
+
+OBS_DECLARE_MODULE()
+OBS_MODULE_USE_DEFAULT_LOCALE("obs-qsv11", "en-US")
+
+extern struct obs_encoder_info obs_qsv_encoder;
+
+bool obs_module_load(void)
+{
+	mfxIMPL impl = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D11;
+	mfxVersion ver = {{0 , 1}};
+	mfxSession session;
+	mfxStatus sts;
+
+	sts = MFXInit(impl, &ver, &session);
+
+	if (sts == MFX_ERR_NONE) {
+		obs_register_encoder(&obs_qsv_encoder);
+		MFXClose(session);
+	} else {
+		impl = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D9;
+		sts = MFXInit(impl, &ver, &session);
+		if (sts == MFX_ERR_NONE) {
+			obs_register_encoder(&obs_qsv_encoder);
+			MFXClose(session);
+		}
+	}
+
+	return true;
+}

+ 687 - 0
plugins/obs-qsv11/obs-qsv11.c

@@ -0,0 +1,687 @@
+/*
+
+This file is provided under a dual BSD/GPLv2 license.  When using or
+redistributing this file, you may do so under either license.
+
+GPL LICENSE SUMMARY
+
+Copyright(c) Oct. 2015 Intel Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+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.
+
+Contact Information:
+
+Seung-Woo Kim, [email protected]
+705 5th Ave S #500, Seattle, WA 98104
+
+BSD LICENSE
+
+Copyright(c) <date> Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Intel Corporation nor the names of its
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <util/dstr.h>
+#include <util/darray.h>
+#include <util/platform.h>
+#include <obs-module.h>
+
+#ifndef _STDINT_H_INCLUDED
+#define _STDINT_H_INCLUDED
+#endif
+
+#include "QSV_Encoder.h"
+#include <Windows.h>
+
+#define do_log(level, format, ...) \
+	blog(level, "[qsv encoder: '%s'] " format, \
+			obs_encoder_get_name(obsqsv->encoder), ##__VA_ARGS__)
+
+#define warn(format, ...)  do_log(LOG_WARNING, format, ##__VA_ARGS__)
+#define info(format, ...)  do_log(LOG_INFO,    format, ##__VA_ARGS__)
+#define debug(format, ...) do_log(LOG_DEBUG,   format, ##__VA_ARGS__)
+
+/* ------------------------------------------------------------------------- */
+
+struct obs_qsv {
+	obs_encoder_t          *encoder;
+
+	qsv_param_t            params;
+	qsv_t                  *context;
+
+	DARRAY(uint8_t)        packet_data;
+
+	uint8_t                *extra_data;
+	uint8_t                *sei;
+
+	size_t                 extra_data_size;
+	size_t                 sei_size;
+
+	os_performance_token_t *performance_token;
+};
+
+/* ------------------------------------------------------------------------- */
+
+static CRITICAL_SECTION g_QsvCs;
+static unsigned short   g_verMajor;
+static unsigned short   g_verMinor;
+static int64_t          g_pts2dtsShift;
+static int64_t          g_prevDts;
+static bool             g_bFirst;
+
+static const char *obs_qsv_getname(void *type_data)
+{
+	UNUSED_PARAMETER(type_data);
+	return "qsv11";
+}
+
+static void obs_qsv_stop(void *data);
+
+static void clear_data(struct obs_qsv *obsqsv)
+{
+	if (obsqsv->context) {
+		qsv_encoder_close(obsqsv->context);
+		// bfree(obsqsv->sei);
+		bfree(obsqsv->extra_data);
+
+		obsqsv->context = NULL;
+		// obsqsv->sei = NULL;
+		obsqsv->extra_data = NULL;
+	}
+}
+
+static void obs_qsv_destroy(void *data)
+{
+	struct obs_qsv *obsqsv = (struct obs_qsv *)data;
+
+	if (obsqsv) {
+		os_end_high_performance(obsqsv->performance_token);
+		clear_data(obsqsv);
+		da_free(obsqsv->packet_data);
+		bfree(obsqsv);
+	}
+}
+
+static void obs_qsv_defaults(obs_data_t *settings)
+{
+	obs_data_set_default_string(settings, "target_usage", "balanced");
+	obs_data_set_default_int(settings, "bitrate", 2500);
+	obs_data_set_default_int(settings, "max_bitrate", 3000);
+	obs_data_set_default_string(settings, "profile", "main");
+	obs_data_set_default_int(settings, "async_depth", 4);
+	obs_data_set_default_string(settings, "rate_control", "CBR");
+
+	obs_data_set_default_int(settings, "accuracy", 1000);
+	obs_data_set_default_int(settings, "convergence", 1);
+	obs_data_set_default_int(settings, "qpi", 23);
+	obs_data_set_default_int(settings, "qpp", 23);
+	obs_data_set_default_int(settings, "qpb", 23);
+	obs_data_set_default_int(settings, "icq_quality", 23);
+	obs_data_set_default_int(settings, "la_depth", 40);
+
+	obs_data_set_default_int(settings, "keyint_sec", 3);
+}
+
+static inline void add_strings(obs_property_t *list, const char *const *strings)
+{
+	while (*strings) {
+		obs_property_list_add_string(list, *strings, *strings);
+		strings++;
+	}
+}
+
+#define TEXT_SPEED              obs_module_text("TargetUsage")
+#define TEXT_TARGET_BITRATE     obs_module_text("Bitrate")
+#define TEXT_MAX_BITRATE        obs_module_text("MaxBitrate")
+#define TEXT_PROFILE            obs_module_text("Profile")
+#define TEXT_ASYNC_DEPTH        obs_module_text("AsyncDepth")
+#define TEXT_RATE_CONTROL       obs_module_text("RateControl")
+#define TEXT_ACCURACY           obs_module_text("Accuracy")
+#define TEXT_CONVERGENCE        obs_module_text("Convergence")
+#define TEXT_ICQ_QUALITY        obs_module_text("ICQQuality")
+#define TEXT_LA_DEPTH           obs_module_text("LookAheadDepth")
+#define TEXT_KEYINT_SEC         obs_module_text("KeyframeIntervalSec")
+
+static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
+	obs_data_t *settings)
+{
+	const char *rate_control = obs_data_get_string(settings, "rate_control");
+
+	bool bVisible =
+		astrcmpi(rate_control, "VCM") == 0 ||
+		astrcmpi(rate_control, "VBR") == 0;
+	p = obs_properties_get(ppts, "max_bitrate");
+	obs_property_set_visible(p, bVisible);
+
+	bVisible =
+		astrcmpi(rate_control, "CQP") == 0 ||
+		astrcmpi(rate_control, "LA_ICQ") == 0 ||
+		astrcmpi(rate_control, "ICQ") == 0;
+	p = obs_properties_get(ppts, "bitrate");
+	obs_property_set_visible(p, !bVisible);
+
+	bVisible = astrcmpi(rate_control, "AVBR") == 0;
+	p = obs_properties_get(ppts, "accuracy");
+	obs_property_set_visible(p, bVisible);
+	p = obs_properties_get(ppts, "convergence");
+	obs_property_set_visible(p, bVisible);
+
+	bVisible = astrcmpi(rate_control, "CQP") == 0;
+	p = obs_properties_get(ppts, "qpi");
+	obs_property_set_visible(p, bVisible);
+	p = obs_properties_get(ppts, "qpb");
+	obs_property_set_visible(p, bVisible);
+	p = obs_properties_get(ppts, "qpp");
+	obs_property_set_visible(p, bVisible);
+
+	bVisible = astrcmpi(rate_control, "ICQ") == 0 ||
+		astrcmpi(rate_control, "LA_ICQ") == 0;
+	p = obs_properties_get(ppts, "icq_quality");
+	obs_property_set_visible(p, bVisible);
+
+	bVisible = astrcmpi(rate_control, "LA_ICQ") == 0 ||
+		astrcmpi(rate_control, "LA") == 0;
+	p = obs_properties_get(ppts, "la_depth");
+	obs_property_set_visible(p, bVisible);
+
+	return true;
+}
+
+static inline void add_rate_controls(obs_property_t *list,
+		const struct qsv_rate_control_info *rc)
+{
+	enum qsv_cpu_platform plat = qsv_get_cpu_platform();
+	while (rc->name) {
+		if (!rc->haswell_or_greater || plat >= QSV_CPU_PLATFORM_HSW)
+			obs_property_list_add_string(list, rc->name, rc->name);
+		rc++;
+	}
+}
+
+static obs_properties_t *obs_qsv_props(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+
+	obs_properties_t *props = obs_properties_create();
+	obs_property_t *list;
+
+	list = obs_properties_add_list(props, "target_usage", TEXT_SPEED,
+		OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+	add_strings(list, qsv_usage_names);
+
+	list = obs_properties_add_list(props, "profile", TEXT_PROFILE,
+		OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+	add_strings(list, qsv_profile_names);
+
+	obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 1, 20, 1);
+	obs_properties_add_int(props, "async_depth", TEXT_ASYNC_DEPTH, 1, 7, 1);
+
+	list = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL,
+		OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+	add_rate_controls(list, qsv_ratecontrols);
+	obs_property_set_modified_callback(list, rate_control_modified);
+
+	obs_properties_add_int(props, "bitrate", TEXT_TARGET_BITRATE, 50,
+			10000000, 1);
+	obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50,
+			10000000, 1);
+	obs_properties_add_int(props, "accuracy", TEXT_ACCURACY, 0, 10000, 1);
+	obs_properties_add_int(props, "convergence", TEXT_CONVERGENCE, 0, 10, 1);
+	obs_properties_add_int(props, "qpi", "QPI", 1, 51, 1);
+	obs_properties_add_int(props, "qpp", "QPP", 1, 51, 1);
+	obs_properties_add_int(props, "qpb", "QPB", 1, 51, 1);
+	obs_properties_add_int(props, "icq_quality", TEXT_ICQ_QUALITY, 1, 51, 1);
+	obs_properties_add_int(props, "la_depth", TEXT_LA_DEPTH, 10, 100, 1);
+
+	return props;
+}
+
+static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings)
+{
+	video_t *video = obs_encoder_video(obsqsv->encoder);
+	const struct video_output_info *voi = video_output_get_info(video);
+
+	const char *target_usage = obs_data_get_string(settings, "target_usage");
+	const char *profile = obs_data_get_string(settings, "profile");
+	const char *rate_control = obs_data_get_string(settings, "rate_control");
+	int async_depth = (int)obs_data_get_int(settings, "async_depth");
+	int target_bitrate = (int)obs_data_get_int(settings, "bitrate");
+	int max_bitrate = (int)obs_data_get_int(settings, "max_bitrate");
+	int accuracy = (int)obs_data_get_int(settings, "accuracy");
+	int convergence = (int)obs_data_get_int(settings, "convergence");
+	int qpi = (int)obs_data_get_int(settings, "qpi");
+	int qpp = (int)obs_data_get_int(settings, "qpp");
+	int qpb = (int)obs_data_get_int(settings, "qpb");
+	int icq_quality = (int)obs_data_get_int(settings, "icq_quality");
+	int la_depth = (int)obs_data_get_int(settings, "la_depth");
+	int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
+	bool cbr_override = obs_data_get_bool(settings, "cbr");
+	int bFrames = 7;
+
+	int width = (int)obs_encoder_get_width(obsqsv->encoder);
+	int height = (int)obs_encoder_get_height(obsqsv->encoder);
+	if (astrcmpi(target_usage, "quality") == 0)
+		obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BEST_QUALITY;
+	else if (astrcmpi(target_usage, "balanced") == 0)
+		obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BALANCED;
+	else if (astrcmpi(target_usage, "speed") == 0)
+		obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BEST_SPEED;
+
+	if (astrcmpi(profile, "baseline") == 0)
+		obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_BASELINE;
+	else if (astrcmpi(profile, "main") == 0)
+		obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_MAIN;
+	else if (astrcmpi(profile, "high") == 0)
+		obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_HIGH;
+
+	/* internal convenience parameter, overrides rate control param */
+	if (cbr_override)
+		rate_control = "CBR";
+
+	if (astrcmpi(rate_control, "CBR") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_CBR;
+	else if (astrcmpi(rate_control, "VBR") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_VBR;
+	else if (astrcmpi(rate_control, "VCM") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_VCM;
+	else if (astrcmpi(rate_control, "CQP") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_CQP;
+	else if (astrcmpi(rate_control, "AVBR") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_AVBR;
+	else if (astrcmpi(rate_control, "ICQ") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_ICQ;
+	else if (astrcmpi(rate_control, "LA_ICQ") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_LA_ICQ;
+	else if (astrcmpi(rate_control, "LA") == 0)
+		obsqsv->params.nRateControl = MFX_RATECONTROL_LA;
+
+	obsqsv->params.nAsyncDepth = (mfxU16)async_depth;
+	obsqsv->params.nAccuracy = (mfxU16)accuracy;
+	obsqsv->params.nConvergence = (mfxU16)convergence;
+	obsqsv->params.nQPI = (mfxU16)qpi;
+	obsqsv->params.nQPP = (mfxU16)qpp;
+	obsqsv->params.nQPB = (mfxU16)qpb;
+	obsqsv->params.nLADEPTH = (mfxU16)la_depth;
+	obsqsv->params.nTargetBitRate = (mfxU16)target_bitrate;
+	obsqsv->params.nMaxBitRate = (mfxU16)max_bitrate;
+	obsqsv->params.nWidth = (mfxU16)width;
+	obsqsv->params.nHeight = (mfxU16)height;
+	obsqsv->params.nFpsNum = (mfxU16)voi->fps_num;
+	obsqsv->params.nFpsDen = (mfxU16)voi->fps_den;
+	obsqsv->params.nbFrames = (mfxU16)bFrames;
+	obsqsv->params.nKeyIntSec = (mfxU16)keyint_sec;
+	obsqsv->params.nICQQuality = (mfxU16)icq_quality;
+
+	info("settings:\n\trate_control:   %s", rate_control);
+
+	if (obsqsv->params.nRateControl != MFX_RATECONTROL_LA_ICQ &&
+	    obsqsv->params.nRateControl != MFX_RATECONTROL_ICQ    &&
+	    obsqsv->params.nRateControl != MFX_RATECONTROL_CQP)
+		blog(LOG_INFO,
+			"\ttarget_bitrate: %d",
+			(int)obsqsv->params.nTargetBitRate);
+
+	if (obsqsv->params.nRateControl == MFX_RATECONTROL_VBR ||
+	    obsqsv->params.nRateControl == MFX_RATECONTROL_VCM)
+		blog(LOG_INFO,
+			"\tmax_bitrate:    %d",
+			(int)obsqsv->params.nMaxBitRate);
+
+	if (obsqsv->params.nRateControl == MFX_RATECONTROL_LA_ICQ ||
+	    obsqsv->params.nRateControl == MFX_RATECONTROL_ICQ)
+		blog(LOG_INFO,
+			"\tICQ Quality:    %d",
+			(int)obsqsv->params.nICQQuality);
+
+	if (obsqsv->params.nRateControl == MFX_RATECONTROL_LA_ICQ ||
+	    obsqsv->params.nRateControl == MFX_RATECONTROL_LA)
+		blog(LOG_INFO,
+			"\tLookahead Depth:%d",
+			(int)obsqsv->params.nLADEPTH);
+
+	if (obsqsv->params.nRateControl == MFX_RATECONTROL_CQP)
+		blog(LOG_INFO,
+			"\tqpi:            %d\n"
+			"\tqpb:            %d\n"
+			"\tqpp:            %d",
+			qpi, qpb, qpp);
+
+	blog(LOG_INFO,
+		"\tfps_num:        %d\n"
+		"\tfps_den:        %d\n"
+		"\twidth:          %d\n"
+		"\theight:         %d",
+		voi->fps_num, voi->fps_den,
+		width, height);
+
+	info("debug info:");
+}
+
+static bool update_settings(struct obs_qsv *obsqsv, obs_data_t *settings)
+{
+	update_params(obsqsv, settings);
+	return true;
+}
+
+static void load_headers(struct obs_qsv *obsqsv)
+{
+	DARRAY(uint8_t) header;
+	uint8_t sei = 0;
+
+	// Not sure if SEI is needed.
+	// Just filling in empty meaningless SEI message.
+	// Seems to work fine.
+	// DARRAY(uint8_t) sei;
+
+	da_init(header);
+	// da_init(sei);
+
+	uint8_t *pSPS, *pPPS;
+	uint16_t nSPS, nPPS;
+	qsv_encoder_headers(obsqsv->context, &pSPS, &pPPS, &nSPS, &nPPS);
+	da_push_back_array(header, pSPS, nSPS);
+	da_push_back_array(header, pPPS, nPPS);
+
+	obsqsv->extra_data = header.array;
+	obsqsv->extra_data_size = header.num;
+	obsqsv->sei = &sei;
+	obsqsv->sei_size = 1;
+}
+
+static bool obs_qsv_update(void *data, obs_data_t *settings)
+{
+	struct obs_qsv *obsqsv = data;
+	bool success = update_settings(obsqsv, settings);
+	int ret;
+
+
+	if (success) {
+		EnterCriticalSection(&g_QsvCs);
+
+		ret = qsv_encoder_reconfig(obsqsv->context, &obsqsv->params);
+		if (ret != 0)
+			warn("Failed to reconfigure: %d", ret);
+
+		LeaveCriticalSection(&g_QsvCs);
+
+		return ret == 0;
+	}
+
+	return false;
+}
+
+static void *obs_qsv_create(obs_data_t *settings, obs_encoder_t *encoder)
+{
+	InitializeCriticalSection(&g_QsvCs);
+
+	struct obs_qsv *obsqsv = bzalloc(sizeof(struct obs_qsv));
+	obsqsv->encoder = encoder;
+
+	if (update_settings(obsqsv, settings)) {
+		obsqsv->context = qsv_encoder_open(&obsqsv->params);
+
+		if (obsqsv->context == NULL)
+			warn("qsv failed to load");
+		else
+			load_headers(obsqsv);
+	} else {
+		warn("bad settings specified");
+	}
+
+	qsv_encoder_version(&g_verMajor, &g_verMinor);
+
+	blog(LOG_INFO, "\tmajor:          %d\n"
+	               "\tminor:          %d",
+	               g_verMajor, g_verMinor);
+
+	// MSDK 1.6 or less doesn't have automatic DTS calculation
+	// including early SandyBridge.
+	// Need to add manual DTS from PTS.
+	if (g_verMajor == 1 && g_verMinor < 7) {
+		int64_t interval = obsqsv->params.nbFrames + 1;
+		int64_t GopPicSize = (int64_t)(obsqsv->params.nKeyIntSec *
+				obsqsv->params.nFpsNum /
+				(float)obsqsv->params.nFpsDen);
+		g_pts2dtsShift = GopPicSize - (GopPicSize / interval) *
+			interval;
+
+		blog(LOG_INFO, "\tinterval:       %d\n"
+		               "\tGopPictSize:    %d\n"
+		               "\tg_pts2dtsShift: %d",
+		               interval, GopPicSize, g_pts2dtsShift);
+	}
+	else
+		g_pts2dtsShift = -1;
+
+	if (!obsqsv->context) {
+		bfree(obsqsv);
+		return NULL;
+	}
+
+	obsqsv->performance_token =
+		os_request_high_performance("qsv encoding");
+
+	g_bFirst = true;
+
+	return obsqsv;
+}
+
+static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size)
+{
+	struct obs_qsv *obsqsv = data;
+
+	if (!obsqsv->context)
+		return false;
+
+	*extra_data = obsqsv->extra_data;
+	*size = obsqsv->extra_data_size;
+	return true;
+}
+
+static bool obs_qsv_sei(void *data, uint8_t **sei,size_t *size)
+{
+	struct obs_qsv *obsqsv = data;
+
+	if (!obsqsv->context)
+		return false;
+
+	/* (Jim) Unused */
+	UNUSED_PARAMETER(sei);
+	UNUSED_PARAMETER(size);
+
+	*sei = obsqsv->sei;
+	*size = obsqsv->sei_size;
+	return true;
+}
+
+static inline bool valid_format(enum video_format format)
+{
+	return format == VIDEO_FORMAT_NV12;
+}
+
+static inline void cap_resolution(struct video_scale_info *info,
+		const struct video_output_info *vid_info)
+{
+	enum qsv_cpu_platform qsv_platform = qsv_get_cpu_platform();
+
+	info->height = vid_info->height;
+	info->width = vid_info->width;
+
+	if (qsv_platform <= QSV_CPU_PLATFORM_IVB) {
+		if (vid_info->width > 1920) {
+			info->width = 1920;
+		}
+
+		if (vid_info->height > 1200) {
+			info->height = 1200;
+		}
+	}
+}
+
+static void obs_qsv_video_info(void *data, struct video_scale_info *info)
+{
+	struct obs_qsv *obsqsv = data;
+	video_t *video = obs_encoder_video(obsqsv->encoder);
+	const struct video_output_info *vid_info = video_output_get_info(video);
+	enum video_format pref_format;
+
+	pref_format = obs_encoder_get_preferred_video_format(obsqsv->encoder);
+
+	if (!valid_format(pref_format)) {
+		pref_format = valid_format(info->format) ?
+			info->format : VIDEO_FORMAT_NV12;
+	}
+
+	info->format = pref_format;
+	cap_resolution(info, vid_info);
+}
+
+static void parse_packet(struct obs_qsv *obsqsv, struct encoder_packet *packet, mfxBitstream *pBS, uint32_t fps_num, bool *received_packet)
+{
+	if (pBS == NULL || pBS->DataLength == 0) {
+		*received_packet = false;
+		return;
+	}
+
+	da_resize(obsqsv->packet_data, 0);
+	da_push_back_array(obsqsv->packet_data, &pBS->Data[pBS->DataOffset],
+			pBS->DataLength);
+
+	packet->data = obsqsv->packet_data.array;
+	packet->size = obsqsv->packet_data.num;
+	packet->type = OBS_ENCODER_VIDEO;
+	packet->pts = pBS->TimeStamp * fps_num / 90000;
+	packet->keyframe = (pBS->FrameType &
+			(MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF));
+
+	//bool iFrame = pBS->FrameType & MFX_FRAMETYPE_I;
+	//bool bFrame = pBS->FrameType & MFX_FRAMETYPE_B;
+	bool pFrame = pBS->FrameType & MFX_FRAMETYPE_P;
+	//int iType = iFrame ? 0 : (bFrame ? 1 : (pFrame ? 2 : -1));
+	//int64_t interval = obsqsv->params.nbFrames + 1;
+
+	// In case MSDK does't support automatic DecodeTimeStamp, do manual
+	// calculation
+	if (g_pts2dtsShift >= 0)
+	{
+		if (g_bFirst) {
+			packet->dts = packet->pts - 3 * obsqsv->params.nFpsDen;
+		} else if (pFrame) {
+			packet->dts = packet->pts - 10 * obsqsv->params.nFpsDen;
+			g_prevDts = packet->dts;
+		} else {
+			packet->dts = g_prevDts + obsqsv->params.nFpsDen;
+			g_prevDts = packet->dts;
+		}
+	} else {
+		packet->dts = pBS->DecodeTimeStamp * fps_num / 90000;
+	}
+
+#if 0
+	info("parse packet:\n"
+		"\tFrameType: %d\n"
+		"\tpts:       %d\n"
+		"\tdts:       %d",
+		iType, packet->pts, packet->dts);
+#endif
+
+	*received_packet = true;
+	pBS->DataLength = 0;
+
+	g_bFirst = false;
+}
+
+static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
+		struct encoder_packet *packet, bool *received_packet)
+{
+	struct obs_qsv *obsqsv = data;
+
+	if (!frame || !packet || !received_packet)
+		return false;
+
+	EnterCriticalSection(&g_QsvCs);
+
+
+	video_t *video = obs_encoder_video(obsqsv->encoder);
+	const struct video_output_info *voi = video_output_get_info(video);
+
+	mfxBitstream *pBS = NULL;
+
+	int ret;
+
+	mfxU64 qsvPTS = frame->pts * 90000 / voi->fps_num;
+
+	if (frame)
+		ret = qsv_encoder_encode(
+			obsqsv->context,
+			qsvPTS,
+			frame->data[0], frame->data[1], frame->linesize[0],
+			frame->linesize[1],
+			&pBS);
+	else
+		ret = qsv_encoder_encode(
+			obsqsv->context,
+			qsvPTS,
+			NULL, NULL, 0, 0, &pBS);
+
+	if (ret < 0) {
+		warn("encode failed");
+		return false;
+	}
+
+	parse_packet(obsqsv, packet, pBS, voi->fps_num, received_packet);
+
+	LeaveCriticalSection(&g_QsvCs);
+
+	return true;
+}
+
+struct obs_encoder_info obs_qsv_encoder = {
+	.id = "obs_qsv11",
+	.type = OBS_ENCODER_VIDEO,
+	.codec = "h264",
+	.get_name = obs_qsv_getname,
+	.create = obs_qsv_create,
+	.destroy = obs_qsv_destroy,
+	.encode = obs_qsv_encode,
+	.update = obs_qsv_update,
+	.get_properties = obs_qsv_props,
+	.get_defaults = obs_qsv_defaults,
+	.get_extra_data = obs_qsv_extra_data,
+	.get_sei_data = obs_qsv_sei,
+	.get_video_info = obs_qsv_video_info
+};