|
@@ -60,8 +60,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#include <util/platform.h>
|
|
#include <util/platform.h>
|
|
#include <obs-module.h>
|
|
#include <obs-module.h>
|
|
#include <obs-avc.h>
|
|
#include <obs-avc.h>
|
|
-#include <d3d11.h>
|
|
|
|
-#include <dxgi1_2.h>
|
|
|
|
|
|
|
|
#ifndef _STDINT_H_INCLUDED
|
|
#ifndef _STDINT_H_INCLUDED
|
|
#define _STDINT_H_INCLUDED
|
|
#define _STDINT_H_INCLUDED
|
|
@@ -584,92 +582,6 @@ static void *obs_qsv_create(obs_data_t *settings, obs_encoder_t *encoder)
|
|
return obsqsv;
|
|
return obsqsv;
|
|
}
|
|
}
|
|
|
|
|
|
-static HANDLE get_lib(const char *lib)
|
|
|
|
-{
|
|
|
|
- HMODULE mod = GetModuleHandleA(lib);
|
|
|
|
- if (mod)
|
|
|
|
- return mod;
|
|
|
|
-
|
|
|
|
- mod = LoadLibraryA(lib);
|
|
|
|
- if (!mod)
|
|
|
|
- blog(LOG_INFO, "Failed to load %s", lib);
|
|
|
|
- return mod;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-typedef HRESULT(WINAPI *CREATEDXGIFACTORY1PROC)(REFIID, void **);
|
|
|
|
-
|
|
|
|
-static bool is_intel_gpu_primary()
|
|
|
|
-{
|
|
|
|
- HMODULE dxgi = get_lib("DXGI.dll");
|
|
|
|
- CREATEDXGIFACTORY1PROC create_dxgi;
|
|
|
|
- IDXGIFactory1 *factory;
|
|
|
|
- IDXGIAdapter *adapter;
|
|
|
|
- DXGI_ADAPTER_DESC desc;
|
|
|
|
- HRESULT hr;
|
|
|
|
-
|
|
|
|
- if (!dxgi) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- create_dxgi = (CREATEDXGIFACTORY1PROC)GetProcAddress(
|
|
|
|
- dxgi, "CreateDXGIFactory1");
|
|
|
|
-
|
|
|
|
- if (!create_dxgi) {
|
|
|
|
- blog(LOG_INFO, "Failed to load D3D11/DXGI procedures");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- hr = create_dxgi(&IID_IDXGIFactory1, &factory);
|
|
|
|
- if (FAILED(hr)) {
|
|
|
|
- blog(LOG_INFO, "CreateDXGIFactory1 failed");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- hr = factory->lpVtbl->EnumAdapters(factory, 0, &adapter);
|
|
|
|
- factory->lpVtbl->Release(factory);
|
|
|
|
- if (FAILED(hr)) {
|
|
|
|
- blog(LOG_INFO, "EnumAdapters failed");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- hr = adapter->lpVtbl->GetDesc(adapter, &desc);
|
|
|
|
- adapter->lpVtbl->Release(adapter);
|
|
|
|
- if (FAILED(hr)) {
|
|
|
|
- blog(LOG_INFO, "GetDesc failed");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*check whether adapter 0 is Intel*/
|
|
|
|
- if (desc.VendorId == 0x8086) {
|
|
|
|
- return true;
|
|
|
|
- } else {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void *obs_qsv_create_tex(obs_data_t *settings, obs_encoder_t *encoder)
|
|
|
|
-{
|
|
|
|
- if (!is_intel_gpu_primary()) {
|
|
|
|
- blog(LOG_INFO,
|
|
|
|
- ">>> app not on intel GPU, fall back to old qsv encoder");
|
|
|
|
- return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!obs_nv12_tex_active()) {
|
|
|
|
- blog(LOG_INFO,
|
|
|
|
- ">>> nv12 tex not active, fall back to old qsv encoder");
|
|
|
|
- return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (obs_encoder_scaling_enabled(encoder)) {
|
|
|
|
- blog(LOG_INFO,
|
|
|
|
- ">>> encoder scaling active, fall back to old qsv encoder");
|
|
|
|
- return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- blog(LOG_INFO, ">>> new qsv encoder");
|
|
|
|
- return obs_qsv_create(settings, encoder);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size)
|
|
static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size)
|
|
{
|
|
{
|
|
struct obs_qsv *obsqsv = data;
|
|
struct obs_qsv *obsqsv = data;
|
|
@@ -880,51 +792,8 @@ static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-static bool obs_qsv_encode_tex(void *data, uint32_t handle, int64_t pts,
|
|
|
|
- uint64_t lock_key, uint64_t *next_key,
|
|
|
|
- struct encoder_packet *packet,
|
|
|
|
- bool *received_packet)
|
|
|
|
-{
|
|
|
|
- struct obs_qsv *obsqsv = data;
|
|
|
|
-
|
|
|
|
- if (handle == GS_INVALID_HANDLE) {
|
|
|
|
- warn("Encode failed: bad texture handle");
|
|
|
|
- *next_key = lock_key;
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!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 = pts * 90000 / voi->fps_num;
|
|
|
|
-
|
|
|
|
- ret = qsv_encoder_encode_tex(obsqsv->context, qsvPTS, handle, lock_key,
|
|
|
|
- next_key, &pBS);
|
|
|
|
-
|
|
|
|
- if (ret < 0) {
|
|
|
|
- warn("encode failed");
|
|
|
|
- LeaveCriticalSection(&g_QsvCs);
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- parse_packet(obsqsv, packet, pBS, voi->fps_num, received_packet);
|
|
|
|
-
|
|
|
|
- LeaveCriticalSection(&g_QsvCs);
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
struct obs_encoder_info obs_qsv_encoder = {
|
|
struct obs_encoder_info obs_qsv_encoder = {
|
|
- .id = "obs_qsv11_soft",
|
|
|
|
|
|
+ .id = "obs_qsv11",
|
|
.type = OBS_ENCODER_VIDEO,
|
|
.type = OBS_ENCODER_VIDEO,
|
|
.codec = "h264",
|
|
.codec = "h264",
|
|
.get_name = obs_qsv_getname,
|
|
.get_name = obs_qsv_getname,
|
|
@@ -937,22 +806,5 @@ struct obs_encoder_info obs_qsv_encoder = {
|
|
.get_extra_data = obs_qsv_extra_data,
|
|
.get_extra_data = obs_qsv_extra_data,
|
|
.get_sei_data = obs_qsv_sei,
|
|
.get_sei_data = obs_qsv_sei,
|
|
.get_video_info = obs_qsv_video_info,
|
|
.get_video_info = obs_qsv_video_info,
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct obs_encoder_info obs_qsv_encoder_tex = {
|
|
|
|
- .id = "obs_qsv11",
|
|
|
|
- .type = OBS_ENCODER_VIDEO,
|
|
|
|
- .codec = "h264",
|
|
|
|
- .get_name = obs_qsv_getname,
|
|
|
|
- .create = obs_qsv_create_tex,
|
|
|
|
- .destroy = obs_qsv_destroy,
|
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE,
|
|
|
|
- .encode_texture = obs_qsv_encode_tex,
|
|
|
|
- .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,
|
|
|
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE,
|
|
};
|
|
};
|