[vlc-commits] Provide a WindowLessBase class
Jean-Baptiste Kempf
git at videolan.org
Thu Dec 13 15:50:11 CET 2012
npapi-vlc | branch: master | Jean-Baptiste Kempf <jb at videolan.org> | 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 <sam at zoy.org>
* Damien Fouilleul <damienf.fouilleul at laposte.net>
* Jean-Paul Saman <jpsaman at videolan.org>
+ * Sergey Radionov <rsatom at gmail.com>
* Cheng Sun <chengsun9 at gmail.com>
*
* 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 <sam at zoy.org>
* Damien Fouilleul <damienf at videolan.org>
* Jean-Paul Saman <jpsaman at videolan.org>
+ * Sergey Radionov <rsatom at gmail.com>
* Cheng Sun <chengsun9 at gmail.com>
*
* 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;
More information about the vlc-commits
mailing list