diff --git a/Changelog b/Changelog index 8c8978b6c8..46f0ecbea5 100644 --- a/Changelog +++ b/Changelog @@ -32,7 +32,7 @@ version : - Wideband Single-bit Data (WSD) demuxer - VAAPI-accelerated H.264/HEVC/MJPEG encoding - DTS Express (LBR) decoder -- Generic OpenMAX IL encoder +- Generic OpenMAX IL encoder with support for Raspberry Pi version 3.0: - Common Encryption (CENC) MP4 encoding and decoding support diff --git a/configure b/configure index e093e639cc..9a986ac8f3 100755 --- a/configure +++ b/configure @@ -162,6 +162,7 @@ Hardware-accelerated decoding/encoding: --enable-mmal enable decoding via MMAL [no] --enable-nvenc enable NVIDIA NVENC support [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 @@ -1552,6 +1553,7 @@ FEATURE_LIST=" ftrapv gray hardcoded_tables + omx_rpi runtime_cpudetect safe_bitstream_reader shared @@ -5730,12 +5732,17 @@ enabled opengl && { check_lib GL/glx.h glXGetProcAddress "-lGL" || check_lib2 ES2/gl.h glGetError "-isysroot=${sysroot} -Wl,-framework,OpenGLES" || die "ERROR: opengl 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 && { use_pkg_config openssl openssl/ssl.h SSL_library_init || check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } -enabled omx && { check_header OMX_Core.h || die "ERROR: OpenMAX IL headers not found"; } enabled qtkit_indev && { check_header_objcc QTKit/QTKit.h || disable qtkit_indev; } # libdc1394 check diff --git a/libavcodec/omx.c b/libavcodec/omx.c index a138d2cc11..c219ec0775 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -19,6 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + +#if CONFIG_OMX_RPI +#define OMX_SKIP64BIT +#endif + #include #include #include @@ -69,6 +75,7 @@ static int64_t from_omx_ticks(OMX_TICKS value) typedef struct OMXContext { void *lib; + void *lib2; OMX_ERRORTYPE (*ptr_Init)(void); OMX_ERRORTYPE (*ptr_Deinit)(void); OMX_ERRORTYPE (*ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32); @@ -76,6 +83,7 @@ typedef struct OMXContext { 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) @@ -86,8 +94,23 @@ static av_cold void *dlsym_prefixed(void *handle, const char *symbol, const char } 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); @@ -106,6 +129,9 @@ static av_cold int omx_try_load(OMXContext *s, void *logctx, 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; @@ -114,8 +140,12 @@ static av_cold int omx_try_load(OMXContext *s, void *logctx, 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; @@ -126,14 +156,14 @@ static av_cold OMXContext *omx_init(void *logctx, const char *libname, const cha 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 { - 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); @@ -141,6 +171,8 @@ static av_cold OMXContext *omx_init(void *logctx, const char *libname, const cha } } + if (omx_context->host_init) + omx_context->host_init(); omx_context->ptr_Init(); return omx_context; } @@ -298,6 +330,12 @@ static av_cold int find_component(OMXContext *omx_context, void *logctx, 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); diff --git a/libavcodec/version.h b/libavcodec/version.h index abe3847f4e..bd506fd124 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 41 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \