Merge pull request #5192 from akallabeth/dynamic_openh264
Using (optional) runtime linking for OpenH264.
This commit is contained in:
commit
b18ba33264
@ -870,6 +870,10 @@ find_feature(soxr ${SOXR_FEATURE_TYPE} ${SOXR_FEATURE_PURPOSE} ${SOXR_FEATURE_DE
|
||||
|
||||
find_feature(GSSAPI ${GSSAPI_FEATURE_TYPE} ${GSSAPI_FEATURE_PURPOSE} ${GSSAPI_FEATURE_DESCRIPTION})
|
||||
|
||||
if (WITH_OPENH264 AND NOT WITH_OPENH264_LOADING)
|
||||
set(WITH_OPENH264_LOADING OFF)
|
||||
endif (WITH_OPENH264 AND NOT WITH_OPENH264_LOADING)
|
||||
|
||||
if ((WITH_FFMPEG OR WITH_DSP_FFMPEG) AND NOT FFMPEG_FOUND)
|
||||
message(FATAL_ERROR "FFMPEG support requested but not detected")
|
||||
endif()
|
||||
|
@ -60,6 +60,7 @@
|
||||
#cmakedefine WITH_SOXR
|
||||
#cmakedefine WITH_GFX_H264
|
||||
#cmakedefine WITH_OPENH264
|
||||
#cmakedefine WITH_OPENH264_LOADING
|
||||
#cmakedefine WITH_FFMPEG
|
||||
#cmakedefine WITH_DSP_EXPERIMENTAL
|
||||
#cmakedefine WITH_DSP_FFMPEG
|
||||
|
@ -206,7 +206,9 @@ endif()
|
||||
if(WITH_OPENH264)
|
||||
set(CODEC_SRCS ${CODEC_SRCS} codec/h264_openh264.c)
|
||||
freerdp_include_directory_add(${OPENH264_INCLUDE_DIR})
|
||||
freerdp_library_add(${OPENH264_LIBRARIES})
|
||||
if (NOT WITH_OPENH264_LOADING)
|
||||
freerdp_library_add(${OPENH264_LIBRARIES})
|
||||
endif (NOT WITH_OPENH264_LOADING)
|
||||
endif()
|
||||
|
||||
if(WITH_FFMPEG)
|
||||
|
@ -18,27 +18,56 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/codec/h264.h>
|
||||
#include <winpr/library.h>
|
||||
|
||||
#include "wels/codec_def.h"
|
||||
#include "wels/codec_api.h"
|
||||
#include "wels/codec_ver.h"
|
||||
|
||||
#if (OPENH264_MAJOR == 1) && (OPENH264_MINOR < 3) || (OPENH264_MAJOR < 1)
|
||||
#error "Unsupported OpenH264 version "OPENH264_MAJOR"."OPENH264_MINOR"."OPENH264_REVISION" detected!"
|
||||
#elif (OPENH264_MAJOR > 1) || (OPENH264_MINOR > 7)
|
||||
#warning "Untested OpenH264 version "OPENH264_MAJOR"."OPENH264_MINOR"."OPENH264_REVISION" detected!"
|
||||
#endif
|
||||
typedef void (*pWelsGetCodecVersionEx)(OpenH264Version* pVersion);
|
||||
|
||||
typedef long (*pWelsCreateDecoder)(ISVCDecoder** ppDecoder);
|
||||
typedef void (*pWelsDestroyDecoder)(ISVCDecoder* pDecoder);
|
||||
|
||||
typedef int (*pWelsCreateSVCEncoder)(ISVCEncoder** ppEncoder);
|
||||
typedef void (*pWelsDestroySVCEncoder)(ISVCEncoder* pEncoder);
|
||||
|
||||
struct _H264_CONTEXT_OPENH264
|
||||
{
|
||||
#if defined (WITH_OPENH264_LOADING)
|
||||
HMODULE lib;
|
||||
OpenH264Version version;
|
||||
#endif
|
||||
pWelsGetCodecVersionEx WelsGetCodecVersionEx;
|
||||
pWelsCreateDecoder WelsCreateDecoder;
|
||||
pWelsDestroyDecoder WelsDestroyDecoder;
|
||||
pWelsCreateSVCEncoder WelsCreateSVCEncoder;
|
||||
pWelsDestroySVCEncoder WelsDestroySVCEncoder;
|
||||
ISVCDecoder* pDecoder;
|
||||
ISVCEncoder* pEncoder;
|
||||
SEncParamExt EncParamExt;
|
||||
};
|
||||
typedef struct _H264_CONTEXT_OPENH264 H264_CONTEXT_OPENH264;
|
||||
|
||||
#if defined (WITH_OPENH264_LOADING)
|
||||
static const char* openh264_library_names[] =
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
"openh264.dll"
|
||||
#elif defined(__APPLE__)
|
||||
"libopenh264.dylib"
|
||||
#else
|
||||
"libopenh264.so"
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
static void openh264_trace_callback(H264_CONTEXT* h264, int level,
|
||||
const char* message)
|
||||
{
|
||||
@ -313,25 +342,85 @@ static void openh264_uninit(H264_CONTEXT* h264)
|
||||
if (sys->pDecoder)
|
||||
{
|
||||
(*sys->pDecoder)->Uninitialize(sys->pDecoder);
|
||||
WelsDestroyDecoder(sys->pDecoder);
|
||||
sysContexts->WelsDestroyDecoder(sys->pDecoder);
|
||||
sys->pDecoder = NULL;
|
||||
}
|
||||
|
||||
if (sys->pEncoder)
|
||||
{
|
||||
(*sys->pEncoder)->Uninitialize(sys->pEncoder);
|
||||
WelsDestroySVCEncoder(sys->pEncoder);
|
||||
sysContexts->WelsDestroySVCEncoder(sys->pEncoder);
|
||||
sys->pEncoder = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (WITH_OPENH264_LOADING)
|
||||
FreeLibrary(sysContexts->lib);
|
||||
#endif
|
||||
free(h264->pSystemData);
|
||||
h264->pSystemData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (WITH_OPENH264_LOADING)
|
||||
static BOOL openh264_load_functionpointers(H264_CONTEXT* h264, const char* name)
|
||||
{
|
||||
H264_CONTEXT_OPENH264* sysContexts;
|
||||
|
||||
if (!h264)
|
||||
return FALSE;
|
||||
|
||||
sysContexts = h264->pSystemData;
|
||||
|
||||
if (!sysContexts)
|
||||
return FALSE;
|
||||
|
||||
sysContexts->lib = sysContexts->lib = LoadLibraryA(name);
|
||||
|
||||
if (!sysContexts->lib)
|
||||
return FALSE;
|
||||
|
||||
sysContexts->WelsGetCodecVersionEx = GetProcAddress(sysContexts->lib, "WelsGetCodecVersionEx");
|
||||
sysContexts->WelsCreateDecoder = GetProcAddress(sysContexts->lib, "WelsCreateDecoder");
|
||||
sysContexts->WelsDestroyDecoder = GetProcAddress(sysContexts->lib, "WelsDestroyDecoder");
|
||||
sysContexts->WelsCreateSVCEncoder = GetProcAddress(sysContexts->lib, "WelsCreateSVCEncoder");
|
||||
sysContexts->WelsDestroySVCEncoder = GetProcAddress(sysContexts->lib, "WelsDestroySVCEncoder");
|
||||
|
||||
if (!sysContexts->WelsCreateDecoder || !sysContexts->WelsDestroyDecoder ||
|
||||
!sysContexts->WelsCreateSVCEncoder || !sysContexts->WelsDestroySVCEncoder ||
|
||||
!sysContexts->WelsGetCodecVersionEx)
|
||||
{
|
||||
FreeLibrary(sysContexts->lib);
|
||||
sysContexts->lib = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sysContexts->WelsGetCodecVersionEx(&sysContexts->version);
|
||||
WLog_Print(h264->log, WLOG_INFO, "loaded %s %d.%d.%d", name, sysContexts->version.uMajor,
|
||||
sysContexts->version.uMinor,
|
||||
sysContexts->version.uRevision);
|
||||
|
||||
if ((sysContexts->version.uMajor < 1) || (sysContexts->version.uMinor < 6))
|
||||
{
|
||||
WLog_Print(h264->log, WLOG_ERROR,
|
||||
"OpenH264 %s %d.%d.%d is too old, need at least version 1.6.0 for dynamic loading",
|
||||
name, sysContexts->version.uMajor, sysContexts->version.uMinor,
|
||||
sysContexts->version.uRevision);
|
||||
FreeLibrary(sysContexts->lib);
|
||||
sysContexts->lib = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOL openh264_init(H264_CONTEXT* h264)
|
||||
{
|
||||
#if defined (WITH_OPENH264_LOADING)
|
||||
BOOL success = FALSE;
|
||||
size_t i;
|
||||
#endif
|
||||
UINT32 x;
|
||||
long status;
|
||||
SDecodingParam sDecParam;
|
||||
@ -350,6 +439,27 @@ static BOOL openh264_init(H264_CONTEXT* h264)
|
||||
goto EXCEPTION;
|
||||
|
||||
h264->pSystemData = (void*) sysContexts;
|
||||
#if defined (WITH_OPENH264_LOADING)
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(openh264_library_names); i++)
|
||||
{
|
||||
const char* current = openh264_library_names[i];
|
||||
success = openh264_load_functionpointers(h264, current);
|
||||
|
||||
if (success)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
goto EXCEPTION;
|
||||
|
||||
#else
|
||||
sysContexts->WelsGetCodecVersionEx = WelsGetCodecVersionEx;
|
||||
sysContexts->WelsCreateDecoder = WelsCreateDecoder;
|
||||
sysContexts->WelsDestroyDecoder = WelsDestroyDecoder;
|
||||
sysContexts->WelsCreateSVCEncoder = WelsCreateSVCEncoder;
|
||||
sysContexts->WelsDestroySVCEncoder = WelsDestroySVCEncoder;
|
||||
#endif
|
||||
|
||||
for (x = 0; x < h264->numSystemData; x++)
|
||||
{
|
||||
@ -357,7 +467,7 @@ static BOOL openh264_init(H264_CONTEXT* h264)
|
||||
|
||||
if (h264->Compressor)
|
||||
{
|
||||
WelsCreateSVCEncoder(&sys->pEncoder);
|
||||
sysContexts->WelsCreateSVCEncoder(&sys->pEncoder);
|
||||
|
||||
if (!sys->pEncoder)
|
||||
{
|
||||
@ -367,7 +477,7 @@ static BOOL openh264_init(H264_CONTEXT* h264)
|
||||
}
|
||||
else
|
||||
{
|
||||
WelsCreateDecoder(&sys->pDecoder);
|
||||
sysContexts->WelsCreateDecoder(&sys->pDecoder);
|
||||
|
||||
if (!sys->pDecoder)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user