| /* | |
| * GPAC - Multimedia Framework C SDK | |
| * | |
| * Authors: Jean Le Feuvre | |
| * Copyright (c) Telecom ParisTech 2000-2012 | |
| * All rights reserved | |
| * | |
| * This file is part of GPAC / EPOC video output module | |
| * | |
| * GPAC 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, or (at your option) | |
| * any later version. | |
| * | |
| * GPAC 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 library; see the file COPYING. If not, write to | |
| * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
| * | |
| */ | |
| /*driver interface*/ | |
| #include <gpac/modules/video_out.h> | |
| #include <gpac/modules/audio_out.h> | |
| #include <gpac/modules/codec.h> | |
| #include <w32std.h> | |
| #ifdef GPAC_USE_GLES1X | |
| #include <GLES/egl.h> | |
| #endif | |
| typedef struct | |
| { | |
| RWindow *window; | |
| RWsSession *session; | |
| u32 pixel_format, bpp, width, height; | |
| CWsScreenDevice *screen; | |
| CFbsBitmap *surface; | |
| CWindowGc *gc; | |
| char *locked_data; | |
| u32 output_3d_type; | |
| #ifdef GPAC_USE_GLES1X | |
| EGLDisplay egl_display; | |
| EGLSurface egl_surface; | |
| EGLContext egl_context; | |
| #endif | |
| } EPOCVideo; | |
| static void EVID_ResetSurface(GF_VideoOutput *dr, Bool gl_only) | |
| { | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| #ifdef GPAC_USE_GLES1X | |
| if (ctx->egl_display) { | |
| eglMakeCurrent(ctx->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
| if (ctx->egl_context) eglDestroyContext(ctx->egl_display, ctx->egl_context); | |
| ctx->egl_context = NULL; | |
| if (ctx->egl_surface) eglDestroySurface(ctx->egl_display, ctx->egl_surface); | |
| ctx->egl_surface = NULL; | |
| eglTerminate(ctx->egl_display); | |
| ctx->egl_display = NULL; | |
| } | |
| #endif | |
| if (gl_only) return; | |
| if (ctx->locked_data) ctx->surface->UnlockHeap(); | |
| ctx->locked_data = NULL; | |
| if (ctx->surface) delete ctx->surface; | |
| ctx->surface = NULL; | |
| if (ctx->gc) delete ctx->gc; | |
| ctx->gc = NULL; | |
| if (ctx->screen) delete ctx->screen; | |
| ctx->screen = NULL; | |
| } | |
| static GF_Err EVID_InitSurface(GF_VideoOutput *dr) | |
| { | |
| TInt gl_buffer_size; | |
| TInt e; | |
| TDisplayMode disp_mode; | |
| TSize s; | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Reseting video\n")); | |
| EVID_ResetSurface(dr, 0); | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Video reset OK\n")); | |
| ctx->screen = new CWsScreenDevice(*ctx->session); | |
| if (!ctx->screen) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create screen device for session\n")); | |
| return GF_IO_ERR; | |
| } | |
| e = ctx->screen->Construct(); | |
| if (e != KErrNone) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot construct screen device for session - error %d\n", e)); | |
| return GF_IO_ERR; | |
| } | |
| e = ctx->screen->CreateContext(ctx->gc); | |
| if (e != KErrNone) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create graphical context - error %d\n", e)); | |
| return GF_IO_ERR; | |
| } | |
| ctx->surface = new CFbsBitmap(); | |
| if (!ctx->surface) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot allocate backbuffer surface\n")); | |
| return GF_IO_ERR; | |
| } | |
| s = ctx->window->Size(); | |
| disp_mode = ctx->screen->DisplayMode(); | |
| e = ctx->surface->Create(s, disp_mode); | |
| if (e != KErrNone) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create backbuffer surface - error %d\n", e)); | |
| return GF_IO_ERR; | |
| } | |
| gl_buffer_size = 0; | |
| switch (disp_mode) { | |
| case EGray256: | |
| ctx->pixel_format = GF_PIXEL_GREYSCALE; | |
| ctx->bpp = 1; | |
| break; | |
| case EColor64K: | |
| ctx->pixel_format = GF_PIXEL_RGB_565; | |
| ctx->bpp = 2; | |
| gl_buffer_size = 16; | |
| break; | |
| case EColor16M: | |
| ctx->pixel_format = GF_PIXEL_RGB_24; | |
| ctx->bpp = 3; | |
| gl_buffer_size = 24; | |
| break; | |
| /** 4096 colour display (12 bpp). */ | |
| case EColor4K: | |
| ctx->pixel_format = GF_PIXEL_RGB_444; | |
| ctx->bpp = 2; | |
| gl_buffer_size = 12; | |
| break; | |
| /** True colour display mode (32 bpp, but top byte is unused and unspecified) */ | |
| case EColor16MU: | |
| ctx->pixel_format = GF_PIXEL_RGB_32; | |
| ctx->bpp = 4; | |
| gl_buffer_size = 32; | |
| break; | |
| #if defined(__SERIES60_3X__) | |
| /** Display mode with alpha (24bpp colour plus 8bpp alpha) */ | |
| case EColor16MA: | |
| ctx->pixel_format = GF_PIXEL_ARGB; | |
| ctx->bpp = 4; | |
| gl_buffer_size = 32; | |
| break; | |
| #endif | |
| default: | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Unsupported display type %d\n", disp_mode)); | |
| return GF_NOT_SUPPORTED; | |
| } | |
| ctx->width = s.iWidth; | |
| ctx->height = s.iHeight; | |
| #ifdef GPAC_USE_GLES1X | |
| if (ctx->output_3d_type==1) { | |
| if (!gl_buffer_size) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Display mode not supported by OpenGL\n")); | |
| return GF_IO_ERR; | |
| } | |
| ctx->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
| if (ctx->egl_display == NULL) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot open OpenGL display\n")); | |
| return GF_IO_ERR; | |
| } | |
| if (eglInitialize(ctx->egl_display, NULL, NULL) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot initialize OpenGL display\n")); | |
| return GF_IO_ERR; | |
| } | |
| EGLConfig *configList = NULL; | |
| EGLint numOfConfigs = 0; | |
| EGLint configSize = 0; | |
| if (eglGetConfigs(ctx->egl_display, configList, configSize, &numOfConfigs) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot retrieve OpenGL configurations\n")); | |
| return GF_IO_ERR; | |
| } | |
| configSize = numOfConfigs; | |
| configList = (EGLConfig*) gf_malloc(sizeof(EGLConfig)*configSize); | |
| // Define properties for the wanted EGLSurface | |
| EGLint atts[7]; | |
| const char *opt = gf_opts_get_key("core", "gl-bits-depth"); | |
| atts[0] = EGL_BUFFER_SIZE; | |
| atts[1] = gl_buffer_size; | |
| atts[2] = EGL_DEPTH_SIZE; | |
| atts[3] = opt ? atoi(opt) : 16; | |
| atts[4] = EGL_SURFACE_TYPE; | |
| atts[5] = EGL_PIXMAP_BIT; | |
| atts[6] = EGL_NONE; | |
| if (eglChooseConfig(ctx->egl_display, atts, configList, configSize, &numOfConfigs) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot choose OpenGL configuration\n")); | |
| return GF_IO_ERR; | |
| } | |
| EGLConfig gl_cfg = configList[0]; | |
| gf_free(configList); | |
| ctx->egl_surface = eglCreatePixmapSurface(ctx->egl_display, gl_cfg, ctx->surface, NULL); | |
| if (ctx->egl_surface == NULL) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create OpenGL surface\n")); | |
| return GF_IO_ERR; | |
| } | |
| ctx->egl_context = eglCreateContext(ctx->egl_display, gl_cfg, EGL_NO_CONTEXT, NULL); | |
| if (ctx->egl_context == NULL) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create OpenGL context\n")); | |
| return GF_IO_ERR; | |
| } | |
| if (eglMakeCurrent(ctx->egl_display, ctx->egl_surface, ctx->egl_surface, ctx->egl_context) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot bind OpenGL context to current thread\n")); | |
| return GF_IO_ERR; | |
| } | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Video OpenGL setup\n")); | |
| } | |
| #endif | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Video setup OK - %d x %d @ PixelFormat %s\n", ctx->width, ctx->height, gf_4cc_to_str(ctx->pixel_format) )); | |
| return GF_OK; | |
| } | |
| #ifdef GPAC_USE_GLES1X | |
| static GF_Err EVID_SetupOGL_ES_Offscreen(GF_VideoOutput *dr, u32 width, u32 height) | |
| { | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| EVID_ResetSurface(dr, 1); | |
| if (!ctx->screen) return GF_NOT_SUPPORTED; | |
| TDisplayMode disp_mode = ctx->screen->DisplayMode(); | |
| TInt gl_buffer_size = 0; | |
| switch (disp_mode) { | |
| case EColor64K: | |
| gl_buffer_size = 16; | |
| break; | |
| case EColor16M: | |
| gl_buffer_size = 24; | |
| break; | |
| /** 4096 colour display (12 bpp). */ | |
| case EColor4K: | |
| gl_buffer_size = 12; | |
| break; | |
| /** True colour display mode (32 bpp, but top byte is unused and unspecified) */ | |
| case EColor16MU: | |
| gl_buffer_size = 32; | |
| break; | |
| #if defined(__SERIES60_3X__) | |
| /** Display mode with alpha (24bpp colour plus 8bpp alpha) */ | |
| case EColor16MA: | |
| gl_buffer_size = 32; | |
| break; | |
| #endif | |
| case EGray256: | |
| default: | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Unsupported display type %d for OpenGL\n", disp_mode)); | |
| return GF_NOT_SUPPORTED; | |
| } | |
| ctx->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
| if (ctx->egl_display == NULL) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot open OpenGL display\n")); | |
| return GF_IO_ERR; | |
| } | |
| if (eglInitialize(ctx->egl_display, NULL, NULL) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot initialize OpenGL display\n")); | |
| return GF_IO_ERR; | |
| } | |
| EGLConfig *configList = NULL; | |
| EGLint numOfConfigs = 0; | |
| EGLint configSize = 0; | |
| if (eglGetConfigs(ctx->egl_display, configList, configSize, &numOfConfigs) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot retrieve OpenGL configurations\n")); | |
| return GF_IO_ERR; | |
| } | |
| configSize = numOfConfigs; | |
| configList = (EGLConfig*) gf_malloc(sizeof(EGLConfig)*configSize); | |
| // Define properties for the wanted EGLSurface | |
| EGLint atts[13]; | |
| const char *opt = gf_opts_get_key("core", "gl-bits-depth"); | |
| atts[0] = EGL_RED_SIZE; | |
| atts[1] = 8; | |
| atts[2] = EGL_GREEN_SIZE; | |
| atts[3] = 8; | |
| atts[4] = EGL_BLUE_SIZE; | |
| atts[5] = 8; | |
| atts[6] = EGL_ALPHA_SIZE; | |
| atts[7] = (dr->hw_caps & GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA) ? 8 : EGL_DONT_CARE; | |
| atts[8] = EGL_SURFACE_TYPE; | |
| atts[9] = EGL_PBUFFER_BIT; | |
| atts[10] = EGL_DEPTH_SIZE; | |
| atts[11] = opt ? atoi(opt) : 16; | |
| atts[12] = EGL_NONE; | |
| if (eglChooseConfig(ctx->egl_display, atts, configList, configSize, &numOfConfigs) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot choose Offscreen OpenGL configuration\n")); | |
| return GF_IO_ERR; | |
| } | |
| EGLConfig gl_cfg = configList[0]; | |
| gf_free(configList); | |
| atts[0] = EGL_WIDTH; | |
| atts[1] = width; | |
| atts[2] = EGL_HEIGHT; | |
| atts[3] = height; | |
| atts[4] = EGL_NONE; | |
| ctx->egl_surface = eglCreatePbufferSurface(ctx->egl_display, gl_cfg, atts); | |
| if (ctx->egl_surface == NULL) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create OpenGL Pbuffer\n")); | |
| return GF_IO_ERR; | |
| } | |
| ctx->egl_context = eglCreateContext(ctx->egl_display, gl_cfg, EGL_NO_CONTEXT, NULL); | |
| if (ctx->egl_context == NULL) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create Offscreen OpenGL context\n")); | |
| return GF_IO_ERR; | |
| } | |
| if (eglMakeCurrent(ctx->egl_display, ctx->egl_surface, ctx->egl_surface, ctx->egl_context) == EGL_FALSE) { | |
| GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot bind Offscreen OpenGL context to current thread\n")); | |
| return GF_IO_ERR; | |
| } | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Offscreen OpenGL setup - size %d x %d\n", width, height)); | |
| return GF_OK; | |
| } | |
| #endif | |
| static GF_Err EVID_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_flags) | |
| { | |
| GF_Err res; | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| ctx->window = (RWindow *)os_handle; | |
| ctx->session = (RWsSession *)os_display; | |
| res = EVID_InitSurface(dr); | |
| /*setup opengl offscreen*/ | |
| #ifdef GPAC_USE_GLES1X | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Querying Offscreen OpenGL Capabilities\n")); | |
| dr->hw_caps |= GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; | |
| GF_Err e = EVID_SetupOGL_ES_Offscreen(dr, 20, 20); | |
| if (e!=GF_OK) { | |
| dr->hw_caps &= ~GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; | |
| e = EVID_SetupOGL_ES_Offscreen(dr, 20, 20); | |
| } | |
| if (!e) { | |
| dr->hw_caps |= GF_VIDEO_HW_OPENGL_OFFSCREEN; | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Offscreen OpenGL available - alpha support: %s\n", (dr->hw_caps & GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA) ? "yes" : "no")); | |
| } else { | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Offscreen OpenGL not available\n")); | |
| } | |
| #endif | |
| return res; | |
| } | |
| static void EVID_Shutdown(GF_VideoOutput *dr) | |
| { | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| EVID_ResetSurface(dr, 0); | |
| ctx->session = NULL; | |
| ctx->window = NULL; | |
| } | |
| static GF_Err EVID_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u32 *outHeight) | |
| { | |
| //EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| return GF_NOT_SUPPORTED; | |
| } | |
| static GF_Err EVID_Flush(GF_VideoOutput *dr, GF_Window *dest) | |
| { | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| if (ctx->gc && ctx->surface) { | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Activating window\n")); | |
| ctx->gc->Activate(*ctx->window); | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Bliting backbuffer\n")); | |
| ctx->gc->BitBlt(TPoint(0,0), ctx->surface); | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Deactivating window\n")); | |
| ctx->gc->Deactivate(); | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Flush success\n")); | |
| } | |
| return GF_OK; | |
| } | |
| static GF_Err EVID_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) | |
| { | |
| //EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| if (!evt) return GF_OK; | |
| switch (evt->type) { | |
| case GF_EVENT_SHOWHIDE: | |
| break; | |
| case GF_EVENT_SIZE: | |
| /*nothing to do since we don't own the window*/ | |
| break; | |
| case GF_EVENT_VIDEO_SETUP: | |
| ((EPOCVideo *)dr->opaque)->output_3d_type = evt->setup.opengl_mode; | |
| if (evt->setup.opengl_mode==2) { | |
| #ifdef GPAC_USE_GLES1X | |
| return EVID_SetupOGL_ES_Offscreen(dr, evt->setup.width, evt->setup.height); | |
| #else | |
| return GF_NOT_SUPPORTED; | |
| #endif | |
| } | |
| return EVID_InitSurface(dr/*, evt->size.width, evt->size.height*/); | |
| } | |
| return GF_OK; | |
| } | |
| static GF_Err EVID_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock) | |
| { | |
| EPOCVideo *ctx = (EPOCVideo *)dr->opaque; | |
| if (!ctx->surface) return GF_BAD_PARAM; | |
| if (do_lock) { | |
| if (!ctx->locked_data) { | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Locking backbuffer memory\n")); | |
| ctx->surface->LockHeap(); | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Retrieving backbuffer memory address\n")); | |
| ctx->locked_data = (char *)ctx->surface->DataAddress(); | |
| } | |
| memset(vi, 0, sizeof(GF_VideoSurface)); | |
| vi->height = ctx->height; | |
| vi->width = ctx->width; | |
| vi->is_hardware_memory = 0; | |
| vi->pitch = ctx->width * ctx->bpp; | |
| vi->pixel_format = ctx->pixel_format; | |
| vi->video_buffer = ctx->locked_data; | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Backbuffer locked OK - address 0x%08x\n", ctx->locked_data)); | |
| } else { | |
| if (ctx->locked_data) { | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Unlocking backbuffer memory\n")); | |
| ctx->surface->UnlockHeap(); | |
| ctx->locked_data = NULL; | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Backbuffer unlocked OK\n")); | |
| } | |
| } | |
| return GF_OK; | |
| } | |
| static void *EPOC_vout_new() | |
| { | |
| EPOCVideo *priv; | |
| GF_VideoOutput *driv; | |
| GF_SAFEALLOC(driv, GF_VideoOutput); | |
| GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "EPOC Video Output", "gpac distribution") | |
| GF_SAFEALLOC(priv, EPOCVideo); | |
| driv->opaque = priv; | |
| /*alpha and keying to do*/ | |
| driv->hw_caps = 0; | |
| #ifdef GPAC_USE_GLES1X | |
| /*no offscreen opengl with epoc at the moment*/ | |
| driv->hw_caps |= GF_VIDEO_HW_OPENGL; | |
| #endif | |
| driv->Setup = EVID_Setup; | |
| driv->Shutdown = EVID_Shutdown; | |
| driv->Flush = EVID_Flush; | |
| driv->ProcessEvent = EVID_ProcessEvent; | |
| driv->Blit = NULL; | |
| driv->LockBackBuffer = EVID_LockBackBuffer; | |
| driv->SetFullScreen = EVID_SetFullScreen; | |
| return (void *)driv; | |
| } | |
| static void EPOC_vout_del(void *ifce) | |
| { | |
| GF_VideoOutput *driv = (GF_VideoOutput *) ifce; | |
| EPOCVideo *priv = (EPOCVideo *)driv->opaque; | |
| gf_free(priv); | |
| gf_free(driv); | |
| } | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| void *EPOC_aout_new(); | |
| void EPOC_aout_del(void *ifce); | |
| void EPOC_codec_del(void *ifcg); | |
| void *EPOC_codec_new(); | |
| /*interface query*/ | |
| GPAC_MODULE_EXPORT | |
| const u32 *QueryInterfaces() | |
| { | |
| static u32 si [] = { | |
| GF_VIDEO_OUTPUT_INTERFACE, | |
| GF_AUDIO_OUTPUT_INTERFACE, | |
| GF_MEDIA_DECODER_INTERFACE, | |
| 0 | |
| }; | |
| return si; | |
| } | |
| /*interface create*/ | |
| GPAC_MODULE_EXPORT | |
| GF_BaseInterface *LoadInterface(u32 InterfaceType) | |
| { | |
| if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) EPOC_vout_new(); | |
| if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return (GF_BaseInterface *) EPOC_aout_new(); | |
| if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *) EPOC_codec_new(); | |
| return NULL; | |
| } | |
| /*interface destroy*/ | |
| GPAC_MODULE_EXPORT | |
| void ShutdownInterface(GF_BaseInterface *ifce) | |
| { | |
| GF_VideoOutput *dd = (GF_VideoOutput *)ifce; | |
| switch (dd->InterfaceType) { | |
| case GF_VIDEO_OUTPUT_INTERFACE: | |
| EPOC_vout_del(dd); | |
| break; | |
| case GF_AUDIO_OUTPUT_INTERFACE: | |
| EPOC_aout_del(ifce); | |
| break; | |
| case GF_MEDIA_DECODER_INTERFACE: | |
| EPOC_codec_del(ifce); | |
| break; | |
| } | |
| } | |
| GPAC_MODULE_STATIC_DECLARATION( epoc_vout ) | |
| #ifdef __cplusplus | |
| } | |
| #endif | |