vlcplugin_base.h 11.8 KB
Newer Older
1
/*****************************************************************************
2
 * vlcplugin_base.h: a VLC plugin for Mozilla
3 4 5 6 7 8 9
 *****************************************************************************
 * Copyright (C) 2002-2009 the VideoLAN team
 * $Id$
 *
 * Authors: Samuel Hocevar <sam@zoy.org>
 *          Damien Fouilleul <damienf@videolan.org>
 *          Jean-Paul Saman <jpsaman@videolan.org>
10
 *          Sergey Radionov <rsatom@gmail.com>
11
 *          Cheng Sun <chengsun9@gmail.com>
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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.
 *****************************************************************************/

/*******************************************************************************
 * Instance state information about the plugin.
 ******************************************************************************/
#ifndef __VLCPLUGIN_BASE_H__
#define __VLCPLUGIN_BASE_H__

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

// Setup XP_MACOSX, XP_UNIX, XP_WIN
#if defined(_WIN32)
40
#   define XP_WIN 1
41
#elif defined(__APPLE__)
42
#   define XP_MACOSX 1
43
#else
44 45
#   define XP_UNIX 1
#   define MOZ_X11 1
46 47 48
#endif

#if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN)
49
#   define XP_UNIX 1
50
#elif defined(XP_MACOSX)
51
#   undef XP_UNIX
52 53
#endif

54
/* Windows includes */
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#ifdef XP_WIN
#   include <windows.h>
#endif

#ifdef XP_UNIX
#   include <pthread.h>
#endif

#ifndef __MAX
#   define __MAX(a, b)   ( ((a) > (b)) ? (a) : (b) )
#endif
#ifndef __MIN
#   define __MIN(a, b)   ( ((a) < (b)) ? (a) : (b) )
#endif

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

72
//on windows, to avoid including <npapi.h>
73 74 75 76 77
//from Microsoft SDK (rather then from Mozilla SDK),
//#include it indirectly via <npfunctions.h>
#include <npfunctions.h>

#include <vector>
78
#include <set>
79 80
#include <assert.h>

81
#include "../common/vlc_player_options.h"
82
#include "../common/vlc_player.h"
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

#if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) < 20)
    typedef uint16 NPuint16_t;
    typedef int16 NPint16_t;
    typedef int32 NPint32_t;
#else
    typedef uint16_t NPuint16_t;
    typedef int16_t NPint16_t;
    typedef int32_t NPint32_t;
#endif

typedef struct {
#if defined(XP_UNIX)
    pthread_mutex_t mutex;
#elif defined(XP_WIN)
    CRITICAL_SECTION cs;
#else
100
# warning "locking not implemented in this platform"
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#endif
} plugin_lock_t;

typedef struct {
    const char *name;                      /* event name */
    const libvlc_event_type_t libvlc_type; /* libvlc event type */
    libvlc_callback_t libvlc_callback;     /* libvlc callback function */
} vlcplugin_event_t;

class EventObj
{
private:

    class Listener
    {
    public:
        Listener(vlcplugin_event_t *event, NPObject *p_object, bool b_bubble):
            _event(event), _listener(p_object), _bubble(b_bubble)
            {
                assert(event);
                assert(p_object);
            }
        Listener(): _event(NULL), _listener(NULL), _bubble(false) { }
        ~Listener()
            {
            }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
127
        libvlc_event_type_t event_type() const { return _event->libvlc_type; }
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
        NPObject *listener() const { return _listener; }
        bool bubble() const { return _bubble; }
    private:
        vlcplugin_event_t *_event;
        NPObject *_listener;
        bool _bubble;
    };

    class VLCEvent
    {
    public:
        VLCEvent(libvlc_event_type_t libvlc_event_type, NPVariant *npparams, uint32_t npcount):
            _libvlc_event_type(libvlc_event_type), _npparams(npparams), _npcount(npcount)
            {
            }
        VLCEvent(): _libvlc_event_type(0), _npparams(NULL), _npcount(0) { }
        ~VLCEvent()
            {
            }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
147
        libvlc_event_type_t event_type() const { return _libvlc_event_type; }
148
        NPVariant *params() const { return _npparams; }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
149
        uint32_t count() const { return _npcount; }
150 151 152 153 154 155 156
    private:
        libvlc_event_type_t _libvlc_event_type;
        NPVariant *_npparams;
        uint32_t _npcount;
    };
    libvlc_event_manager_t *_em; /* libvlc media_player event manager */
public:
157
    EventObj(): _em(NULL), _already_in_deliver(false) { /* deferred to init() */ }
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
    bool init();
    ~EventObj();

    void deliver(NPP browser);
    void callback(const libvlc_event_t *event, NPVariant *npparams, uint32_t count);
    bool insert(const NPString &name, NPObject *listener, bool bubble);
    bool remove(const NPString &name, NPObject *listener, bool bubble);
    void unhook_manager(void *);
    void hook_manager(libvlc_event_manager_t *, void *);
private:
    vlcplugin_event_t *find_event(const char *s) const;
    const char *find_name(const libvlc_event_t *event);
    typedef std::vector<Listener> lr_l;
    typedef std::vector<VLCEvent> ev_l;
    lr_l _llist; /* list of registered listeners with 'addEventListener' method */
    ev_l _elist; /* scheduled events list for delivery to browser */

    plugin_lock_t lock;
176
    bool _already_in_deliver;
177 178 179 180 181 182 183 184 185 186 187 188 189 190
};

typedef enum vlc_toolbar_clicked_e {
    clicked_Unknown = 0,
    clicked_Play,
    clicked_Pause,
    clicked_Stop,
    clicked_timeline,
    clicked_Time,
    clicked_Fullscreen,
    clicked_Mute,
    clicked_Unmute
} vlc_toolbar_clicked_t;

191
class VlcPluginBase: private vlc_player_options, private vlc_player
192 193 194 195 196 197 198
{
protected:

public:
    VlcPluginBase( NPP, NPuint16_t );
    virtual ~VlcPluginBase();

199 200 201 202 203
    vlc_player& get_player()
    {
        return *static_cast<vlc_player*>(this);
    }

204 205 206 207 208
    vlc_player_options& get_options()
        { return *static_cast<vlc_player_options*>(this); }
    const vlc_player_options& get_options() const
        { return *static_cast<const vlc_player_options*>(this); }

209 210 211 212 213
    NPError             init(int argc, char* const argn[], char* const argv[]);
    libvlc_instance_t*  getVLC()
                            { return libvlc_instance; };
    libvlc_media_player_t* getMD()
    {
214
        if( !get_player().is_open() )
215 216 217
        {
             libvlc_printerr("no mediaplayer");
        }
218
        return get_player().get_mp();
219 220 221 222 223 224
    }
    NPP                 getBrowser()
                            { return p_browser; };
    char*               getAbsoluteURL(const char *url);
    NPWindow&           getWindow()
                            { return npwindow; };
225
    virtual void        setWindow(const NPWindow &window);
226 227 228 229 230 231 232 233 234 235 236 237

    NPClass*            getScriptClass()
                            { return p_scriptClass; };

    NPuint16_t  i_npmode; /* either NP_EMBED or NP_FULL */

    /* plugin properties */
    int      b_stream;
    char *   psz_target;

    void playlist_play()
    {
238
        get_player().play();
239 240 241
    }
    void playlist_play_item(int idx)
    {
242
        get_player().play(idx);
243 244 245
    }
    void playlist_stop()
    {
246
        get_player().stop();
247 248 249
    }
    void playlist_next()
    {
250
        get_player().next();
251 252 253
    }
    void playlist_prev()
    {
254
        get_player().prev();
255 256 257
    }
    void playlist_pause()
    {
258
        get_player().pause();
259 260 261
    }
    int playlist_isplaying()
    {
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
        return get_player().is_playing();
    }
    int playlist_add( const char * mrl)
    {
        return get_player().add_item(mrl);
    }
    int playlist_add_extended_untrusted( const char *mrl, const char *,
                    int optc, const char **optv )
    {
        return get_player().add_item(mrl, optc, optv);
    }
    int playlist_delete_item( int idx)
    {
        return get_player().delete_item(idx);
    }
    void playlist_clear()
    {
        get_player().clear_items() ;
    }
    int  playlist_count()
    {
        return get_player().items_count();
284 285 286 287 288 289 290 291 292 293
    }

    void control_handler(vlc_toolbar_clicked_t);

    bool  player_has_vout();

    virtual bool create_windows() = 0;
    virtual bool resize_windows() = 0;
    virtual bool destroy_windows() = 0;

294 295
    virtual bool handle_event(void *event);

296
    virtual void toggle_fullscreen() = 0;
297 298 299 300 301
    virtual void set_fullscreen(int) = 0;
    virtual int get_fullscreen() = 0;

    virtual void set_toolbar_visible(bool) = 0;
    virtual bool get_toolbar_visible() = 0;
302

303
    virtual void update_controls() = 0;
304
    virtual void popup_menu() = 0;
305

306 307
    virtual void set_player_window() = 0;

308 309 310 311 312 313
    static bool canUseEventListener();

    EventObj events;
    void event_callback(const libvlc_event_t *, NPVariant *, uint32_t);

protected:
314 315 316 317 318
    // called after libvlc_media_player_new_from_media
    virtual void on_media_player_new()     {};
    // called before libvlc_media_player_release
    virtual void on_media_player_release() {};

319 320 321 322 323 324 325 326
    bool playlist_select(int);

    /* VLC reference */
    libvlc_instance_t   *libvlc_instance;
    NPClass             *p_scriptClass;

    /* browser reference */
    NPP     p_browser;
327
    char    *psz_baseURL;
328 329 330 331 332

    /* display settings */
    NPWindow  npwindow;

    static void eventAsync(void *);
333 334 335

private:
    static std::set<VlcPluginBase*> _instances;
336 337
};

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404

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;
};

405
#endif