root/include/gpac/scene_manager.h

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

INCLUDED FROM


/*
 *                      GPAC - Multimedia Framework C SDK
 *
 *                      Authors: Jean Le Feuvre
 *                      Copyright (c) Telecom ParisTech 2000-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / Authoring Tools sub-project
 *
 *  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_SCENE_MANAGER_H_
#define _GF_SCENE_MANAGER_H_


#ifdef __cplusplus
extern "C" {
#endif


/*!
 *      \file <gpac/scene_manager.h>
 *      \brief Scene management for importing/encoding of BIFS, XMT, LASeR scenes
 */
        
/*!
 *      \addtogroup smgr Scene Manager
 *      \ingroup scene_grp
 *      \brief Scene management for importing/encoding of BIFS, XMT, LASeR scenes.
 *
 *This section documents the Scene manager used for importing/encoding of BIFS, XMT, LASeR scenes.
 *      @{
 */

#include <gpac/isomedia.h>
#include <gpac/mpeg4_odf.h>
#include <gpac/scenegraph_vrml.h>

/*
                Memory scene management

*/

/*NDT check - return 1 if node belongs to given NDT. Handles proto, and assumes undefined nodes
always belong to the desired NDT*/
Bool gf_node_in_table(GF_Node *node, u32 NDTType);

enum
{
        /*AU is RAP - random access indication - may be overriden by encoder*/
        GF_SM_AU_RAP = 1,
        /*AU will not be aggregated (only used by scene engine)*/
        GF_SM_AU_NOT_AGGREGATED = 1<<1,
        /*AU has been modified (only used by scene engine)*/
        GF_SM_AU_MODIFIED = 1<<2,
        /*AU is a carousel (only used by scene engine)*/
        GF_SM_AU_CAROUSEL = 1<<3
};

/*generic systems access unit context*/
typedef struct
{
        /*AU timing in TimeStampResolution*/
        u64 timing;
        /*timing in sec - used if timing isn't set*/
        Double timing_sec;
        /*opaque command list per stream type*/
        GF_List *commands;

        u32 flags;

        /*pointer to owner stream*/
        struct _stream_context *owner;
} GF_AUContext;

/*generic stream context*/
typedef struct _stream_context
{
        /*ESID of stream, or 0 if unknown in which case it is automatically updated at encode stage*/
        u16 ESID;
        /*stream name if any (XMT), NULL otherwise*/
        char *name;

        /*stream type - used as a hint, the encoder(s) may override it*/
        u8 streamType;
        u8 objectType;
        u32 timeScale;
        GF_List *AUs;

        /*last stream AU time, when playing the context directly*/
        u64 last_au_time;
        /*set if stream is part of root OD (playback only)*/
        Bool in_root_od;
        /*number of previous AUs (used in live scene encoder only)*/
        u32 current_au_count;
        char *dec_cfg;
        u32 dec_cfg_len;

        /*time offset when exporting (dumping), max AU time created when importing*/
        u64 imp_exp_time;

        u16 aggregate_on_esid;
        u32 carousel_period;
        Bool disable_aggregation;
} GF_StreamContext;

/*generic presentation context*/
typedef struct
{
        /*the one and only scene graph used by the scene manager.*/
        GF_SceneGraph *scene_graph;

        /*all systems streams used in presentation*/
        GF_List *streams;
        /*(initial) object descriptor if any - if not set the encoder will generate it*/
        GF_ObjectDescriptor *root_od;

        /*scene resolution*/
        u32 scene_width, scene_height;
        Bool is_pixel_metrics;

        /*BIFS encoding - these is needed for:
        - protos in protos which define subscene graph, hence seperate namespace, but are coded with the same IDs
        - route insertions which are not tracked by the scene graph
        we could do this by hand (counting protos & route insert) but let's be lazy
        */
        u32 max_node_id, max_route_id, max_proto_id;
} GF_SceneManager;

/*scene manager constructor - @scene_graph: scene graph used by the manager. */
GF_SceneManager *gf_sm_new(GF_SceneGraph *scene_graph);
/*scene manager destructor - does not destroy the attached scene graph*/
void gf_sm_del(GF_SceneManager *ctx);
/*retrive or create a stream context in the presentation context
WARNING: if a stream with the same streamType and no ESID already exists in the context,
it is assigned the requested ES_ID - this is needed to solve base layer*/
GF_StreamContext *gf_sm_stream_new(GF_SceneManager *ctx, u16 ES_ID, u8 streamType, u8 objectType);
/*removes and destroy stream context from presentation context*/
void gf_sm_stream_del(GF_SceneManager *ctx, GF_StreamContext *sc);
/*locate a stream based on its id*/
GF_StreamContext *gf_sm_stream_find(GF_SceneManager *ctx, u16 ES_ID);
/*create a new AU context in the given stream context*/
GF_AUContext *gf_sm_stream_au_new(GF_StreamContext *stream, u64 timing, Double time_ms, Bool isRap);

GF_MuxInfo *gf_sm_get_mux_info(GF_ESD *src);

/*reset the context:
- purge all access units on all streams
- destroy root OD
*/
void gf_sm_reset(GF_SceneManager *ctx);

/*applies all commands in all streams (only BIFS for now): the context manager will only have maximum one AU per
stream, this AU being a random access for the stream
if @ESID is set, aggregation is only performed on the given stream*/
GF_Err gf_sm_aggregate(GF_SceneManager *ctx, u16 ESID);

/*translates SRT/SUB (TTXT not supported) source into BIFS command stream source
        @src: GF_ESD of new stream (MUST be created before to store TS resolution)
        @mux: GF_MuxInfo of src stream - shall contain a valid file, and at least the textNode member set
*/
GF_Err gf_sm_import_bifs_subtitle(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux);


/*SWF to MPEG-4 flags*/
enum
{
        /*all data in dictionary is in first frame*/
        GF_SM_SWF_STATIC_DICT = 1,
        /*remove all text*/
        GF_SM_SWF_NO_TEXT = (1<<1),
        /*remove embedded fonts (force device font usage)*/
        GF_SM_SWF_NO_FONT = (1<<2),
        /*forces XCurve2D which supports quadratic bezier*/
        GF_SM_SWF_QUAD_CURVE = (1<<3),
        /*forces line remove*/
        GF_SM_SWF_NO_LINE = (1<<4),
        /*forces XLineProperties (supports scalable lines)*/
        GF_SM_SWF_SCALABLE_LINE = (1<<5),
        /*forces gradient remove (using center color) */
        GF_SM_SWF_NO_GRADIENT = (1<<6),
        /*use a dedicated BIFS stream to control display list. This allows positioning in the movie
        (jump to frame, etc..) as well as looping from inside the movie (set by default)*/
        GF_SM_SWF_SPLIT_TIMELINE = (1<<7),
        /*enable appearance reuse*/
        GF_SM_SWF_REUSE_APPEARANCE = (1<<9),
        /*enable IndexedCurve2D proto*/
        GF_SM_SWF_USE_IC2D = (1<<10),
        /*enable SVG output*/
        GF_SM_SWF_USE_SVG = (1<<11),
};

/*general loader flags*/
enum
{
        /*if set, always load MPEG-4 nodes, otherwise X3D versions are used for vrml/x3d*/
        GF_SM_LOAD_MPEG4_STRICT = 1,
        /*signal loading is done for playback:
                scrips will be queued in their parent command for later loading
                SFTime (MPEG-4 only) fields will be handled correctly when inserting/creating nodes based on AU timing
        */
        GF_SM_LOAD_FOR_PLAYBACK = 1<<1,

        /*special flag indicating that the context is already loaded & valid (eg no default stream creations & co)
        this is used when performing diff encoding (eg the file to load only has updates).
        When set, gf_sm_load_init will NOT attempt to parse first frame*/
        GF_SM_LOAD_CONTEXT_READY = 1<<2,

        /* in this mode, each root svg tag will be interpreted as a REPLACE SCENE */
        GF_SM_LOAD_CONTEXT_STREAMING = 1<<3,
        /*indicates that external resources in the content should be embedded as if possible*/
        GF_SM_LOAD_EMBEDS_RES = 1<<4,
};

/*loader type, usually detected based on file ext*/
typedef enum
{
        GF_SM_LOAD_BT = 1, /*BT loader*/
        GF_SM_LOAD_VRML, /*VRML97 loader*/
        GF_SM_LOAD_X3DV, /*X3D VRML loader*/
        GF_SM_LOAD_XMTA, /*XMT-A loader*/
        GF_SM_LOAD_X3D, /*X3D XML loader*/
        GF_SM_LOAD_SVG, /*SVG loader*/
        GF_SM_LOAD_XSR, /*LASeR+XML loader*/
        GF_SM_LOAD_DIMS, /*DIMS LASeR+XML loader*/
        GF_SM_LOAD_SWF, /*SWF->MPEG-4 converter*/
        GF_SM_LOAD_QT, /*MOV->MPEG-4 converter (only cubic QTVR for now)*/
        GF_SM_LOAD_MP4, /*MP4 memory loader*/
        GF_SM_LOAD_XBL
} GF_SceneManager_LoadType;

typedef struct __scene_loader GF_SceneLoader;

struct __scene_loader
{
        /*loader type, one of the above value. If not set, detected based on file extension*/
        GF_SceneManager_LoadType type;

        /*scene graph worked on - may be NULL if ctx is present*/
        GF_SceneGraph *scene_graph;

        struct _scene  *is;

        /*context manager to load (MUST BE RESETED BEFORE if needed) - may be NULL for loaders not using commands,
        in which case the graph will be directly updated*/
        GF_SceneManager *ctx;
        /*file to import except IsoMedia files*/
        const char *fileName;
        //original URL for the file or NULL if same as fileName
        const char *src_url;
#ifndef GPAC_DISABLE_ISOM
        /*IsoMedia file to import (we need to be able to load from an opened file for scene stats)*/
        GF_ISOFile *isom;
#endif
        /*swf import flags*/
        u32 swf_import_flags;
        /*swf flatten limit: angle limit below which 2 lines are considered as aligned,
        in which case the lines are merged as one. If 0, no flattening happens*/
        Float swf_flatten_limit;
        /*swf extraction path: if set, swf media (mp3, jpeg) are extracted to this path. If not set
        media are extracted to original file directory*/
        const char *localPath;

        /* carrying svgOutFile when the loader is used by a SceneDumper */
        const char *svgOutFile;

        /*loader flags*/
        u32 flags;

        u16 force_es_id;

        /*private to loader*/
        void *loader_priv;
        GF_Err (*process)(GF_SceneLoader *loader);
        void (*done)(GF_SceneLoader *loader);
        GF_Err (*parse_string)(GF_SceneLoader *loader, const char *str);
        GF_Err (*suspend)(GF_SceneLoader *loader, Bool suspend);
};

/*initializes the context loader - this will load any IOD and the first frame of the main scene*/
GF_Err gf_sm_load_init(GF_SceneLoader *load);
/*completely loads context*/
GF_Err gf_sm_load_run(GF_SceneLoader *load);
/*terminates the context loader*/
void gf_sm_load_done(GF_SceneLoader *load);
/*suspends/resume context loading*/
GF_Err gf_sm_load_suspend(GF_SceneLoader *load, Bool suspend);

/*parses memory scene (any textural format) into the context
!! THE LOADER TYPE MUST BE ASSIGNED (BT/WRL/XMT/X3D/SVG only) !!
The string MUST be at least 4 bytes long in order to detect BOM (unicode encoding).
The string can ba either UTF-8 or UTF-16 data
if clean_at_end is set, associated parser is destroyed. Otherwise, a call to gf_sm_load_done must be done
to clean ressources (needed for SAX progressive loading)
*/
GF_Err gf_sm_load_string(GF_SceneLoader *load, const char *str, Bool clean_at_end);

#ifndef GPAC_DISABLE_SCENE_ENCODER

/*encoding flags*/
enum
{
        /*if flag set, DEF names are encoded*/
        GF_SM_ENCODE_USE_NAMES =        1,
        /*if flag set, RAP are generated inband rather than as redundant samples*/
        GF_SM_ENCODE_RAP_INBAND = 2,
        /*if flag set, RAP are generated inband rather than as sync shadow samples*/
        GF_SM_ENCODE_RAP_SHADOW = 4,
};

typedef struct
{
        /*encoding flags*/
        u32 flags;
        /*delay between 2 RAP in ms. If 0 RAPs are not forced - BIFS and LASeR only for now*/
        u32 rap_freq;
        /*if set, any unknown stream in the scene will be looked for in @mediaSource (MP4 only)*/
        char *mediaSource;
        /*LASeR */
        /*resolution*/
        s32 resolution;
        /*coordBits, scaleBits*/
        u32 coord_bits, scale_bits;
        /*auto quantification type:
                0: none
                1: LASeR
                2: BIFS
        */
        u32 auto_quant;

        const char *src_url;
} GF_SMEncodeOptions;

/*
encodes scene context into @mp4.
if @log is set, generates BIFS encoder log file
*/
GF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOptions *opt);

#endif /*GPAC_DISABLE_SCENE_ENCODER*/


/*Dumping tools*/
#ifndef GPAC_DISABLE_SCENE_DUMP

/*scene dump mode*/
typedef enum
{
        /*BT*/
        GF_SM_DUMP_BT = 0,
        /*XMT-A*/
        GF_SM_DUMP_XMTA,
        /*VRML Text (WRL)*/
        GF_SM_DUMP_VRML,
        /*X3D Text (x3dv)*/
        GF_SM_DUMP_X3D_VRML,
        /*X3D XML*/
        GF_SM_DUMP_X3D_XML,
        /*LASeR XML*/
        GF_SM_DUMP_LASER,
        /*SVG dump (only dumps svg root of the first LASeR unit*/
        GF_SM_DUMP_SVG,
        /*blind XML dump*/
        GF_SM_DUMP_XML,
        /*automatic selection of MPEG4 vs X3D, text mode*/
        GF_SM_DUMP_AUTO_TXT,
        /*automatic selection of MPEG4 vs X3D, xml mode*/
        GF_SM_DUMP_AUTO_XML,
        /* disables dumping the scene */
        GF_SM_DUMP_NONE
} GF_SceneDumpFormat;

/*dumps scene context to a given format
@rad_name: file name & loc without extension - if NULL dump will happen in stdout
@is_final_name: if set, no extension is added to the filename
@dump_mode: one of the above*/
GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, Bool is_final_name, GF_SceneDumpFormat dump_mode);

typedef struct _scenedump GF_SceneDumper;

/*create a scene dumper
@graph: scene graph being dumped
@rad_name: file radical (NULL for stdout) - if not NULL MUST BE GF_MAX_PATH length
@is_final_name: if set, rad_name is the final name (no extension added)
@indent_char: indent format
@dump_mode: if set, dumps in XML format otherwise regular text
returns NULL if can't create a file
*/
GF_SceneDumper *gf_sm_dumper_new(GF_SceneGraph *graph, char *_rad_name, Bool is_final_name, char indent_char, GF_SceneDumpFormat dump_mode);
void gf_sm_dumper_set_extra_graph(GF_SceneDumper *sdump, GF_SceneGraph *extra);
void gf_sm_dumper_del(GF_SceneDumper *bd);

/*gets a pointer to the filename (rad+ext) of the dumped file
returns null if no file has been dumped
*/
char *gf_sm_dump_get_name(GF_SceneDumper *bd);

/*dumps commands list
@indent: indent to use
@skip_replace_scene_header: if set and dumping in BT mode, the initial REPLACE SCENE header is skipped
*/
GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 indent, Bool skip_first_replace);

/*dumps complete graph -
@skip_proto: proto declarations are skipped
@skip_routes: routes are not dumped
*/
GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes);

#endif /*GPAC_DISABLE_SCENE_DUMP*/

#ifndef GPAC_DISABLE_SCENE_STATS

/*stat object - to refine :)*/

/*store nodes or proto stats*/
typedef struct
{
        /*node type or protoID*/
        u32 tag;
        const char *name;
        /*number of created nodes*/
        u32 nb_created;
        /*number of used nodes*/
        u32 nb_used;
        /*number of used nodes*/
        u32 nb_del;
} GF_NodeStats;

typedef struct _scenestat
{
        GF_List *node_stats;

        GF_List *proto_stats;

        /*ranges of all SFVec2fs for points only (MFVec2fs)*/
        SFVec2f max_2d, min_2d;
        /* resolution of 2D points (nb bits for integer part and decimal part)*/
        u32 int_res_2d, frac_res_2d;
        /* resolution of scale coefficient (nb bits for integer part)*/
        u32 scale_int_res_2d, scale_frac_res_2d;

        Fixed max_fixed, min_fixed;

        /*number of parsed 2D points*/
        u32 count_2d;
        /*number of deleted 2D points*/
        u32 rem_2d;

        /*ranges of all SFVec3fs for points only (MFVec3fs)*/
        SFVec3f max_3d, min_3d;
        u32 count_3d;
        /*number of deleted 3D points*/
        u32 rem_3d;

        u32 count_float, rem_float;
        u32 count_color, rem_color;
        /*all SFVec2f other than MFVec2fs elements*/
        u32 count_2f;
        /*all SFVec3f other than MFVec3fs elements*/
        u32 count_3f;

        u32 nb_svg_attributes;

        GF_StreamContext *base_layer;
} GF_SceneStatistics;

typedef struct _statman GF_StatManager;

/*creates new stat handler*/
GF_StatManager *gf_sm_stats_new();
/*deletes stat handler*/
void gf_sm_stats_del(GF_StatManager *stat);
/*reset statistics*/
void gf_sm_stats_reset(GF_StatManager *stat);

/*get statistics - do NOT modify the returned structure*/
GF_SceneStatistics *gf_sm_stats_get(GF_StatManager *stat);

/*produces stat report for a complete graph*/
GF_Err gf_sm_stats_for_graph(GF_StatManager *stat, GF_SceneGraph *sg);

/*produces stat report for the full scene*/
GF_Err gf_sm_stats_for_scene(GF_StatManager *stat, GF_SceneManager *sm);

/*produces stat report for the given command*/
GF_Err gf_sm_stats_for_command(GF_StatManager *stat, GF_Command *com);

#endif /*GPAC_DISABLE_SCENE_STATS*/

/*! @} */

#ifdef __cplusplus
}
#endif


#endif  /*_GF_SCENE_MANAGER_H_*/


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