obs-StreamFX/source/nvidia/ar/nvidia-ar.cpp
Michael Fabian 'Xaymar' Dirks 43f1dcf205 filter-nv-face-tracking: Nvidia exclusive Face Tracking filter
Ever wished you had a professional camera operator to highlight and follow the action, ensuring the audience never misses a beat? Thanks to NVIDIA, you can now do this at home for free! The new NVIDIA AR SDK unlocks augmented reality features, including motion tracking for faces.

This allows me to provide you with an automated zoom and cropping solution for your video camera to transform your streams into a slick, polished broadcast, where you’ll always be the star of the show. Don’t forget - everything is customizable so the possibilities are endless. You can even recreate that Futurama squinting meme if you wanted to (with some scripting)!

The filter requires compatible Nvidia RTX hardware and the Nvidia AR SDK Runtime to be installed ahead of time. This filter is considered "stable" and shouldn't change much from version to version.
2020-03-31 21:46:47 +02:00

260 lines
7.8 KiB
C++

/*
* Modern effects for a modern Streamer
* Copyright (C) 2020 Michael Fabian Dirks
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "nvidia-ar.hpp"
#include <stdexcept>
#include <util/bmem.h>
#include <util/platform.h>
#ifdef WIN32
#include <Shlobj.h>
#include <Windows.h>
#endif
#include <nvARProxy.cpp>
nvidia::ar::ar::ar()
{
if (!getNvARLib())
throw std::runtime_error("Failed to load Nvidia AR SDK runtime.");
}
nvidia::ar::ar::~ar() {}
std::filesystem::path nvidia::ar::ar::get_ar_sdk_path()
{
char* arsdk_path = getenv("NV_AR_SDK_PATH");
if (arsdk_path) {
return std::filesystem::path(std::string{arsdk_path});
} else {
std::filesystem::path res;
#ifdef WIN32
std::vector<wchar_t> dll_path_w;
dll_path_w.resize(65535);
DWORD size_w = GetModuleFileNameW(getNvARLib(), dll_path_w.data(), static_cast<DWORD>(dll_path_w.size()));
std::vector<char> dll_path;
dll_path.resize(65535);
std::size_t size = os_wcs_to_utf8(dll_path_w.data(), size_w, dll_path.data(), dll_path.size());
std::filesystem::path dll = std::string{dll_path.data(), dll_path.data() + size};
res = dll.remove_filename();
#endif
return res;
}
}
NvCV_Status nvidia::ar::ar::image_init(NvCVImage* im, unsigned width, unsigned height, int pitch, void* pixels,
NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned isPlanar,
unsigned onGPU)
{
return NvCVImage_Init(im, width, height, pitch, pixels, format, type, isPlanar, onGPU);
}
void nvidia::ar::ar::image_init_view(NvCVImage* subImg, NvCVImage* fullImg, int x, int y, unsigned width,
unsigned height)
{
NvCVImage_InitView(subImg, fullImg, x, y, width, height);
}
NvCV_Status nvidia::ar::ar::image_alloc(NvCVImage* im, unsigned width, unsigned height, NvCVImage_PixelFormat format,
NvCVImage_ComponentType type, unsigned isPlanar, unsigned onGPU,
unsigned alignment)
{
return NvCVImage_Alloc(im, width, height, format, type, isPlanar, onGPU, alignment);
}
NvCV_Status nvidia::ar::ar::image_realloc(NvCVImage* im, unsigned width, unsigned height, NvCVImage_PixelFormat format,
NvCVImage_ComponentType type, unsigned isPlanar, unsigned onGPU,
unsigned alignment)
{
return NvCVImage_Realloc(im, width, height, format, type, isPlanar, onGPU, alignment);
}
void nvidia::ar::ar::image_dealloc(NvCVImage* im)
{
NvCVImage_Dealloc(im);
}
NvCV_Status nvidia::ar::ar::image_create(unsigned width, unsigned height, NvCVImage_PixelFormat format,
NvCVImage_ComponentType type, unsigned isPlanar, unsigned onGPU,
unsigned alignment, NvCVImage** out)
{
return NvCVImage_Create(width, height, format, type, isPlanar, onGPU, alignment, out);
}
void nvidia::ar::ar::image_destroy(NvCVImage* im)
{
NvCVImage_Destroy(im);
}
void nvidia::ar::ar::image_component_offsets(NvCVImage_PixelFormat format, int* rOff, int* gOff, int* bOff, int* aOff,
int* yOff)
{
NvCVImage_ComponentOffsets(format, rOff, gOff, bOff, aOff, yOff);
}
NvCV_Status nvidia::ar::ar::image_transfer(const NvCVImage* src, NvCVImage* dst, float scale, CUstream_st* stream,
NvCVImage* tmp)
{
return NvCVImage_Transfer(src, dst, scale, stream, tmp);
}
NvCV_Status nvidia::ar::ar::image_composite(const NvCVImage* src, const NvCVImage* mat, NvCVImage* dst)
{
return NvCVImage_Composite(src, mat, dst);
}
NvCV_Status nvidia::ar::ar::image_composite_over_constant(const NvCVImage* src, const NvCVImage* mat,
const unsigned char bgColor[3], NvCVImage* dst)
{
return NvCVImage_CompositeOverConstant(src, mat, bgColor, dst);
}
NvCV_Status nvidia::ar::ar::image_flipy(const NvCVImage* src, NvCVImage* dst)
{
return NvCVImage_FlipY(src, dst);
}
NvCV_Status nvidia::ar::ar::create(NvAR_FeatureID featureID, NvAR_FeatureHandle* handle)
{
return NvAR_Create(featureID, handle);
}
NvCV_Status nvidia::ar::ar::destroy(NvAR_FeatureHandle handle)
{
return NvAR_Destroy(handle);
}
NvCV_Status nvidia::ar::ar::set_uint32(NvAR_FeatureHandle handle, const char* name, unsigned int val)
{
return NvAR_SetU32(handle, name, val);
}
NvCV_Status nvidia::ar::ar::set_int32(NvAR_FeatureHandle handle, const char* name, int val)
{
return NvAR_SetS32(handle, name, val);
}
NvCV_Status nvidia::ar::ar::set_float32(NvAR_FeatureHandle handle, const char* name, float val)
{
return NvAR_SetF32(handle, name, val);
}
NvCV_Status nvidia::ar::ar::set_float64(NvAR_FeatureHandle handle, const char* name, double val)
{
return NvAR_SetF64(handle, name, val);
}
NvCV_Status nvidia::ar::ar::set_uint64(NvAR_FeatureHandle handle, const char* name, unsigned long long val)
{
return NvAR_SetU64(handle, name, val);
}
NvCV_Status nvidia::ar::ar::set_object(NvAR_FeatureHandle handle, const char* name, void* ptr, unsigned long typeSize)
{
return NvAR_SetObject(handle, name, ptr, typeSize);
}
NvCV_Status nvidia::ar::ar::set_string(NvAR_FeatureHandle handle, const char* name, const char* str)
{
return NvAR_SetString(handle, name, str);
}
NvCV_Status nvidia::ar::ar::set_cuda_stream(NvAR_FeatureHandle handle, const char* name, CUstream stream)
{
return NvAR_SetCudaStream(handle, name, stream);
}
NvCV_Status nvidia::ar::ar::set_float32_array(NvAR_FeatureHandle handle, const char* name, float* val, int count)
{
return NvAR_SetF32Array(handle, name, val, count);
}
NvCV_Status nvidia::ar::ar::get_uint32(NvAR_FeatureHandle handle, const char* name, unsigned int* val)
{
return NvAR_GetU32(handle, name, val);
}
NvCV_Status nvidia::ar::ar::get_int32(NvAR_FeatureHandle handle, const char* name, int* val)
{
return NvAR_GetS32(handle, name, val);
}
NvCV_Status nvidia::ar::ar::get_float32(NvAR_FeatureHandle handle, const char* name, float* val)
{
return NvAR_GetF32(handle, name, val);
}
NvCV_Status nvidia::ar::ar::get_float64(NvAR_FeatureHandle handle, const char* name, double* val)
{
return NvAR_GetF64(handle, name, val);
}
NvCV_Status nvidia::ar::ar::get_uint64(NvAR_FeatureHandle handle, const char* name, unsigned long long* val)
{
return NvAR_GetU64(handle, name, val);
}
NvCV_Status nvidia::ar::ar::get_object(NvAR_FeatureHandle handle, const char* name, const void** ptr,
unsigned long typeSize)
{
return NvAR_GetObject(handle, name, ptr, typeSize);
}
NvCV_Status nvidia::ar::ar::get_string(NvAR_FeatureHandle handle, const char* name, const char** str)
{
return NvAR_GetString(handle, name, str);
}
NvCV_Status nvidia::ar::ar::get_cuda_stream(NvAR_FeatureHandle handle, const char* name, const CUstream* stream)
{
return NvAR_GetCudaStream(handle, name, stream);
}
NvCV_Status nvidia::ar::ar::get_float32_array(NvAR_FeatureHandle handle, const char* name, const float** vals,
int* count)
{
return NvAR_GetF32Array(handle, name, vals, count);
}
NvCV_Status nvidia::ar::ar::run(NvAR_FeatureHandle handle)
{
return NvAR_Run(handle);
}
NvCV_Status nvidia::ar::ar::load(NvAR_FeatureHandle handle)
{
return NvAR_Load(handle);
}
NvCV_Status nvidia::ar::ar::cuda_stream_create(CUstream* stream)
{
return NvAR_CudaStreamCreate(stream);
}
NvCV_Status nvidia::ar::ar::cuda_stream_destroy(CUstream stream)
{
return NvAR_CudaStreamDestroy(stream);
}
const char* nvidia::ar::ar::cv_get_error_string_from_code(NvCV_Status code)
{
return NvCV_GetErrorStringFromCode(code);
}