📄 epoc_vout.cpp
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * 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_OGL_ES#include <GLES/egl.h>#endiftypedef struct{ RWindow *window; RWsSession *session; Bool is_gl; u32 pixel_format, bpp, width, height; CWsScreenDevice *screen; CFbsBitmap *surface; CWindowGc *gc; char *locked_data;#ifdef GPAC_USE_OGL_ES EGLDisplay egl_display; EGLSurface egl_surface; EGLContext egl_context;#endif} EPOCVideo;static void EVID_ResetSurface(GF_VideoOutput *dr){ EPOCVideo *ctx = (EPOCVideo *)dr->opaque;#ifdef GPAC_USE_OGL_ES 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 (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); 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; /** 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; 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_OGL_ES if (ctx->is_gl) { 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*) malloc(sizeof(EGLConfig)*configSize); // Define properties for the wanted EGLSurface const EGLint attrib_list[] = { EGL_BUFFER_SIZE, gl_buffer_size, EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, EGL_NONE }; if (eglChooseConfig(ctx->egl_display, attrib_list, 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]; 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;}static GF_Err EVID_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, Bool noover, GF_GLConfig *gl_cfg){ EPOCVideo *ctx = (EPOCVideo *)dr->opaque; ctx->window = (RWindow *)os_handle; ctx->session = (RWsSession *)os_display; if (gl_cfg) ctx->is_gl = 1; return EVID_InitSurface(dr);}static void EVID_Shutdown(GF_VideoOutput *dr){ EPOCVideo *ctx = (EPOCVideo *)dr->opaque; EVID_ResetSurface(dr); 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: 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(); } 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_OGL_ES driv->hw_caps |= GF_VIDEO_HW_HAS_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; free(priv); free(driv);}#ifdef __cplusplusextern "C" {#endifvoid *EPOC_aout_new();void EPOC_aout_del(void *ifce);void EPOC_codec_del(void *ifcg);void *EPOC_codec_new(); /*interface query*/GF_EXPORTBool QueryInterface(u32 InterfaceType){ if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return 1; if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; return 0;}/*interface create*/GF_EXPORTGF_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*/GF_EXPORTvoid 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; }}#ifdef __cplusplus}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -