root/include/gpac/html5_media.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


/*
 *                      GPAC - Multimedia Framework C SDK
 *
 *                      Authors: Cyril Concolato
 *                      Copyright (c) Telecom ParisTech 2013-
 *                                      All rights reserved
 *
 *  This file is part of GPAC / HTML Media Element header
 *
 *  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.
 *
 */


#ifndef _GF_HTMLMEDIA_H_
#define _GF_HTMLMEDIA_H_

#ifdef __cplusplus
extern "C" {
#endif


/*!
 *      \file <gpac/html5_media.h>
 *      \brief Scene graph extensions for HTML5 media.
 */
        
/*! \defgroup html5_grp HTML5
 *      \ingroup scene_grp
 *      \brief HTML5 extensions of the scene graph.
 *      
*/
/*!
 *  \addtogroup html5media_grp HTML5 media
 *      \ingroup html5_grp
 *      \brief Scene graph extensions for HTML5 media.
 *
 *This section documents the scene graph extensions used for HTML5 media (video).
 *      @{
 */

#include <gpac/internal/scenegraph_dev.h>

/*base SVG type*/
#include <gpac/nodes_svg.h>
/*dom events*/
#include <gpac/events.h>
/*dom text event*/
#include <gpac/utf.h>

#include <gpac/download.h>
#include <gpac/network.h>
#include <gpac/modules/service.h>
#include <gpac/xml.h>
#include <gpac/internal/terminal_dev.h>

#ifdef GPAC_HAS_SPIDERMONKEY
#include <gpac/internal/smjs_api.h>
#endif

typedef struct
{
        u32 nb_inst;
        /* Basic classes */
        GF_JSClass  arrayBufferClass;

        /*HTML Media classes*/
        GF_JSClass  htmlVideoElementClass;
        GF_JSClass  htmlAudioElementClass;
        GF_JSClass  htmlSourceElementClass;
        GF_JSClass  htmlTrackElementClass;
        GF_JSClass  htmlMediaElementClass;
        GF_JSClass  mediaControllerClass;
        GF_JSClass  audioTrackListClass;
        GF_JSClass  audioTrackClass;
        GF_JSClass  videoTrackListClass;
        GF_JSClass  videoTrackClass;
        GF_JSClass  textTrackListClass;
        GF_JSClass  textTrackClass;
        GF_JSClass  textTrackCueListClass;
        GF_JSClass  textTrackCueClass;
        GF_JSClass  timeRangesClass;
        GF_JSClass  trackEventClass;
        GF_JSClass  mediaErrorClass;

        /* Media Source Extensions */
        GF_JSClass  mediaSourceClass;
        GF_JSClass  sourceBufferClass;
        GF_JSClass  sourceBufferListClass;
        GF_JSClass  URLClass;

        /* Media Capture */
        GF_JSClass  mediaStreamClass;
        GF_JSClass  localMediaStreamClass;
        GF_JSClass  mediaStreamTrackClass;
        GF_JSClass  mediaStreamTrackListClass;
        GF_JSClass  navigatorUserMediaClass;
        GF_JSClass  navigatorUserMediaErrorClass;
} GF_HTML_MediaRuntime;

/************************************************************
 *
 *  HTML 5 Media Element
 *  http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#media-element
 *
 *************************************************************/

typedef enum
{
        MEDIA_ERR_ABORTED           = 1,
        MEDIA_ERR_NETWORK           = 2,
        MEDIA_ERR_DECODE            = 3,
        MEDIA_ERR_SRC_NOT_SUPPORTED = 4
} GF_HTML_MediaErrorCode;

typedef enum
{
        NETWORK_EMPTY               = 0,
        NETWORK_IDLE                = 1,
        NETWORK_LOADING             = 2,
        NETWORK_NO_SOURCE           = 3
} GF_HTML_NetworkState;

typedef enum
{
        HAVE_NOTHING                = 0,
        HAVE_METADATA               = 1,
        HAVE_CURRENT_DATA           = 2,
        HAVE_FUTURE_DATA            = 3,
        HAVE_ENOUGH_DATA            = 4
} GF_HTML_MediaReadyState;

typedef struct
{
        /* JavaScript context associated to this object */
        JSContext               *c;
        /* JavaScript counterpart */
        JSObject                *_this;

        GF_HTML_MediaErrorCode   code;
} GF_HTML_MediaError;

typedef struct _timerange
{
        /* JavaScript context associated to this object */
        JSContext               *c;
        /* JavaScript counterpart */
        JSObject                *_this;

        GF_List                 *times;
        u32                                             timescale;
} GF_HTML_MediaTimeRanges;

typedef enum {
        HTML_MEDIA_TRACK_TYPE_UNKNOWN = 0,
        HTML_MEDIA_TRACK_TYPE_AUDIO = 1,
        HTML_MEDIA_TRACK_TYPE_VIDEO = 2,
        HTML_MEDIA_TRACK_TYPE_TEXT  = 3
} GF_HTML_TrackType;

#define BASE_HTML_TRACK     \
    /* JavaScript context associated to this object */\
    JSContext               *c;\
    /* JavaScript counterpart */\
    JSObject                *_this;\
    /* GPAC-specific properties */\
    u32                     bin_id;    /* track id */\
    LPNETCHANNEL            channel;   /* channel object used by the terminal */\
    GF_ObjectDescriptor     *od;       /* MPEG-4 Object descriptor for this track */\
    GF_List                 *buffer;   /* List of MSE Packets */\
    u32                                         packet_index;   /* index of MSE Packets*/\
    GF_Mutex                *buffer_mutex;\
    Bool                    last_dts_set; \
    u64                                         last_dts; /* MSE  last decode timestamp (in timescale units)*/ \
    u32                                         last_dur; /* MSE  last frame duration (in timescale units)*/ \
    Bool                    highest_pts_set; \
    u64                                         highest_pts; /* MSE highest presentation timestamp (in timescale units)*/ \
    Bool                    needs_rap; /* MSE  need random access point flag */ \
    u32                     timescale; /* used by time stamps in MSE Packets */ \
    s64                     timestampOffset; /* MSE SourceBuffer value (in timescale units) */ \
    /* standard HTML properties */ \
    GF_HTML_TrackType        type;\
    char                    *id;\
    char                    *kind;\
    char                    *label;\
    char                    *language;\
    char                    *mime; \
    Bool                    enabled_or_selected;

typedef struct
{
        BASE_HTML_TRACK
} GF_HTML_Track;

typedef struct
{
        BASE_HTML_TRACK
        JSFunction                              *oncuechange;
        char                    *inBandMetadataTrackDispatchType;
        //GF_HTMLTextTrackMode    mode;
        //GF_HTMLTextTrackCueList cues;
        //GF_HTMLTextTrackCueList activeCues;
} GF_HTML_TextTrack;

#define BASE_HTML_TRACK_LIST     \
    /* JavaScript context associated to this object */\
    JSContext               *c;\
    /* JavaScript counterpart */\
    JSObject                *_this;\
    GF_List                 *tracks; \
        jsval                                   onchange; \
        jsval                                   onaddtrack; \
        jsval                                   onremovetrack; \
    u32                     selected_index;

typedef struct
{
        BASE_HTML_TRACK_LIST
} GF_HTML_TrackList;

typedef enum
{
        MEDIA_CONTROLLER_WAITING = 0,
        MEDIA_CONTROLLER_PLAYING = 1,
        MEDIA_CONTROLLER_ENDED   = 2
} GF_HTML_MediaControllerPlaybackState;

typedef struct
{
        /* JavaScript context associated to this object */
        JSContext               *c;
        /* JavaScript counterpart */
        JSObject                *_this;

        GF_HTML_MediaTimeRanges  *buffered;
        GF_HTML_MediaTimeRanges  *seekable;
        GF_HTML_MediaTimeRanges  *played;
        Bool                    paused;
        GF_HTML_MediaControllerPlaybackState playbackState;
        double                  defaultPlaybackRate;

        /* list of media elements using this media controller */
        GF_List                 *media_elements;
} GF_HTML_MediaController;

typedef struct
{
        /* JavaScript context associated to this object */
        JSContext               *c;
        /* JavaScript counterpart */
        JSObject                *_this;

        /* The audio or video node */
        GF_Node                 *node;

        /* error state */
        GF_HTML_MediaError       error;

        /* src: not stored in this structure,
                using the value stored in the node ( see HTML 5 "must reflect the content of the attribute")*/
        /* currentSrc: the actual source used for the video (src attribute on video, audio or source elements) */
        char                    *currentSrc;
        /* crossOrigin: "must reflect the content of the attribute of the same name", use the node */
        /* networkState: retrieved dynamically from GPAC Service */
        /* preload: "must reflect the content of the attribute of the same name", use the node */
        GF_HTML_MediaTimeRanges  *buffered;
        /* ready state */
        /* readyState: retrieved from GPAC Media Object dynamically */
        Bool                    seeking;

        /* playback state */
        /* currentTime: retrieved from GPAC Media Object */
        /* duration: retrieved from GPAC Media Object */
        char                    *startDate;
        Bool                    paused;
        double                  defaultPlaybackRate;
        GF_HTML_MediaTimeRanges  *played;
        GF_HTML_MediaTimeRanges  *seekable;
        /* ended: retrieved from the state of GPAC Media Object */
        /* autoplay: "must reflect the content of the attribute of the same name", use the node */
        /* loop: "must reflect the content of the attribute of the same name", use the node */

        /* media controller*/
        /* mediaGroup: "must reflect the content of the attribute of the same name", use the node */
        GF_HTML_MediaController  *controller;

        /* controls*/
        /* controls: "must reflect the content of the attribute of the same name", use the node */
        /* volume: retrieved from GPAC Audio Input in GPAC Media Object */
        /* muted: retrieved from GPAC media object */
        /* defaultMuted: "must reflect the content of the attribute of with the name" muted */

        /* tracks*/
        GF_HTML_TrackList        audioTracks;
        GF_HTML_TrackList        videoTracks;
        GF_HTML_TrackList        textTracks;

        GF_DOMEventTarget                *evt_target;
} GF_HTML_MediaElement;

typedef struct
{
        /* JavaScript context used to create the JavaScript object below */
        JSContext               *c;

        /* JavaScript counterpart for this object*/
        JSObject                *_this;

        char    *data;
        u32     length;
        char    *url;
        Bool    is_init;

        /* used to do proper garbage collection between JS and Terminal */
        u32     reference_count;
} GF_HTML_ArrayBuffer;

/*
 * TimeRanges
 */
GF_HTML_MediaTimeRanges *gf_html_timeranges_new(u32 timescale);
GF_Err gf_html_timeranges_add_start(GF_HTML_MediaTimeRanges *timeranges, u64 start);
GF_Err gf_html_timeranges_add_end(GF_HTML_MediaTimeRanges *timeranges, u64 end);
void    gf_html_timeranges_reset(GF_HTML_MediaTimeRanges *range);
void    gf_html_timeranges_del(GF_HTML_MediaTimeRanges *range);
GF_HTML_MediaTimeRanges *gf_html_timeranges_intersection(GF_HTML_MediaTimeRanges *a, GF_HTML_MediaTimeRanges *b);
GF_HTML_MediaTimeRanges *gf_html_timeranges_union(GF_HTML_MediaTimeRanges *a, GF_HTML_MediaTimeRanges *b);

/*
 * HTML5 TrackList
 */
GF_HTML_Track *html_media_add_new_track_to_list(GF_HTML_TrackList *tracklist,
        GF_HTML_TrackType type, const char *mime, Bool enable_or_selected,
        const char *id, const char *kind, const char *label, const char *lang);
Bool html_media_tracklist_has_track(GF_HTML_TrackList *tracklist, const char *id);
GF_HTML_Track *html_media_tracklist_get_track(GF_HTML_TrackList *tracklist, const char *id);
void gf_html_tracklist_del(GF_HTML_TrackList *tlist);

/*
 * HTML5 Tracks
 */
GF_HTML_Track *gf_html_media_track_new(GF_HTML_TrackType type, const char *mime, Bool enable_or_selected,
                                       const char *id, const char *kind, const char *label, const char *lang);
void gf_html_track_del(GF_HTML_Track *track);

/*
 * HTML5 Media Element
 */
GF_HTML_MediaElement *gf_html_media_element_new(GF_Node *media_node, GF_HTML_MediaController *mc);
void gf_html_media_element_del(GF_HTML_MediaElement *me);

void html_media_element_js_init(JSContext *c, JSObject *new_obj, GF_Node *n);

/*
 * HTML5 Media Controller
 */
GF_HTML_MediaController *gf_html_media_controller_new();
void gf_html_media_controller_del(GF_HTML_MediaController *mc);

/*
 * HTML5 Array Buffer
 */
GF_HTML_ArrayBuffer *gf_arraybuffer_new(char *data, u32 length);
JSObject *gf_arraybuffer_js_new(JSContext *c, char *data, u32 length, JSObject *parent);
void gf_arraybuffer_del(GF_HTML_ArrayBuffer *buffer, Bool del_js);

/*! @} */

#ifdef __cplusplus
}
#endif

#endif  // _GF_HTMLMEDIA_H_

/* [<][>][^][v][top][bottom][index][help] */