npapi-vlc | branch: master | Jean-Baptiste Kempf <[email protected]> | Thu Dec 13 15:00:13 2012 +0100| [64c3d0f07e4faf53e3bba8bab029df71978d4610] | committer: Jean-Baptiste Kempf
Provide a WindowLessBase class > http://git.videolan.org/gitweb.cgi/npapi-vlc.git/?a=commit;h=64c3d0f07e4faf53e3bba8bab029df71978d4610 --- npapi/vlcplugin_base.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++ npapi/vlcplugin_base.h | 68 +++++++++++++++++++++++++++++++++ npapi/vlcshell.cpp | 44 +++++++++++++++++++++- 3 files changed, 204 insertions(+), 1 deletion(-) diff --git a/npapi/vlcplugin_base.cpp b/npapi/vlcplugin_base.cpp index 15280ec..eb6471d 100644 --- a/npapi/vlcplugin_base.cpp +++ b/npapi/vlcplugin_base.cpp @@ -7,6 +7,7 @@ * Authors: Samuel Hocevar <[email protected]> * Damien Fouilleul <[email protected]> * Jean-Paul Saman <[email protected]> + * Sergey Radionov <[email protected]> * Cheng Sun <[email protected]> * * This program is free software; you can redistribute it and/or modify @@ -835,3 +836,95 @@ bool VlcPluginBase::canUseEventListener() return true; return false; } + +VlcWindowlessBase::VlcWindowlessBase(NPP instance, NPuint16_t mode) : + VlcPluginBase(instance, mode) +{ +} + +VlcWindowlessBase::~VlcWindowlessBase() +{ +} + +unsigned VlcWindowlessBase::video_format_cb(char *chroma, + unsigned *width, unsigned *height, + unsigned *pitches, unsigned *lines) +{ + if ( p_browser ) { + float src_aspect = (float)(*width) / (*height); + float dst_aspect = (float)npwindow.width/npwindow.height; + if ( src_aspect > dst_aspect ) { + if( npwindow.width != (*width) ) { //don't scale if size equal + (*width) = npwindow.width; + (*height) = static_cast<unsigned>( (*width) / src_aspect + 0.5); + } + } + else { + if( npwindow.height != (*height) ) { //don't scale if size equal + (*height) = npwindow.height; + (*width) = static_cast<unsigned>( (*height) * src_aspect + 0.5); + } + } + } + + m_media_width = (*width); + m_media_height = (*height); + + memcpy(chroma, DEF_CHROMA, sizeof(DEF_CHROMA)-1); + (*pitches) = m_media_width * DEF_PIXEL_BYTES; + (*lines) = m_media_height; + + //+1 for vlc 2.0.3/2.1 bug workaround. + //They writes after buffer end boundary by some reason unknown to me... + m_frame_buf.resize( (*pitches) * ((*lines)+1) ); + + return 1; +} + +void VlcWindowlessBase::video_cleanup_cb() +{ + m_frame_buf.resize(0); + m_media_width = 0; + m_media_height = 0; +} + +void* VlcWindowlessBase::video_lock_cb(void **planes) +{ + (*planes) = m_frame_buf.empty()? 0 : &m_frame_buf[0]; + return 0; +} + +void VlcWindowlessBase::video_unlock_cb(void* /*picture*/, void *const * /*planes*/) +{ +} + +void VlcWindowlessBase::invalidate_window() +{ + NPRect rect; + rect.left = 0; + rect.top = 0; + rect.right = npwindow.width; + rect.bottom = npwindow.height; + NPN_InvalidateRect(p_browser, &rect); + NPN_ForceRedraw(p_browser); +} + +void VlcWindowlessBase::video_display_cb(void * /*picture*/) +{ + if (p_browser) { + NPN_PluginThreadAsyncCall(p_browser, + VlcWindowlessBase::invalidate_window_proxy, + this); + } +} + +void VlcWindowlessBase::set_player_window() { + libvlc_video_set_format_callbacks(getMD(), + video_format_proxy, + video_cleanup_proxy); + libvlc_video_set_callbacks(getMD(), + video_lock_proxy, + video_unlock_proxy, + video_display_proxy, + this); +} diff --git a/npapi/vlcplugin_base.h b/npapi/vlcplugin_base.h index e112eeb..02c22de 100644 --- a/npapi/vlcplugin_base.h +++ b/npapi/vlcplugin_base.h @@ -7,6 +7,7 @@ * Authors: Samuel Hocevar <[email protected]> * Damien Fouilleul <[email protected]> * Jean-Paul Saman <[email protected]> + * Sergey Radionov <[email protected]> * Cheng Sun <[email protected]> * * This program is free software; you can redistribute it and/or modify @@ -338,4 +339,71 @@ private: static std::set<VlcPluginBase*> _instances; }; + +const char DEF_CHROMA[] = "RV32"; +enum{ + DEF_PIXEL_BYTES = 4 +}; + +class VlcWindowlessBase : public VlcPluginBase +{ +public: + VlcWindowlessBase(NPP, NPuint16_t); + virtual ~VlcWindowlessBase(); + + //for libvlc_video_set_format_callbacks + static unsigned video_format_proxy(void **opaque, char *chroma, + unsigned *width, unsigned *height, + unsigned *pitches, unsigned *lines) + { return reinterpret_cast<VlcWindowlessBase*>(*opaque)->video_format_cb(chroma, + width, height, + pitches, lines); } + static void video_cleanup_proxy(void *opaque) + { reinterpret_cast<VlcWindowlessBase*>(opaque)->video_cleanup_cb(); }; + + unsigned video_format_cb(char *chroma, + unsigned *width, unsigned *height, + unsigned *pitches, unsigned *lines); + void video_cleanup_cb(); + //end (for libvlc_video_set_format_callbacks) + + //for libvlc_video_set_callbacks + static void* video_lock_proxy(void *opaque, void **planes) + { return reinterpret_cast<VlcWindowlessBase*>(opaque)->video_lock_cb(planes); } + static void video_unlock_proxy(void *opaque, void *picture, void *const *planes) + { reinterpret_cast<VlcWindowlessBase*>(opaque)->video_unlock_cb(picture, planes); } + static void video_display_proxy(void *opaque, void *picture) + { reinterpret_cast<VlcWindowlessBase*>(opaque)->video_display_cb(picture); } + + void* video_lock_cb(void **planes); + void video_unlock_cb(void *picture, void *const *planes); + void video_display_cb(void *picture); + //end (for libvlc_video_set_callbacks) + + static void invalidate_window_proxy(void *opaque) + { reinterpret_cast<VlcWindowlessBase*>(opaque)->invalidate_window(); } + void invalidate_window(); + + void set_player_window(); + + + bool create_windows() { return true; } + bool resize_windows() { return true; } + bool destroy_windows() { return true; } + + void toggle_fullscreen() { /* STUB */ } + void set_fullscreen( int ) { /* STUB */ } + int get_fullscreen() { return false; } + + void set_toolbar_visible(bool) { /* STUB */ } + bool get_toolbar_visible() { return false; } + void update_controls() {/* STUB */} + void popup_menu() {/* STUB */} + +protected: + std::vector<char> m_frame_buf; + unsigned int m_media_width; + unsigned int m_media_height; +}; + #endif diff --git a/npapi/vlcshell.cpp b/npapi/vlcshell.cpp index 883eb33..adb18c5 100644 --- a/npapi/vlcshell.cpp +++ b/npapi/vlcshell.cpp @@ -151,18 +151,60 @@ void NPP_Shutdown( void ) ; } +static bool boolValue(const char *value) { + return ( !strcmp(value, "1") || + !strcasecmp(value, "true") || + !strcasecmp(value, "yes") ); +} + NPError NPP_New( NPMIMEType, NPP instance, NPuint16_t mode, NPint16_t argc, char* argn[], char* argv[], NPSavedData* ) { NPError status; + VlcPluginBase *p_plugin; if( instance == NULL ) { return NPERR_INVALID_INSTANCE_ERROR; } - VlcPluginBase *p_plugin = new VlcPlugin( instance, mode ); + /* we need to tell whether the plugin will be windowless + * before it is instantiated */ + bool windowless = false; + for( int i = 0; i < argc; i++ ) + { + if( !strcmp( argn[i], "windowless" ) ) + { + windowless = boolValue(argv[i]); + break; + } + } + +#ifdef WINDOWLESS + if( windowless ) + { + /* set windowless flag */ + status = NPN_SetValue( instance, NPPVpluginWindowBool, + (void *)false); + if( NPERR_NO_ERROR != status ) + { + return status; + } + status = NPN_SetValue( instance, NPPVpluginTransparentBool, + (void *)false); + if( NPERR_NO_ERROR != status ) + { + return status; + } + + p_plugin = new VlcWindowless( instance, mode ); + } + else +#endif + { + p_plugin = new VlcPlugin( instance, mode ); + } if( NULL == p_plugin ) { return NPERR_OUT_OF_MEMORY_ERROR; _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
