The raspberry pi uses the alternative API/ABI for OMX; this makes
such builds incompatible with all the normal OpenMAX implementations.
Since this can't easily be detected at configure time (one can
build for raspberry pi's OMX just fine using the generic, pristine
Khronos OpenMAX IL headers, no need for their own extensions),
require a separate configure switch for it instead.
The broadcom host library can't be unloaded once loaded and started;
the deinit function that it provides is a no-op, and after started,
it has got background threads running, so dlclosing it makes it
crash.
Signed-off-by: Martin Storsjö <martin@martin.st>
- VAAPI-accelerated format conversion and scaling
- libnpp/CUDA-accelerated format conversion and scaling
- VAAPI-accelerate H.264/HEVC/MJPEG encoding
- VAAPI-accelerated format conversion and scaling
- libnpp/CUDA-accelerated format conversion and scaling
- VAAPI-accelerate H.264/HEVC/MJPEG encoding
-- Generic OpenMAX IL encoder
+- Generic OpenMAX IL encoder with support for Raspberry Pi
--enable-mmal enable decoding via MMAL [no]
--enable-nvenc enable encoding via NVENC [no]
--enable-omx enable encoding via OpenMAX IL [no]
--enable-mmal enable decoding via MMAL [no]
--enable-nvenc enable encoding via NVENC [no]
--enable-omx enable encoding via OpenMAX IL [no]
+ --enable-omx-rpi enable encoding via OpenMAX IL for Raspberry Pi [no]
Individual component options:
--disable-everything disable all components listed below
Individual component options:
--disable-everything disable all components listed below
FEATURE_LIST="
gray
hardcoded_tables
FEATURE_LIST="
gray
hardcoded_tables
runtime_cpudetect
safe_bitstream_reader
shared
runtime_cpudetect
safe_bitstream_reader
shared
check_lib interface/mmal/mmal.h mmal_port_connect ; }
check_lib interface/mmal/mmal.h mmal_port_connect ; } ||
die "ERROR: mmal not found"; }
check_lib interface/mmal/mmal.h mmal_port_connect ; }
check_lib interface/mmal/mmal.h mmal_port_connect ; } ||
die "ERROR: mmal not found"; }
-enabled omx && { check_header OMX_Core.h || die "ERROR: OpenMAX IL headers not found"; }
+enabled omx_rpi && enable omx
+enabled omx && { check_header OMX_Core.h ||
+ { ! enabled cross_compile && enabled omx_rpi && {
+ add_cflags -isystem/opt/vc/include/IL ; }
+ check_header OMX_Core.h ; } ||
+ die "ERROR: OpenMAX IL headers not found"; }
enabled openssl && { check_pkg_config openssl openssl/ssl.h SSL_library_init && {
add_cflags $openssl_cflags && add_extralibs $openssl_libs; }||
check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
enabled openssl && { check_pkg_config openssl openssl/ssl.h SSL_library_init && {
add_cflags $openssl_cflags && add_extralibs $openssl_libs; }||
check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+
+#if CONFIG_OMX_RPI
+#define OMX_SKIP64BIT
+#endif
+
#include <dlfcn.h>
#include <OMX_Core.h>
#include <OMX_Component.h>
#include <dlfcn.h>
#include <OMX_Core.h>
#include <OMX_Component.h>
typedef struct OMXContext {
void *lib;
typedef struct OMXContext {
void *lib;
OMX_ERRORTYPE (*ptr_Init)(void);
OMX_ERRORTYPE (*ptr_Deinit)(void);
OMX_ERRORTYPE (*ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32);
OMX_ERRORTYPE (*ptr_Init)(void);
OMX_ERRORTYPE (*ptr_Deinit)(void);
OMX_ERRORTYPE (*ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32);
OMX_ERRORTYPE (*ptr_FreeHandle)(OMX_HANDLETYPE);
OMX_ERRORTYPE (*ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
OMX_ERRORTYPE (*ptr_GetRolesOfComponent)(OMX_STRING, OMX_U32*, OMX_U8**);
OMX_ERRORTYPE (*ptr_FreeHandle)(OMX_HANDLETYPE);
OMX_ERRORTYPE (*ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
OMX_ERRORTYPE (*ptr_GetRolesOfComponent)(OMX_STRING, OMX_U32*, OMX_U8**);
+ void (*host_init)(void);
} OMXContext;
static av_cold void *dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
} OMXContext;
static av_cold void *dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
}
static av_cold int omx_try_load(OMXContext *s, void *logctx,
}
static av_cold int omx_try_load(OMXContext *s, void *logctx,
- const char *libname, const char *prefix)
+ const char *libname, const char *prefix,
+ const char *libname2)
+ if (libname2) {
+ s->lib2 = dlopen(libname2, RTLD_NOW | RTLD_GLOBAL);
+ if (!s->lib2) {
+ av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname);
+ return AVERROR_ENCODER_NOT_FOUND;
+ }
+ s->host_init = dlsym(s->lib2, "bcm_host_init");
+ if (!s->host_init) {
+ av_log(logctx, AV_LOG_WARNING, "bcm_host_init not found\n");
+ dlclose(s->lib2);
+ s->lib2 = NULL;
+ return AVERROR_ENCODER_NOT_FOUND;
+ }
+ }
s->lib = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
if (!s->lib) {
av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname);
s->lib = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
if (!s->lib) {
av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname);
av_log(logctx, AV_LOG_WARNING, "Not all functions found in %s\n", libname);
dlclose(s->lib);
s->lib = NULL;
av_log(logctx, AV_LOG_WARNING, "Not all functions found in %s\n", libname);
dlclose(s->lib);
s->lib = NULL;
+ if (s->lib2)
+ dlclose(s->lib2);
+ s->lib2 = NULL;
return AVERROR_ENCODER_NOT_FOUND;
}
return 0;
return AVERROR_ENCODER_NOT_FOUND;
}
return 0;
static av_cold OMXContext *omx_init(void *logctx, const char *libname, const char *prefix)
{
static const char * const libnames[] = {
static av_cold OMXContext *omx_init(void *logctx, const char *libname, const char *prefix)
{
static const char * const libnames[] = {
- "libOMX_Core.so",
- "libOmxCore.so",
+#if CONFIG_OMX_RPI
+ "/opt/vc/lib/libopenmaxil.so", "/opt/vc/lib/libbcm_host.so",
+#else
+ "libOMX_Core.so", NULL,
+ "libOmxCore.so", NULL,
+#endif
NULL
};
const char* const* nameptr;
NULL
};
const char* const* nameptr;
if (!omx_context)
return NULL;
if (libname) {
if (!omx_context)
return NULL;
if (libname) {
- ret = omx_try_load(omx_context, logctx, libname, prefix);
+ ret = omx_try_load(omx_context, logctx, libname, prefix, NULL);
if (ret < 0) {
av_free(omx_context);
return NULL;
}
} else {
if (ret < 0) {
av_free(omx_context);
return NULL;
}
} else {
- for (nameptr = libnames; *nameptr; nameptr++)
- if (!(ret = omx_try_load(omx_context, logctx, *nameptr, prefix)))
+ for (nameptr = libnames; *nameptr; nameptr += 2)
+ if (!(ret = omx_try_load(omx_context, logctx, nameptr[0], prefix, nameptr[1])))
break;
if (!*nameptr) {
av_free(omx_context);
break;
if (!*nameptr) {
av_free(omx_context);
+ if (omx_context->host_init)
+ omx_context->host_init();
omx_context->ptr_Init();
return omx_context;
}
omx_context->ptr_Init();
return omx_context;
}
char **components;
int ret = 0;
char **components;
int ret = 0;
+#if CONFIG_OMX_RPI
+ if (av_strstart(role, "video_encoder.", NULL)) {
+ av_strlcpy(str, "OMX.broadcom.video_encode", str_size);
+ return 0;
+ }
+#endif
omx_context->ptr_GetComponentsOfRole((OMX_STRING) role, &num, NULL);
if (!num) {
av_log(logctx, AV_LOG_WARNING, "No component for role %s found\n", role);
omx_context->ptr_GetComponentsOfRole((OMX_STRING) role, &num, NULL);
if (!num) {
av_log(logctx, AV_LOG_WARNING, "No component for role %s found\n", role);
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 18
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 18
-#define LIBAVCODEC_VERSION_MICRO 0
+#define LIBAVCODEC_VERSION_MICRO 1
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \