vlc | branch: master | Thomas Guillem <guil...@archos.com> | Thu Jul 24 15:11:25 2014 +0200| [e77a89bc021c1e83b0d478d332d60dfef770d37a] | committer: Martin Storsjö
iomx: add iomx_hwbuffer Wrapper to android native window api located in aosp system/window.h. Allow to queue/dequeue hw buffers (ANativeWindowBuffer_t) allocated with a speficied hal_format and hw_usage. This requires changes to the android build project to include iomx_hwbuffer.c when building libiomx-*.so. Signed-off-by: Martin Storsjö <mar...@martin.st> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e77a89bc021c1e83b0d478d332d60dfef770d37a --- modules/codec/omxil/iomx_hwbuffer.c | 230 +++++++++++++++++++++++++++++++++++ modules/codec/omxil/omxil_core.c | 17 +++ modules/codec/omxil/omxil_core.h | 10 ++ 3 files changed, 257 insertions(+) diff --git a/modules/codec/omxil/iomx_hwbuffer.c b/modules/codec/omxil/iomx_hwbuffer.c new file mode 100644 index 0000000..50cf322 --- /dev/null +++ b/modules/codec/omxil/iomx_hwbuffer.c @@ -0,0 +1,230 @@ +/***************************************************************************** + * iomx_hwbuffer.c: Wrapper to android native window api used for IOMX + ***************************************************************************** + * Copyright (C) 2011 VLC authors and VideoLAN + * + * Authors: Thomas Guillem <guil...@archos.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ + +#include <errno.h> +#include <stdio.h> + +#if ANDROID_API == 10 +#include <ui/android_native_buffer.h> +#include <ui/egl/android_natives.h> +#else +#include <system/window.h> +#endif + +#include <hardware/gralloc.h> + +#include <android/log.h> + +#define NO_ERROR 0 +typedef int32_t status_t; + +#if ANDROID_API == 10 +typedef android_native_buffer_t ANativeWindowBuffer_t; +#endif + +#define LOG_TAG "VLC/IOMX" + +#define LOGD(...) __android_log_print( ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__ ) +#define LOGE(...) __android_log_print( ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__ ) + +#define CHECK_ERR() do {\ + if( err != NO_ERROR ) {\ + LOGE( "IOMXHWBuffer: error %d in %s line %d\n", err, __FUNCTION__, __LINE__ );\ + return err;\ + }\ +} while (0) + +#define CHECK_ANW() do {\ + if( anw->common.magic != ANDROID_NATIVE_WINDOW_MAGIC &&\ + anw->common.version != sizeof(ANativeWindow) ) {\ + LOGE( "IOMXHWBuffer: error, window not valid\n" );\ + return -EINVAL;\ + }\ +} while (0) + +#define CHECK_ANB() do {\ + if( anb->common.magic != ANDROID_NATIVE_BUFFER_MAGIC &&\ + anb->common.version != sizeof(ANativeWindowBuffer_t) ) {\ + LOGE( "IOMXHWBuffer: error, buffer not valid\n" );\ + return -EINVAL;\ + }\ +} while (0) + +int IOMXHWBuffer_Connect( void *window ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + CHECK_ANW(); + +#if ANDROID_API >= 11 + if (native_window_api_connect( anw, NATIVE_WINDOW_API_MEDIA) != 0) { + LOGE( "native_window_api_connect FAIL" ); + return -EINVAL; + } +#endif +} + +int IOMXHWBuffer_Disconnect( void *window ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + + CHECK_ANW(); + +#if ANDROID_API >= 11 + native_window_api_disconnect( anw, NATIVE_WINDOW_API_MEDIA ); +#endif + + return 0; +} + + +int IOMXHWBuffer_Setup( void *window, int w, int h, int hal_format, int hw_usage, + unsigned int *num_frames, unsigned int *min_undequeued ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + int usage = 0; + status_t err; + + CHECK_ANW(); + + LOGD( "IOMXHWBuffer_setup: %p, %d, %d, %X, %X\n", + anw, w, h, hal_format, hw_usage ); + + usage |= hw_usage | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; +#if ANDROID_API >= 11 + usage |= GRALLOC_USAGE_EXTERNAL_DISP; +#endif + + err = native_window_set_usage( anw, usage ); + CHECK_ERR(); + +#if ANDROID_API == 10 + err = native_window_set_buffers_geometry( anw, w, h, hal_format ); + CHECK_ERR(); +#else + err = native_window_set_scaling_mode( anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW ); + CHECK_ERR(); + + err = native_window_set_buffers_dimensions( anw, w, h ); + CHECK_ERR(); + + err = native_window_set_buffers_format( anw, hal_format ); + CHECK_ERR(); + + if( *min_undequeued == 0 ) + { + anw->query( anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, min_undequeued ); + CHECK_ERR(); + } +#endif + /* set a minimum value of min_undequeued in case query fails */ + if( *min_undequeued == 0 ) + *min_undequeued = 2; + *num_frames += *min_undequeued; + + err = native_window_set_buffer_count( anw, *num_frames ); + CHECK_ERR(); + + return 0; +} + +int IOMXHWBuffer_Setcrop( void *window, int ofs_x, int ofs_y, int w, int h ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + android_native_rect_t crop; + + CHECK_ANW(); + + crop.left = ofs_x; + crop.top = ofs_y; + crop.right = ofs_x + w; + crop.bottom = ofs_y + h; + return native_window_set_crop( anw, &crop ); +} + +int IOMXHWBuffer_Dequeue( void *window, void **pp_handle ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + ANativeWindowBuffer_t *anb; + status_t err = NO_ERROR; + + CHECK_ANW(); + +#if ANDROID_API >= 18 + err = anw->dequeueBuffer_DEPRECATED( anw, &anb ); +#else + err = anw->dequeueBuffer( anw, &anb ); +#endif + CHECK_ERR(); + +#if ANDROID_API >= 18 + err = anw->lockBuffer_DEPRECATED( anw, anb ); +#else + err = anw->lockBuffer( anw, anb ); +#endif + CHECK_ERR(); + + *pp_handle = anb; + + return 0; +} + +int IOMXHWBuffer_Queue( void *window, void *p_handle ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle; + status_t err = NO_ERROR; + + CHECK_ANW(); + CHECK_ANB(); + +#if ANDROID_API >= 18 + err = anw->queueBuffer_DEPRECATED( anw, anb ); +#else + err = anw->queueBuffer( anw, anb ); +#endif + CHECK_ERR(); + + return 0; +} + +int IOMXHWBuffer_Cancel( void *window, void *p_handle ) +{ + ANativeWindow *anw = (ANativeWindow *)window; + ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle; + status_t err = NO_ERROR; + + CHECK_ANW(); + CHECK_ANB(); + +#if ANDROID_API >= 18 + err = anw->cancelBuffer_DEPRECATED( anw, anb ); +#else + err = anw->cancelBuffer( anw, anb ); +#endif + CHECK_ERR(); + + return 0; +} diff --git a/modules/codec/omxil/omxil_core.c b/modules/codec/omxil/omxil_core.c index 66ed161..5a934e6 100644 --- a/modules/codec/omxil/omxil_core.c +++ b/modules/codec/omxil/omxil_core.c @@ -87,6 +87,14 @@ OMX_ERRORTYPE (*pf_get_handle) (OMX_HANDLETYPE *, OMX_STRING, OMX_ERRORTYPE (*pf_free_handle) (OMX_HANDLETYPE); OMX_ERRORTYPE (*pf_component_enum)(OMX_STRING, OMX_U32, OMX_U32); OMX_ERRORTYPE (*pf_get_roles_of_component)(OMX_STRING, OMX_U32 *, OMX_U8 **); +int (*pf_omx_hwbuffer_connect) (void *); +int (*pf_omx_hwbuffer_disconnect) (void *); +int (*pf_omx_hwbuffer_setup) (void *, int, int, int, int, unsigned int *, + unsigned int *); +int (*pf_omx_hwbuffer_setcrop) (void *, int, int, int, int); +int (*pf_omx_hwbuffer_dequeue) (void *, void **); +int (*pf_omx_hwbuffer_queue) (void *, void *); +int (*pf_omx_hwbuffer_cancel) (void *, void *); #ifdef RPI_OMX static void *extra_dll_handle; @@ -160,6 +168,15 @@ int InitOmxCore(vlc_object_t *p_this) vlc_mutex_unlock( &omx_core_mutex ); return VLC_EGENERIC; } +#if defined(USE_IOMX) + pf_omx_hwbuffer_connect = dlsym( dll_handle, "OMXHWBuffer_Connect" ); + pf_omx_hwbuffer_disconnect = dlsym( dll_handle, "OMXHWBuffer_Disconnect" ); + pf_omx_hwbuffer_setup = dlsym( dll_handle, "OMXHWBuffer_Setup" ); + pf_omx_hwbuffer_setcrop = dlsym( dll_handle, "OMXHWBuffer_Setcrop" ); + pf_omx_hwbuffer_dequeue = dlsym( dll_handle, "OMXHWBuffer_Dequeue" ); + pf_omx_hwbuffer_queue = dlsym( dll_handle, "OMXHWBuffer_Queue" ); + pf_omx_hwbuffer_cancel = dlsym( dll_handle, "OMXHWBuffer_Cancel" ); +#endif /* Initialise the OMX core */ OMX_ERRORTYPE omx_error = pf_init(); diff --git a/modules/codec/omxil/omxil_core.h b/modules/codec/omxil/omxil_core.h index b223f6b..38faba2 100644 --- a/modules/codec/omxil/omxil_core.h +++ b/modules/codec/omxil/omxil_core.h @@ -33,6 +33,16 @@ OMX_ERRORTYPE (*pf_free_handle) (OMX_HANDLETYPE); OMX_ERRORTYPE (*pf_component_enum)(OMX_STRING, OMX_U32, OMX_U32); OMX_ERRORTYPE (*pf_get_roles_of_component)(OMX_STRING, OMX_U32 *, OMX_U8 **); +/* OMXHWBuffer functions */ +int (*pf_omx_hwbuffer_connect) (void *); +int (*pf_omx_hwbuffer_disconnect) (void *); +int (*pf_omx_hwbuffer_setup) (void *, int, int, int, int, unsigned int *, + unsigned int *); +int (*pf_omx_hwbuffer_setcrop) (void *, int, int, int, int); +int (*pf_omx_hwbuffer_dequeue) (void *, void **); +int (*pf_omx_hwbuffer_queue) (void *, void *); +int (*pf_omx_hwbuffer_cancel) (void *, void *); + int InitOmxCore(vlc_object_t *p_this); void DeinitOmxCore(void); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits