Imported Upstream version 0.5.0+svn4231~dfsg0
authorAlessio Treglia <alessio@debian.org>
Fri, 16 Nov 2012 12:06:41 +0000 (12:06 +0000)
committerAlessio Treglia <alessio@debian.org>
Fri, 16 Nov 2012 12:06:41 +0000 (12:06 +0000)
640 files changed:
Makefile
applications/Makefile
applications/generators/MPEG4/main.c
applications/generators/SVG/html.c
applications/generators/SVG/laser.c
applications/generators/SVG/main.c
applications/generators/SVG/svggen.h
applications/generators/SVG/v1.c
applications/generators/SVG/v2.c
applications/generators/SVG/v3.c
applications/generators/X3D/main.c
applications/m3u82mpd/main.c
applications/mp42avi/Makefile
applications/mp42avi/main.c
applications/mp42ts/Makefile
applications/mp42ts/main.c
applications/mp42ts/mp42ts.h
applications/mp4box/Makefile
applications/mp4box/filedump.c
applications/mp4box/fileimport.c
applications/mp4box/live.c
applications/mp4box/main.c
applications/mp4client/Makefile
applications/mp4client/extract.c
applications/mp4client/main.c
applications/testapps/broadcaster/Makefile
applications/testapps/dmbrs/main.c
applications/testapps/loadcompare/Makefile
applications/testapps/loadcompare/loadcompare.c
applications/testapps/mpedemux/Makefile
applications/testapps/mpedemux/main.c
applications/testapps/svg2bifs/main.c
applications/ts2hds/Makefile [new file with mode: 0644]
applications/ts2hds/f4m.c [new file with mode: 0644]
applications/ts2hds/f4v.c [new file with mode: 0644]
applications/ts2hds/main.c [new file with mode: 0644]
applications/ts2hds/ts2hds.h [new file with mode: 0644]
applications/udptsseg/Makefile
applications/udptsseg/main.c
bin/smartphone 2003 (armv4)/release/install/archive.bat
bin/smartphone 2003 (armv4)/release/install/build_installer.bat
bin/smartphone 2003 (armv4)/release/install/gpac.inf
bin/smartphone 2003 (armv4)/release/install/readme.txt
bin/win32/release/nsis_install/gpac_installer.nsi
configure
doc/configuration.html
extra_lib/include/avcap/Connector.h
extra_lib/include/avcap/FormatManager.h
extra_lib/include/avcap/linux/V4L1_Connector.h
extra_lib/include/avcap/linux/V4L1_ConnectorManager.h
extra_lib/include/avcap/linux/V4L2_Connector.h
extra_lib/include/avcap/linux/V4L2_ControlBase.h
extra_lib/include/avcap/linux/V4L2_Tuner.h
extra_lib/include/libavcodec/avcodec.h
extra_lib/include/libavcodec/avfft.h [new file with mode: 0644]
extra_lib/include/libavcodec/dxva2.h [new file with mode: 0644]
extra_lib/include/libavcodec/old_codec_ids.h [new file with mode: 0644]
extra_lib/include/libavcodec/vaapi.h [new file with mode: 0644]
extra_lib/include/libavcodec/vda.h [new file with mode: 0644]
extra_lib/include/libavcodec/vdpau.h [new file with mode: 0644]
extra_lib/include/libavcodec/version.h [new file with mode: 0644]
extra_lib/include/libavcodec/xvmc.h [new file with mode: 0644]
extra_lib/include/libavformat/avformat.h
extra_lib/include/libavformat/avio.h
extra_lib/include/libavformat/version.h [new file with mode: 0644]
extra_lib/include/libavutil/adler32.h [new file with mode: 0644]
extra_lib/include/libavutil/aes.h [new file with mode: 0644]
extra_lib/include/libavutil/attributes.h [new file with mode: 0644]
extra_lib/include/libavutil/audio_fifo.h [new file with mode: 0644]
extra_lib/include/libavutil/audioconvert.h [new file with mode: 0644]
extra_lib/include/libavutil/avassert.h [new file with mode: 0644]
extra_lib/include/libavutil/avconfig.h [new file with mode: 0644]
extra_lib/include/libavutil/avstring.h [new file with mode: 0644]
extra_lib/include/libavutil/avutil.h
extra_lib/include/libavutil/base64.h [new file with mode: 0644]
extra_lib/include/libavutil/blowfish.h [new file with mode: 0644]
extra_lib/include/libavutil/bprint.h [new file with mode: 0644]
extra_lib/include/libavutil/bswap.h [new file with mode: 0644]
extra_lib/include/libavutil/common.h
extra_lib/include/libavutil/cpu.h [new file with mode: 0644]
extra_lib/include/libavutil/crc.h [new file with mode: 0644]
extra_lib/include/libavutil/dict.h [new file with mode: 0644]
extra_lib/include/libavutil/error.h [new file with mode: 0644]
extra_lib/include/libavutil/eval.h [new file with mode: 0644]
extra_lib/include/libavutil/fifo.h [new file with mode: 0644]
extra_lib/include/libavutil/file.h [new file with mode: 0644]
extra_lib/include/libavutil/imgutils.h [new file with mode: 0644]
extra_lib/include/libavutil/intfloat.h [new file with mode: 0644]
extra_lib/include/libavutil/intfloat_readwrite.h
extra_lib/include/libavutil/intreadwrite.h [new file with mode: 0644]
extra_lib/include/libavutil/lfg.h [new file with mode: 0644]
extra_lib/include/libavutil/log.h
extra_lib/include/libavutil/lzo.h [new file with mode: 0644]
extra_lib/include/libavutil/mathematics.h
extra_lib/include/libavutil/md5.h [new file with mode: 0644]
extra_lib/include/libavutil/mem.h
extra_lib/include/libavutil/old_pix_fmts.h [new file with mode: 0644]
extra_lib/include/libavutil/opt.h [new file with mode: 0644]
extra_lib/include/libavutil/parseutils.h [new file with mode: 0644]
extra_lib/include/libavutil/pixdesc.h [new file with mode: 0644]
extra_lib/include/libavutil/pixfmt.h
extra_lib/include/libavutil/random_seed.h [new file with mode: 0644]
extra_lib/include/libavutil/rational.h
extra_lib/include/libavutil/samplefmt.h [new file with mode: 0644]
extra_lib/include/libavutil/sha.h [new file with mode: 0644]
extra_lib/include/libavutil/time.h [new file with mode: 0644]
extra_lib/include/libavutil/timecode.h [new file with mode: 0644]
extra_lib/include/libavutil/timestamp.h [new file with mode: 0644]
extra_lib/include/libavutil/version.h [new file with mode: 0644]
extra_lib/include/libavutil/xtea.h [new file with mode: 0644]
extra_lib/include/libswscale/swscale.h
extra_lib/include/libswscale/version.h [new file with mode: 0644]
extra_lib/include/platinum/NptStack.h
generate_installer.bat
include/gpac/avparse.h
include/gpac/base_coding.h
include/gpac/bifs.h
include/gpac/bitstream.h
include/gpac/cache.h
include/gpac/color.h
include/gpac/compositor.h
include/gpac/config_file.h
include/gpac/configuration.h
include/gpac/constants.h
include/gpac/crypt.h
include/gpac/dash.h [new file with mode: 0644]
include/gpac/download.h
include/gpac/dsmcc.h
include/gpac/dvb_mpe.h
include/gpac/esi.h
include/gpac/events.h
include/gpac/events_constants.h
include/gpac/filestreamer.h
include/gpac/ietf.h
include/gpac/internal/bifs_dev.h
include/gpac/internal/bifs_tables.h
include/gpac/internal/camera.h
include/gpac/internal/compositor_dev.h
include/gpac/internal/crypt_dev.h
include/gpac/internal/dvb_mpe_dev.h
include/gpac/internal/ietf_dev.h
include/gpac/internal/isomedia_dev.h
include/gpac/internal/laser_dev.h
include/gpac/internal/m3u8.h
include/gpac/internal/media_dev.h
include/gpac/internal/mesh.h
include/gpac/internal/mpd.h
include/gpac/internal/odf_dev.h
include/gpac/internal/odf_parse_common.h
include/gpac/internal/scenegraph_dev.h
include/gpac/internal/smjs_api.h
include/gpac/internal/swf_dev.h
include/gpac/internal/terminal_dev.h
include/gpac/ismacryp.h
include/gpac/iso639.h
include/gpac/isomedia.h
include/gpac/laser.h
include/gpac/list.h
include/gpac/math.h
include/gpac/media_tools.h
include/gpac/mediaobject.h
include/gpac/module.h
include/gpac/modules/audio_out.h
include/gpac/modules/codec.h
include/gpac/modules/font.h
include/gpac/modules/hardcoded_proto.h
include/gpac/modules/ipmp.h
include/gpac/modules/js_usr.h
include/gpac/modules/raster2d.h
include/gpac/modules/service.h
include/gpac/modules/term_ext.h
include/gpac/modules/video_out.h
include/gpac/mpeg4_odf.h
include/gpac/mpegts.h
include/gpac/network.h
include/gpac/nodes_mpeg4.h
include/gpac/nodes_svg.h
include/gpac/nodes_x3d.h
include/gpac/nodes_xbl.h
include/gpac/options.h
include/gpac/path2d.h
include/gpac/ringbuffer.h
include/gpac/rtp_streamer.h
include/gpac/scene_engine.h
include/gpac/scene_manager.h
include/gpac/scenegraph.h
include/gpac/scenegraph_svg.h
include/gpac/scenegraph_vrml.h
include/gpac/setup.h
include/gpac/svg_types.h
include/gpac/sync_layer.h
include/gpac/term_info.h
include/gpac/terminal.h
include/gpac/thread.h
include/gpac/token.h
include/gpac/tools.h
include/gpac/unicode.h
include/gpac/user.h
include/gpac/utf.h
include/gpac/version.h [new file with mode: 0644]
include/gpac/xml.h
include/win32/inttypes.h
mkdmg.sh
modules/Makefile
modules/aac_in/Makefile
modules/aac_in/aac_in.c
modules/aac_in/faad_dec.c
modules/ac3_in/Makefile
modules/ac3_in/ac3_in.c
modules/ac3_in/liba52_dec.c
modules/alsa/Makefile
modules/alsa/alsa.c
modules/amr_dec/Makefile
modules/amr_dec/amr_dec.c
modules/amr_dec/amr_in.c
modules/amr_float_dec/Makefile
modules/amr_float_dec/amr_float_dec.c
modules/audio_filter/Makefile
modules/audio_filter/audio_filter.c
modules/avcap/Makefile
modules/avcap/avcap.cpp
modules/bifs_dec/Makefile
modules/bifs_dec/bifs_dec.c
modules/ctx_load/Makefile
modules/ctx_load/ctx_load.c
modules/demo_is/Makefile
modules/demo_is/demo_is.c
modules/directfb_out/Makefile
modules/directfb_out/directfb_out.c
modules/directfb_out/directfb_out.h
modules/directfb_out/directfb_wrapper.c
modules/droid_audio/droidaudio.c
modules/droid_audio/javaenv.c
modules/droid_audio/javaenv.h
modules/droid_cam/droid_cam.c
modules/droid_mpegv/droid_mpegv.c
modules/droid_out/droid_vout-bitmap.c
modules/droid_out/droid_vout.c
modules/dummy_in/Makefile
modules/dummy_in/dummy_in.c
modules/dx_hw/Makefile
modules/dx_hw/copy_pixels.c
modules/dx_hw/dx_2d.c
modules/dx_hw/dx_audio.c
modules/dx_hw/dx_hw.h
modules/dx_hw/dx_video.c
modules/dx_hw/dx_window.c
modules/epoc_hw/epoc_aout.cpp
modules/epoc_hw/epoc_codec.cpp
modules/epoc_hw/epoc_vout.cpp
modules/ffmpeg_in/Makefile
modules/ffmpeg_in/ffmpeg_decode.c
modules/ffmpeg_in/ffmpeg_demux.c
modules/ffmpeg_in/ffmpeg_in.h
modules/ffmpeg_in/ffmpeg_load.c
modules/freenect/Makefile
modules/freenect/freenect.c
modules/ft_font/Makefile
modules/ft_font/ft_font.c
modules/ft_font/ft_font.h
modules/gapi/gapi.cpp
modules/gapi/gapi.h
modules/gdip_raster/gdip_font.cpp
modules/gdip_raster/gdip_grad.cpp
modules/gdip_raster/gdip_priv.h
modules/gdip_raster/gdip_rend.cpp
modules/gdip_raster/gdip_texture.cpp
modules/gpac_js/Makefile
modules/gpac_js/gpac_js.c
modules/hyb_in/Makefile
modules/img_in/Makefile
modules/img_in/bmp_dec.c
modules/img_in/img_dec.c
modules/img_in/img_in.c
modules/img_in/img_in.h
modules/img_in/jp2_dec.c
modules/img_in/jpeg_dec.c
modules/img_in/png_dec.c
modules/ismacryp/Makefile
modules/ismacryp/ismacryp.c
modules/isom_in/Makefile
modules/isom_in/cache.c
modules/isom_in/isom_in.h
modules/isom_in/load.c
modules/isom_in/read.c
modules/isom_in/read_ch.c
modules/jack/Makefile
modules/jack/jack.c
modules/laser_dec/Makefile
modules/laser_dec/laser_dec.c
modules/libplayer/Makefile
modules/libplayer/libplayer.c
modules/modules_export.cpp
modules/mp3_in/Makefile
modules/mp3_in/mad_dec.c
modules/mp3_in/mp3_in.c
modules/mpd_in/Makefile
modules/mpd_in/mpd_in.c
modules/mpegts_in/Makefile
modules/mpegts_in/mpegts_in.c
modules/odf_dec/Makefile
modules/odf_dec/odf_dec.c
modules/ogg/Makefile
modules/ogg/ogg_in.c
modules/ogg/ogg_in.h
modules/ogg/ogg_load.c
modules/ogg/theora_dec.c
modules/ogg/vorbis_dec.c
modules/opencv_is/Makefile
modules/opencv_is/opencv_is.c
modules/opensvc_dec/Makefile
modules/opensvc_dec/opensvc_dec.c
modules/osd/Makefile
modules/osd/osd.c
modules/oss_audio/Makefile
modules/oss_audio/oss.c
modules/platinum/GPACFileMediaServer.cpp
modules/platinum/GPACFileMediaServer.h
modules/platinum/GPACMediaController.cpp
modules/platinum/GPACMediaController.h
modules/platinum/GPACMediaRenderer.cpp
modules/platinum/GPACMediaRenderer.h
modules/platinum/GPACPlatinum.cpp
modules/platinum/GPACPlatinum.h
modules/platinum/GenericDevice.cpp
modules/platinum/GenericDevice.h
modules/platinum/Makefile
modules/pulseaudio/Makefile
modules/pulseaudio/pulseaudio.c
modules/raw_out/Makefile
modules/raw_out/raw_video.c
modules/redirect_av/Makefile
modules/redirect_av/ffmpeg_ts_muxer.c
modules/redirect_av/gpac_ts_muxer.c
modules/redirect_av/redirect_av.c
modules/rtp_in/Makefile
modules/rtp_in/rtp_in.c
modules/rtp_in/rtp_in.h
modules/rtp_in/rtp_session.c
modules/rtp_in/rtp_signaling.c
modules/rtp_in/rtp_stream.c
modules/rtp_in/sdp_fetch.c
modules/rtp_in/sdp_load.c
modules/rvc_dec/Makefile
modules/rvc_dec/rvc_dec.c
modules/saf_in/Makefile
modules/saf_in/saf_in.c
modules/sdl_out/Makefile
modules/sdl_out/audio.c
modules/sdl_out/cursors.c
modules/sdl_out/sdl_out.c
modules/sdl_out/sdl_out.h
modules/sdl_out/video.c
modules/sdl_out/video2d.c
modules/soft_raster/Makefile
modules/soft_raster/rast_soft.h
modules/soft_raster/raster_565.c
modules/soft_raster/raster_argb.c
modules/soft_raster/raster_load.c
modules/soft_raster/raster_rgb.c
modules/soft_raster/stencil.c
modules/soft_raster/surface.c
modules/svg_in/Makefile
modules/svg_in/svg_in.c
modules/timedtext/Makefile
modules/timedtext/timedtext_dec.c
modules/timedtext/timedtext_in.c
modules/ui_rec/Makefile
modules/ui_rec/ui_rec.c
modules/validator/validator.c
modules/wav_out/Makefile
modules/wav_out/wav_out.c
modules/widgetman/Makefile
modules/widgetman/unzip.c
modules/widgetman/wgt_load.c
modules/widgetman/widget.c
modules/widgetman/widgetman.c
modules/widgetman/widgetman.h
modules/wiiis/Makefile
modules/wiiis/wiiis.c
modules/x11_out/Makefile
modules/x11_out/x11_out.c
modules/x11_out/x11_out.h
modules/xvid_dec/Makefile
modules/xvid_dec/xvid_dec.c
modules/xvid_dec/xvid_dec_wce.cpp
regression_tests/bifs/bifs-script-timestamp.bt
src/Makefile
src/bifs/arith_decoder.c
src/bifs/bifs_codec.c
src/bifs/bifs_node_tables.c
src/bifs/com_dec.c
src/bifs/com_enc.c
src/bifs/conditional.c
src/bifs/field_decode.c
src/bifs/field_encode.c
src/bifs/memory_decoder.c
src/bifs/predictive_mffield.c
src/bifs/quant.h
src/bifs/quantize.c
src/bifs/script.h
src/bifs/script_dec.c
src/bifs/script_enc.c
src/bifs/unquantize.c
src/compositor/audio_input.c
src/compositor/audio_mixer.c
src/compositor/audio_render.c
src/compositor/bindable.c
src/compositor/camera.c
src/compositor/compositor.c
src/compositor/compositor_2d.c
src/compositor/compositor_3d.c
src/compositor/compositor_node_init.c
src/compositor/drawable.c
src/compositor/drawable.h
src/compositor/events.c
src/compositor/font_engine.c
src/compositor/gl_inc.h
src/compositor/hardcoded_protos.c
src/compositor/hc_flash_shape.c
src/compositor/mesh.c
src/compositor/mesh_collide.c
src/compositor/mesh_tesselate.c
src/compositor/mpeg4_animstream.c
src/compositor/mpeg4_audio.c
src/compositor/mpeg4_background.c
src/compositor/mpeg4_background2d.c
src/compositor/mpeg4_bitmap.c
src/compositor/mpeg4_composite.c
src/compositor/mpeg4_form.c
src/compositor/mpeg4_geometry_2d.c
src/compositor/mpeg4_geometry_3d.c
src/compositor/mpeg4_geometry_ifs2d.c
src/compositor/mpeg4_geometry_ils2d.c
src/compositor/mpeg4_gradients.c
src/compositor/mpeg4_grouping.c
src/compositor/mpeg4_grouping.h
src/compositor/mpeg4_grouping_2d.c
src/compositor/mpeg4_grouping_3d.c
src/compositor/mpeg4_layer_2d.c
src/compositor/mpeg4_layer_3d.c
src/compositor/mpeg4_layout.c
src/compositor/mpeg4_lighting.c
src/compositor/mpeg4_path_layout.c
src/compositor/mpeg4_sensors.c
src/compositor/mpeg4_sound.c
src/compositor/mpeg4_text.c
src/compositor/mpeg4_textures.c
src/compositor/mpeg4_timesensor.c
src/compositor/mpeg4_viewport.c
src/compositor/navigate.c
src/compositor/nodes_stacks.h
src/compositor/offscreen_cache.c
src/compositor/offscreen_cache.h
src/compositor/svg_base.c
src/compositor/svg_filters.c
src/compositor/svg_font.c
src/compositor/svg_geometry.c
src/compositor/svg_grouping.c
src/compositor/svg_media.c
src/compositor/svg_paint_servers.c
src/compositor/svg_text.c
src/compositor/texturing.c
src/compositor/texturing.h
src/compositor/texturing_gl.c
src/compositor/visual_manager.c
src/compositor/visual_manager.h
src/compositor/visual_manager_2d.c
src/compositor/visual_manager_2d.h
src/compositor/visual_manager_2d_draw.c
src/compositor/visual_manager_3d.c
src/compositor/visual_manager_3d.h
src/compositor/visual_manager_3d_gl.c
src/compositor/x3d_geometry.c
src/export.cpp
src/ietf/rtcp.c
src/ietf/rtp.c
src/ietf/rtp_depacketizer.c
src/ietf/rtp_packetizer.c
src/ietf/rtp_pck_3gpp.c
src/ietf/rtp_pck_mpeg12.c
src/ietf/rtp_pck_mpeg4.c
src/ietf/rtp_streamer.c
src/ietf/rtsp_command.c
src/ietf/rtsp_common.c
src/ietf/rtsp_response.c
src/ietf/rtsp_session.c
src/ietf/sdp.c
src/isomedia/avc_ext.c
src/isomedia/box_code_3gpp.c
src/isomedia/box_code_adobe.c [new file with mode: 0644]
src/isomedia/box_code_apple.c
src/isomedia/box_code_base.c
src/isomedia/box_code_drm.c [new file with mode: 0644]
src/isomedia/box_code_isma.c [deleted file]
src/isomedia/box_code_meta.c
src/isomedia/box_dump.c
src/isomedia/box_funcs.c
src/isomedia/data_map.c
src/isomedia/drm_sample.c [new file with mode: 0644]
src/isomedia/generic_subtitle.c [new file with mode: 0644]
src/isomedia/hint_track.c
src/isomedia/hinting.c
src/isomedia/isma_sample.c [deleted file]
src/isomedia/isom_intern.c
src/isomedia/isom_read.c
src/isomedia/isom_store.c
src/isomedia/isom_write.c
src/isomedia/media.c
src/isomedia/media_odf.c
src/isomedia/meta.c
src/isomedia/movie_fragments.c
src/isomedia/sample_descs.c
src/isomedia/stbl_read.c
src/isomedia/stbl_write.c
src/isomedia/track.c
src/isomedia/tx3g.c
src/laser/lsr_dec.c
src/laser/lsr_enc.c
src/laser/lsr_tables.c
src/mcrypt/des.c
src/mcrypt/g_crypt.c
src/mcrypt/tripledes.c
src/media_tools/ait.c
src/media_tools/av_parsers.c
src/media_tools/dash_client.c [new file with mode: 0644]
src/media_tools/dash_segmenter.c [new file with mode: 0644]
src/media_tools/dsmcc.c
src/media_tools/dvb_mpe.c
src/media_tools/filestreamer.c
src/media_tools/img.c
src/media_tools/ismacryp.c
src/media_tools/isom_hinter.c
src/media_tools/isom_tools.c
src/media_tools/m2ts_mux.c
src/media_tools/m3u8.c
src/media_tools/media_export.c
src/media_tools/media_import.c
src/media_tools/mpd.c
src/media_tools/mpeg2_ps.c
src/media_tools/mpegts.c
src/media_tools/reedsolomon.c
src/media_tools/saf.c
src/media_tools/text_import.c
src/odf/desc_private.c
src/odf/descriptors.c
src/odf/ipmpx_code.c
src/odf/ipmpx_dump.c
src/odf/ipmpx_parse.c
src/odf/oci_codec.c
src/odf/odf_code.c
src/odf/odf_codec.c
src/odf/odf_command.c
src/odf/odf_dump.c
src/odf/odf_parse.c
src/odf/qos.c
src/odf/slc.c
src/scene_manager/encode_isom.c
src/scene_manager/loader_bt.c
src/scene_manager/loader_isom.c
src/scene_manager/loader_qt.c
src/scene_manager/loader_svg.c
src/scene_manager/loader_xmt.c
src/scene_manager/scene_dump.c
src/scene_manager/scene_engine.c
src/scene_manager/scene_manager.c
src/scene_manager/scene_stats.c
src/scene_manager/swf_bifs.c
src/scene_manager/swf_parse.c
src/scene_manager/swf_svg.c [new file with mode: 0644]
src/scene_manager/text_to_bifs.c
src/scenegraph/base_scenegraph.c
src/scenegraph/commands.c
src/scenegraph/dom_events.c
src/scenegraph/dom_smjs.c
src/scenegraph/mpeg4_animators.c
src/scenegraph/mpeg4_nodes.c
src/scenegraph/mpeg4_valuator.c
src/scenegraph/smil_anim.c
src/scenegraph/smil_timing.c
src/scenegraph/svg_attributes.c
src/scenegraph/svg_properties.c
src/scenegraph/svg_smjs.c
src/scenegraph/svg_types.c
src/scenegraph/vrml_interpolators.c
src/scenegraph/vrml_proto.c
src/scenegraph/vrml_route.c
src/scenegraph/vrml_script.c
src/scenegraph/vrml_smjs.c
src/scenegraph/vrml_tools.c
src/scenegraph/x3d_nodes.c
src/scenegraph/xbl_process.c
src/scenegraph/xml_ns.c
src/terminal/channel.c
src/terminal/clock.c
src/terminal/decoder.c
src/terminal/input_sensor.c
src/terminal/input_sensor.h
src/terminal/media_control.c
src/terminal/media_control.h
src/terminal/media_manager.c
src/terminal/media_memory.c
src/terminal/media_memory.h
src/terminal/media_object.c
src/terminal/media_sensor.c
src/terminal/mpeg4_inline.c
src/terminal/network_service.c
src/terminal/object_browser.c
src/terminal/object_manager.c
src/terminal/scene.c
src/terminal/svg_external.c
src/terminal/term_node_init.c
src/terminal/terminal.c
src/utils/alloc.c
src/utils/base_encoding.c
src/utils/bitstream.c
src/utils/cache.c
src/utils/color.c
src/utils/configfile.c
src/utils/downloader.c
src/utils/error.c
src/utils/list.c
src/utils/math.c
src/utils/module.c
src/utils/module_wrap.h
src/utils/os_config_init.c
src/utils/os_divers.c
src/utils/os_module.c
src/utils/os_net.c
src/utils/os_thread.c
src/utils/path2d.c
src/utils/ringbuffer.c
src/utils/symbian_net.cpp
src/utils/symbian_os.cpp
src/utils/token.c
src/utils/uni_bidi.c
src/utils/url.c
src/utils/utf.c
src/utils/xml_parser.c
version.bat

index 13b25331ee57cbe29089b1778dd29cec1e60df40..a3bd4b4ba379934e6bb3755ab265ab3a0ef0f5b1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ all:  version
        $(MAKE) -C modules all
 
 version:
-       @if [ -d ".svn" ]; then if which svnversion >/dev/null; then echo "#define GPAC_SVN_REVISION    \"$(shell svnversion $(SRC_PATH) )\"" > $(SRC_PATH)/include/gpac/version.h ; else  echo "No SVN Version found"; fi; fi
+       @if [ -d ".svn" ]; then if which svnversion >/dev/null; then echo "#define GPAC_SVN_REVISION    \"$(shell svnversion $(SRC_PATH) )\"" > $(SRC_PATH)/include/gpac/revision.h ; else  echo "No SVN Version found"; fi; fi
 
 lib:   version
        $(MAKE) -C src all
@@ -47,7 +47,7 @@ distclean:
 dep:   depend
 
 # tar release (use 'make -k tar' on a checkouted tree)
-FILE=gpac-$(shell grep "\#define GPAC_VERSION " include/gpac/tools.h | \
+FILE=gpac-$(shell grep "\#define GPAC_VERSION " include/gpac/version.h | \
                     cut -d "\"" -f 2 )
 
 tar:
@@ -160,8 +160,9 @@ deb:
        sed -i "s/.DEV/.DEV-r`svnversion \"$(SRC_PATH)\"`/" debian/changelog
        fakeroot debian/rules configure
        fakeroot debian/rules binary
+       rm -rf debian/
        svn cleanup
-       svn revert debian/changelog
+       svn up
 endif
 
 help:
@@ -184,7 +185,7 @@ ifeq ($(CONFIG_DARWIN),yes)
        @echo "dmg: creates DMG package file for OSX"
 endif
 ifeq ($(CONFIG_LINUX),yes)
-        @echo "dmg: creates DEB package file for debian based systems"
+        @echo "deb: creates DEB package file for debian based systems"
 endif
        @echo 
        @echo "install-lib: install gpac library (dyn and static) and headers <gpac/*.h>, <gpac/modules/*.h> and <gpac/internal/*.h>"
index 16b0b7a024697635e964ca0fefc923e0d68e1e15..b2511e9b64ccd200e6caf09d145a3bf3aa51b18b 100644 (file)
@@ -8,7 +8,7 @@ endif
 
 ifeq ($(DISABLE_ISOFF), no)
 APPDIRS+=mp4box
-ifeq ($(DISABLE_M2TS), no)
+ifeq ($(DISABLE_M2TS_MUX), no)
 APPDIRS+=mp42ts
 endif
 endif
index 980ec6f062d24108ede0b8f48953921a255c0cd1..c940f066eb4f9e0c5fb914f1c3d74fdcc18737cc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG4 Scene Graph Generator sub-project
@@ -35,8 +36,8 @@
 #include <time.h>
 
 
-#define COPYRIGHT_SCENE "/*\n *                        GPAC - Multimedia Framework C SDK\n *\n *                       Copyright (c) Jean Le Feuvre 2000-2005\n *                                      All rights reserved\n *\n *  This file is part of GPAC / Scene Graph sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.       \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
-#define COPYRIGHT_BIFS "/*\n *                 GPAC - Multimedia Framework C SDK\n *\n *                       Copyright (c) Jean Le Feuvre 2000-2005\n *                                      All rights reserved\n *\n *  This file is part of GPAC / BIFS codec sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.        \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
+#define COPYRIGHT_SCENE "/*\n *                        GPAC - Multimedia Framework C SDK\n *\n *                       Authors: Jean Le Feuvre\n *                     Copyright (c) Telecom ParisTech 2000-2012\n *                                   All rights reserved\n *\n *  This file is part of GPAC / Scene Graph sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.       \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
+#define COPYRIGHT_BIFS "/*\n *                 GPAC - Multimedia Framework C SDK\n *\n *                       Authors: Jean Le Feuvre\n *                     Copyright (c) Telecom ParisTech 2000-2012\n *                                   All rights reserved\n *\n *  This file is part of GPAC / BIFS codec sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.        \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
 
 static char *CurrentLine;
 
@@ -48,7 +49,7 @@ void PrintUsage()
                        "Template files MUST be fed in order\n"
                        "\n"
                        "Generated Files are directly updated in the GPAC distribution - do NOT try to change this\n\n"
-                       "Written by Jean Le Feuvre - (c) 2000-2005\n"
+                       "Written by Jean Le Feuvre - Copyright (c) Telecom ParisTech 2000-2012\n"
                        );
 }
 
index 6e79378d8cc7c58698bb8f7faa2ca08f041b23b4..8525f2c3d3ad611469f0a3a5d8f7bd621385332c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
index 914594cb2962c3b1546608f7982f3affc914d7d4..2986d9a0a3b6a64383a93b2c0a121d13e3240712 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
index fa51fa158ad9f94690e3a4eab5340b3ddda8c698..7de0a239913ed2305e87924d31d5452a94e530cd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
index 8913f312b55613a349d6077e498c66f7adaea8c1..fd74a60a49debd319883019a1cbaa33c1500bece 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
@@ -54,7 +55,7 @@ static u32 generation_mode = 3;
 #define RNGA_PREFIX "rnga"
 #define SVGA_PREFIX "svg"
 
-#define COPYRIGHT "/*\n *                      GPAC - Multimedia Framework C SDK\n *\n *                       Authors: Cyril Concolato - Jean Le Feuvre\n *    Copyright (c)2004-200X ENST - All rights reserved\n *\n *  This file is part of GPAC / SVG Scene Graph sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.    \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
+#define COPYRIGHT "/*\n *                      GPAC - Multimedia Framework C SDK\n *\n *                       Authors: Cyril Concolato - Jean Le Feuvre\n *    Copyright (c) Telecom ParisTech 2000-2012 - All rights reserved\n *\n *  This file is part of GPAC / SVG Scene Graph sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.      \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
 
 
 /* 
index 785866e2fb85c0ef34ff077f5f5bd1f5c1a1378b..792a20db1bcc055882bb1430c6ccf7501c03d2c0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
index 8c549e6ccbc6e408e42cb48ee450644e342d60d0..3497f1a4791a5d200acfca6b48180bc069347ae6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
index 331688988d91c17fe3557ce26dc9df7f7d5cea97..0156844ddf1fb301298af5bb434d458cf6736f73 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004-2005
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph Generator sub-project
index 22954ae1e180ba2a66df535edc6e9dad004a5f3a..a2f9c405a77fb0fb74c663cbff4e077ae5572245 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012 
  *                                     All rights reserved
  *
  *  This file is part of GPAC / X3D Scene Graph Generator sub-project
@@ -29,7 +30,7 @@
 #include <gpac/list.h>
 #include <time.h>
 
-#define COPYRIGHT "/*\n *                      GPAC - Multimedia Framework C SDK\n *\n *                       Copyright (c) Jean Le Feuvre 2000-2005\n *                                      All rights reserved\n *\n *  This file is part of GPAC / X3D Scene Graph sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.   \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
+#define COPYRIGHT "/*\n *                      GPAC - Multimedia Framework C SDK\n *\n *                       Authors: Jean Le Feuvre\n *                     Copyright (c) Telecom ParisTech 2000-2012\n *                                   All rights reserved\n *\n *  This file is part of GPAC / X3D Scene Graph sub-project\n *\n *  GPAC is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU Lesser General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  GPAC is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU Lesser General Public License for more details.   \n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; see the file COPYING.  If not, write to\n *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"
 
 static char *CurrentLine;
 
index cb8c8e21a2f526772a23334c10bb239021ac430b..b64442f1402fad916483e6925071dea37103957d 100644 (file)
@@ -51,7 +51,7 @@ int main(int argc, char **argv)
                        m3u8_local_name = url;
                        is_local = 1;
                } else {
-                       e = gf_dm_wget(url, m3u8_local_name);
+                       e = gf_dm_wget(url, m3u8_local_name, 0, 0);
                        if (e != GF_OK) return -1;
                }
 
index 2226793d63a6b501ca40748f8c411785c563e4cf..3dce49f70c9ede82df28c5df354f3f0049105dd1 100644 (file)
@@ -33,11 +33,6 @@ all: $(PROG)
 $(PROG): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/$(TARGET_BIN_DIR) -lgpac -lz
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(PROG)
 
index dd31812597f900eea94d58e0bb89c00a7d496416..0089f0f71c8ce48305fd7939c4deba6080139243 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / command-line mp4 toolbox
index f41ae96a6f741a9cfdda3c399814f11b0d33a643..a108db54b58e1925e8c1c9378e6200cff015c5f3 100644 (file)
@@ -2,7 +2,7 @@ include ../../config.mak
 
 vpath %.c $(SRC_PATH)/applications/mp42ts
 
-CFLAGS= $(OPTFLAGS) -DGPAC_HAVE_CONFIG_H -I"$(SRC_PATH)/include"
+CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include"
 
 ifeq ($(DEBUGBUILD), yes)
 CFLAGS+=-g
@@ -35,11 +35,6 @@ all: $(PROG)
 $(PROG): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(PROG)
 
index 64bd04375971be12abacdc660e73ceba435cc6cb..0eedc2565eb562173fcaa5080a106b47b2f02562 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2000-200X
+ *                     Authors: Jean Le Feuvre, Cyril Concolato, Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mp4-to-ts (mp42ts) application
@@ -28,7 +29,7 @@
 #include <gpac/mpegts.h>
 
 #ifndef GPAC_DISABLE_STREAMING
-#include <gpac/ietf.h>
+#include <gpac/internal/ietf_dev.h>
 #endif
 
 #ifndef GPAC_DISABLE_SENG
@@ -123,6 +124,8 @@ typedef struct
        u32 nb_real_streams;
        Bool real_time;
        GF_List *od_updates;
+
+       Double last_ntp;
 } M2TSProgram;
 
 typedef struct
@@ -360,6 +363,9 @@ static void fill_isom_es_ifce(M2TSProgram *prog, GF_ESInterface *ifce, GF_ISOFil
        if (dcd->decoderSpecificInfo && dcd->decoderSpecificInfo->dataLength) {
                switch (dcd->objectTypeIndication) {
                case GPAC_OTI_AUDIO_AAC_MPEG4:
+               case GPAC_OTI_AUDIO_AAC_MPEG2_MP:
+               case GPAC_OTI_AUDIO_AAC_MPEG2_LCP:
+               case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP:
                        ifce->decoder_config = gf_malloc(sizeof(char)*dcd->decoderSpecificInfo->dataLength);
                        ifce->decoder_config_size = dcd->decoderSpecificInfo->dataLength;
                        memcpy(ifce->decoder_config, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength);
@@ -390,6 +396,7 @@ static void fill_isom_es_ifce(M2TSProgram *prog, GF_ESInterface *ifce, GF_ISOFil
                        }
                        gf_bs_get_content(bs, (char **) &priv->dsi, &priv->dsi_size);
                        gf_bs_del(bs);
+                       gf_odf_avc_cfg_del(avccfg);
 #endif
                        priv->nalu_delim[3] = 1;
                        priv->nalu_delim[4] = 0; /*this will be nal header*/
@@ -432,7 +439,7 @@ static void fill_isom_es_ifce(M2TSProgram *prog, GF_ESInterface *ifce, GF_ISOFil
        }
        
 #ifdef GPAC_DISABLE_ISOM_WRITE
-       fprintf(stdout, "Warning: GPAC was compiled without ISOM Write support, can't set SL Config!\n");
+       fprintf(stderr, "Warning: GPAC was compiled without ISOM Write support, can't set SL Config!\n");
 #else
        gf_isom_set_extraction_slc(mp4, track_num, 1, ifce->sl_config);
 #endif
@@ -475,11 +482,20 @@ typedef struct
 
        GF_ESInterface *ifce;
 
-       Bool cat_dsi;
+       Bool cat_dsi, is_264;
        void *dsi_and_rap;
+       u32 avc_dsi_size;
 
        Bool use_carousel;
        u32 au_sn;
+
+       s64 ts_offset;
+       Bool rtcp_init;
+       M2TSProgram *prog;
+
+       u32 min_dts_inc;
+       u64 prev_cts;
+       u64 prev_dts;
 } GF_ESIRTP;
 
 static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param)
@@ -494,6 +510,31 @@ static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param)
 
        switch (act_type) {
        case GF_ESI_INPUT_DATA_FLUSH:
+               /*flush rtcp channel*/
+               while (1) {
+                       Bool has_sr=0;
+                       size = gf_rtp_read_rtcp(rtp->rtp_ch, buffer, 8000);
+                       if (!size) break;
+                       e = gf_rtp_decode_rtcp(rtp->rtp_ch, buffer, size, &has_sr);
+
+                       if (e == GF_EOS) ifce->caps |= GF_ESI_STREAM_IS_OVER;
+
+                       if (has_sr && !rtp->rtcp_init) {
+                               Double time = rtp->rtp_ch->last_SR_NTP_sec;
+                               time += ((Double)rtp->rtp_ch->last_SR_NTP_frac)/0xFFFFFFFF;
+                               if (!rtp->prog->last_ntp) {
+                                       rtp->prog->last_ntp = time;
+                               }
+                               if (time >= rtp->prog->last_ntp) {
+                                       time -= rtp->prog->last_ntp;
+                               } else {
+                                       time = 0;
+                               }
+                               rtp->ts_offset = rtp->rtp_ch->last_SR_rtp_time;
+                               rtp->ts_offset -= (s64) (time * rtp->rtp_ch->TimeScale);
+                               rtp->rtcp_init = 1;
+                       }
+               }
                /*flush rtp channel*/
                while (1) {
                        size = gf_rtp_read_rtp(rtp->rtp_ch, buffer, 8000);
@@ -502,25 +543,229 @@ static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param)
                        if (e) return e;
                        gf_rtp_depacketizer_process(rtp->depacketizer, &hdr, buffer + PayloadStart, size - PayloadStart);
                }
-               /*flush rtcp channel*/
-               while (1) {
-                       size = gf_rtp_read_rtcp(rtp->rtp_ch, buffer, 8000);
-                       if (!size) break;
-                       e = gf_rtp_decode_rtcp(rtp->rtp_ch, buffer, size, NULL);
-                       if (e == GF_EOS) ifce->caps |= GF_ESI_STREAM_IS_OVER;
-               }
                return GF_OK;
        case GF_ESI_INPUT_DESTROY:
                gf_rtp_depacketizer_del(rtp->depacketizer);
                if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap);
                gf_rtp_del(rtp->rtp_ch);
                gf_free(rtp);
+
+               if (ifce->decoder_config) {
+                       gf_free(ifce->decoder_config);
+                       ifce->decoder_config = NULL;
+               }
                ifce->input_udta = NULL;
                return GF_OK;
        }
        return GF_OK;
 }
+
+static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e)
+{
+       GF_ESIRTP *rtp = (GF_ESIRTP*)udta;
+
+       /*sync not found yet, cannot start (since we don't support PCR discontinuities yet ...)*/
+       if (!rtp->rtcp_init) return;
+
+       /*try to compute a DTS*/
+       if (hdr->accessUnitStartFlag && !hdr->decodingTimeStampFlag) {
+               if (!rtp->prev_cts) {
+                       rtp->prev_cts = rtp->prev_dts = hdr->compositionTimeStamp;
+               }
+
+               if (hdr->compositionTimeStamp > rtp->prev_cts) {
+                       u32 diff = (u32) (hdr->compositionTimeStamp - rtp->prev_cts);
+                       if (!rtp->min_dts_inc || (rtp->min_dts_inc > diff)) {
+                               rtp->min_dts_inc = diff;
+                               rtp->prev_dts = hdr->compositionTimeStamp - diff;
+                       }
+               }
+               hdr->decodingTimeStampFlag = 1;
+               hdr->decodingTimeStamp = rtp->prev_dts + rtp->min_dts_inc;
+               rtp->prev_dts += rtp->min_dts_inc;
+               if (hdr->compositionTimeStamp < hdr->decodingTimeStamp) {
+                       hdr->decodingTimeStamp = hdr->compositionTimeStamp;
+               }
+       }
+
+       rtp->pck.data = payload;
+       rtp->pck.data_len = size;
+       rtp->pck.dts = hdr->decodingTimeStamp + rtp->ts_offset;
+       rtp->pck.cts = hdr->compositionTimeStamp + rtp->ts_offset;
+       rtp->pck.flags = 0;
+       if (hdr->compositionTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_CTS;
+       if (hdr->decodingTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_DTS;
+       if (hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_AU_RAP;
+       if (hdr->accessUnitStartFlag) rtp->pck.flags |= GF_ESI_DATA_AU_START;
+       if (hdr->accessUnitEndFlag) rtp->pck.flags |= GF_ESI_DATA_AU_END;
+
+       if (rtp->use_carousel) {
+               if ((hdr->AU_sequenceNumber==rtp->au_sn) && hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_REPEAT;
+               rtp->au_sn = hdr->AU_sequenceNumber;
+       }
+
+       if (rtp->is_264) {
+               if (!payload) return;
+
+               /*send a NALU delim: copy over NAL ref idc*/
+               if (hdr->accessUnitStartFlag) {
+                       char sc[6];
+                       sc[0] = sc[1] = sc[2] = 0;
+                       sc[3] = 1;
+                       sc[4] = (payload[4] & 0x60) | GF_AVC_NALU_ACCESS_UNIT;
+                       sc[5] = 0xF0 /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/;
+
+                       rtp->pck.data = sc;
+                       rtp->pck.data_len = 6;
+                       rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck);
+
+                       rtp->pck.flags &= ~GF_ESI_DATA_AU_START;
+
+                       /*since we don't inspect the RTP content, we can only concatenate SPS and PPS indicated in SDP*/
+                       if (hdr->randomAccessPointFlag && rtp->dsi_and_rap) {
+                               rtp->pck.data = rtp->dsi_and_rap;
+                               rtp->pck.data_len = rtp->avc_dsi_size;
+
+                               rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck);
+                       }
+
+                       rtp->pck.data = payload;
+                       rtp->pck.data_len = size;
+               }
+
+               rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck);
+       } else {
+               if (rtp->cat_dsi && hdr->randomAccessPointFlag && hdr->accessUnitStartFlag) {
+                       if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap);
+                       rtp->pck.data_len = size + rtp->depacketizer->sl_map.configSize;
+                       rtp->dsi_and_rap = gf_malloc(sizeof(char)*(rtp->pck.data_len));
+                       memcpy(rtp->dsi_and_rap, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize);
+                       memcpy((char *) rtp->dsi_and_rap + rtp->depacketizer->sl_map.configSize, payload, size);
+                       rtp->pck.data = rtp->dsi_and_rap;
+               }
+               rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck);
+       }
+}
+
+static void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp, M2TSProgram *prog)
+{
+       u32 i;
+       GF_Err e;
+       GF_X_Attribute*att;
+       GF_ESIRTP *rtp;
+       GF_RTPMap*map;
+       GF_SDPConnection *conn;
+       GF_RTSPTransport trans;
+
+       /*check connection*/
+       conn = sdp->c_connection;
+       if (!conn) conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0);
+
+       /*check payload type*/
+       map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0);
+       GF_SAFEALLOC(rtp, GF_ESIRTP);
+
+       memset(ifce, 0, sizeof(GF_ESInterface));
+       rtp->rtp_ch = gf_rtp_new();
+       i=0;
+       while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &i))) {
+               if (!stricmp(att->Name, "mpeg4-esid") && att->Value) ifce->stream_id = atoi(att->Value);
+       }
+
+       memset(&trans, 0, sizeof(GF_RTSPTransport));
+       trans.Profile = media->Profile;
+       trans.source = conn ? conn->host : sdp->o_address;
+       trans.IsUnicast = gf_sk_is_multicast_address(trans.source) ? 0 : 1;
+       if (!trans.IsUnicast) {
+               trans.port_first = media->PortNumber;
+               trans.port_last = media->PortNumber + 1;
+               trans.TTL = conn ? conn->TTL : 0;
+       } else {
+               trans.client_port_first = media->PortNumber;
+               trans.client_port_last = media->PortNumber + 1;
+       }
+
+       if (gf_rtp_setup_transport(rtp->rtp_ch, &trans, NULL) != GF_OK) {
+               gf_rtp_del(rtp->rtp_ch);
+               fprintf(stderr, "Cannot initialize RTP transport\n");
+               return;
+       }
+       /*setup depacketizer*/
+       rtp->depacketizer = gf_rtp_depacketizer_new(media, rtp_sl_packet_cbk, rtp);
+       if (!rtp->depacketizer) {
+               gf_rtp_del(rtp->rtp_ch);
+               fprintf(stderr, "Cannot create RTP depacketizer\n");
+               return;
+       }
+       /*setup channel*/
+       gf_rtp_setup_payload(rtp->rtp_ch, map);
+       ifce->input_udta = rtp;
+       ifce->input_ctrl = rtp_input_ctrl;
+       rtp->ifce = ifce;
+       rtp->prog = prog;
+
+       ifce->object_type_indication = rtp->depacketizer->sl_map.ObjectTypeIndication;
+       ifce->stream_type = rtp->depacketizer->sl_map.StreamType;
+       ifce->timescale = gf_rtp_get_clockrate(rtp->rtp_ch);
+       if (rtp->depacketizer->sl_map.config) {
+               switch (ifce->object_type_indication) {
+               case GPAC_OTI_VIDEO_MPEG4_PART2:
+                       rtp->cat_dsi = 1;
+                       break;
+               case GPAC_OTI_VIDEO_AVC:
+                       rtp->is_264 = 1;
+                       rtp->depacketizer->flags |= GF_RTP_AVC_USE_ANNEX_B;
+               {
+#ifndef GPAC_DISABLE_AV_PARSERS
+                       GF_AVCConfig *avccfg = gf_odf_avc_cfg_read(rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize);
+                       if (avccfg) {
+                               GF_AVCConfigSlot *slc;
+                               u32 i;
+                               GF_BitStream *bs;
+
+                               bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+                               for (i=0; i<gf_list_count(avccfg->sequenceParameterSets);i++) {
+                                       slc = gf_list_get(avccfg->sequenceParameterSets, i);
+                                       gf_bs_write_u32(bs, 1);
+                                       gf_bs_write_data(bs, slc->data, slc->size);
+                               }
+                               for (i=0; i<gf_list_count(avccfg->pictureParameterSets);i++) {
+                                       slc = gf_list_get(avccfg->pictureParameterSets, i);
+                                       gf_bs_write_u32(bs, 1);
+                                       gf_bs_write_data(bs, slc->data, slc->size);
+                               }
+                               gf_bs_get_content(bs, (char **) &rtp->dsi_and_rap, &rtp->avc_dsi_size);
+                               gf_bs_del(bs);
+                       }       
+                       gf_odf_avc_cfg_del(avccfg);
 #endif
+               }
+                       break;
+               case GPAC_OTI_AUDIO_AAC_MPEG4:
+                       ifce->decoder_config = gf_malloc(sizeof(char) * rtp->depacketizer->sl_map.configSize);
+                       ifce->decoder_config_size = rtp->depacketizer->sl_map.configSize;
+                       memcpy(ifce->decoder_config, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize);
+                       break;
+               }
+       }
+       if (rtp->depacketizer->sl_map.StreamStateIndication) {
+               rtp->use_carousel = 1;
+               rtp->au_sn=0;
+       }
+
+       /*DTS signaling is only supported for MPEG-4 visual*/
+       if (rtp->depacketizer->sl_map.DTSDeltaLength) ifce->caps |= GF_ESI_SIGNAL_DTS;
+
+       gf_rtp_depacketizer_reset(rtp->depacketizer, 1);
+       e = gf_rtp_initialize(rtp->rtp_ch, 0x100000ul, 0, 0, 10, 200, NULL);
+       if (e!=GF_OK) {
+               gf_rtp_del(rtp->rtp_ch);
+               fprintf(stderr, "Cannot initialize RTP channel: %s\n", gf_error_to_string(e));
+               return;
+       }
+       fprintf(stderr, "RTP interface initialized\n");
+}
+#endif /*GPAC_DISABLE_STREAMING*/
 
 static GF_Err void_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param)
 {
@@ -918,7 +1163,7 @@ static Bool seng_output(void *param)
                                case 'p':
                                {
                                        char rad[GF_MAX_PATH];
-                                       fprintf(stderr, "Enter output file name - \"std\" for stdout: ");
+                                       fprintf(stderr, "Enter output file name - \"std\" for stderr: ");
                                        if (1 > scanf("%s", rad)){
                                            fprintf(stderr, "No outfile name has been entered, aborting.\n");
                                            break;
@@ -939,128 +1184,7 @@ static Bool seng_output(void *param)
        
        return e ? 1 : 0;
 }
-#endif
-
-
-#ifndef GPAC_DISABLE_STREAMING
-static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e)
-{
-       GF_ESIRTP *rtp = (GF_ESIRTP*)udta;
-       rtp->pck.data = payload;
-       rtp->pck.data_len = size;
-       rtp->pck.dts = hdr->decodingTimeStamp;
-       rtp->pck.cts = hdr->compositionTimeStamp;
-       rtp->pck.flags = 0;
-       if (hdr->compositionTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_CTS;
-       if (hdr->decodingTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_DTS;
-       if (hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_AU_RAP;
-       if (hdr->accessUnitStartFlag) rtp->pck.flags |= GF_ESI_DATA_AU_START;
-       if (hdr->accessUnitEndFlag) rtp->pck.flags |= GF_ESI_DATA_AU_END;
-
-       if (rtp->use_carousel) {
-               if ((hdr->AU_sequenceNumber==rtp->au_sn) && hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_REPEAT;
-               rtp->au_sn = hdr->AU_sequenceNumber;
-       }
-
-       if (rtp->cat_dsi && hdr->randomAccessPointFlag && hdr->accessUnitStartFlag) {
-               if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap);
-               rtp->pck.data_len = size + rtp->depacketizer->sl_map.configSize;
-               rtp->dsi_and_rap = gf_malloc(sizeof(char)*(rtp->pck.data_len));
-               memcpy(rtp->dsi_and_rap, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize);
-               memcpy((char *) rtp->dsi_and_rap + rtp->depacketizer->sl_map.configSize, payload, size);
-               rtp->pck.data = rtp->dsi_and_rap;
-       }
-
-
-       rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck);
-}
-
-static void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp)
-{
-       u32 i;
-       GF_Err e;
-       GF_X_Attribute*att;
-       GF_ESIRTP *rtp;
-       GF_RTPMap*map;
-       GF_SDPConnection *conn;
-       GF_RTSPTransport trans;
-
-       /*check connection*/
-       conn = sdp->c_connection;
-       if (!conn) conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0);
-
-       /*check payload type*/
-       map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0);
-       GF_SAFEALLOC(rtp, GF_ESIRTP);
-
-       memset(ifce, 0, sizeof(GF_ESInterface));
-       rtp->rtp_ch = gf_rtp_new();
-       i=0;
-       while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &i))) {
-               if (!stricmp(att->Name, "mpeg4-esid") && att->Value) ifce->stream_id = atoi(att->Value);
-       }
-
-       memset(&trans, 0, sizeof(GF_RTSPTransport));
-       trans.Profile = media->Profile;
-       trans.source = conn ? conn->host : sdp->o_address;
-       trans.IsUnicast = gf_sk_is_multicast_address(trans.source) ? 0 : 1;
-       if (!trans.IsUnicast) {
-               trans.port_first = media->PortNumber;
-               trans.port_last = media->PortNumber + 1;
-               trans.TTL = conn ? conn->TTL : 0;
-       } else {
-               trans.client_port_first = media->PortNumber;
-               trans.client_port_last = media->PortNumber + 1;
-       }
-
-       if (gf_rtp_setup_transport(rtp->rtp_ch, &trans, NULL) != GF_OK) {
-               gf_rtp_del(rtp->rtp_ch);
-               fprintf(stderr, "Cannot initialize RTP transport\n");
-               return;
-       }
-       /*setup depacketizer*/
-       rtp->depacketizer = gf_rtp_depacketizer_new(media, rtp_sl_packet_cbk, rtp);
-       if (!rtp->depacketizer) {
-               gf_rtp_del(rtp->rtp_ch);
-               fprintf(stderr, "Cannot create RTP depacketizer\n");
-               return;
-       }
-       /*setup channel*/
-       gf_rtp_setup_payload(rtp->rtp_ch, map);
-       ifce->input_udta = rtp;
-       ifce->input_ctrl = rtp_input_ctrl;
-       rtp->ifce = ifce;
-
-       ifce->object_type_indication = rtp->depacketizer->sl_map.ObjectTypeIndication;
-       ifce->stream_type = rtp->depacketizer->sl_map.StreamType;
-       ifce->timescale = gf_rtp_get_clockrate(rtp->rtp_ch);
-       if (rtp->depacketizer->sl_map.config) {
-               switch (ifce->object_type_indication) {
-               case GPAC_OTI_VIDEO_MPEG4_PART2:
-                       rtp->cat_dsi = 1;
-                       break;
-               }
-       }
-       if (rtp->depacketizer->sl_map.StreamStateIndication) {
-               rtp->use_carousel = 1;
-               rtp->au_sn=0;
-       }
-
-       /*DTS signaling is only supported for MPEG-4 visual*/
-       if (rtp->depacketizer->sl_map.DTSDeltaLength) ifce->caps |= GF_ESI_SIGNAL_DTS;
-
-       gf_rtp_depacketizer_reset(rtp->depacketizer, 1);
-       e = gf_rtp_initialize(rtp->rtp_ch, 0x100000ul, 0, 0, 10, 200, NULL);
-       if (e!=GF_OK) {
-               gf_rtp_del(rtp->rtp_ch);
-               fprintf(stderr, "Cannot initialize RTP channel: %s\n", gf_error_to_string(e));
-               return;
-       }
-       fprintf(stderr, "RTP interface initialized\n");
-}
-#endif /*GPAC_DISABLE_STREAMING*/
 
-#ifndef GPAC_DISABLE_SENG
 void fill_seng_es_ifce(GF_ESInterface *ifce, u32 i, GF_SceneEngine *seng, u32 period)
 {
        GF_Err e = GF_OK;
@@ -1300,7 +1424,7 @@ static Bool open_program(M2TSProgram *prog, char *src, u32 carousel_rate, u32 mp
                prog->nb_streams = gf_list_count(sdp->media_desc);
                for (i=0; i<prog->nb_streams; i++) {
                        GF_SDPMedia *media = gf_list_get(sdp->media_desc, i);
-                       fill_rtp_es_ifce(&prog->streams[i], media, sdp);
+                       fill_rtp_es_ifce(&prog->streams[i], media, sdp, prog);
                        switch(prog->streams[i].stream_type) {
                        case GF_STREAM_OD:
                        case GF_STREAM_SCENE:
@@ -1589,7 +1713,7 @@ static GFINLINE GF_Err parse_args(int argc, char **argv, u32 *mux_rate, u32 *car
                        gf_sys_init(1);
                        gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_DEBUG);
 #else
-                       fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
+                       fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
 #endif
                } else if (!strnicmp(arg, "-rate=", 6)) {
                        if (rate_found) {
@@ -1772,9 +1896,8 @@ error:
        return GF_BAD_PARAM;
 }
 
-/* adapted from http://svn.assembla.com/svn/legend/segmenter/segmenter.c */
-static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_duration, char *segment_prefix, char *http_prefix, 
-                                                       u32 first_segment, u32 last_segment, Bool end) {
+static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_duration, char *segment_prefix, char *http_prefix, u32 first_segment, u32 last_segment, Bool end) 
+{
        FILE *manifest_fp;
        u32 i;
        char manifest_tmp_name[GF_MAX_PATH];
@@ -1810,7 +1933,7 @@ static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_dura
                return GF_OK;
        } else {
                if (remove(manifest_name)) {
-                       fprintf(stdout, "Error removing file %s\n", manifest_name);
+                       fprintf(stderr, "Error removing file %s\n", manifest_name);
                        return GF_IO_ERR;
                } else if (rename(tmp_manifest, manifest_name)) {
                        fprintf(stderr, "Could not rename temporary m3u8 manifest file (%s) into %s\n", tmp_manifest, manifest_name);
@@ -2016,7 +2139,7 @@ int main(int argc, char **argv)
                                e = gf_sk_bind(audio_input_udp_sk, NULL, audio_input_port, (char *)audio_input_ip, audio_input_port, GF_SOCK_REUSE_PORT);
                        }
                        if (e) {
-                               fprintf(stdout, "Error initializing UDP socket for %s:%d : %s\n", audio_input_ip, audio_input_port, gf_error_to_string(e));
+                               fprintf(stderr, "Error initializing UDP socket for %s:%d : %s\n", audio_input_ip, audio_input_port, gf_error_to_string(e));
                                goto exit;
                        }
                        gf_sk_set_buffer_size(audio_input_udp_sk, 0, UDP_BUFFER_SIZE);
@@ -2223,8 +2346,8 @@ int main(int argc, char **argv)
        {
                u64 bits = muxer->tot_pck_sent*8*188;
                u32 dur_sec = gf_m2ts_get_ts_clock(muxer) / 1000;
-               fprintf(stdout, "Done muxing - %d sec - average rate %d kbps "LLD" packets written\n", dur_sec, (u32) (bits/dur_sec/1000), muxer->tot_pck_sent);
-               fprintf(stdout, "\tPadding: "LLD" packets - "LLD" PES padded bytes (%g kbps)\n", muxer->tot_pad_sent, muxer->tot_pes_pad_bytes, (Double) (muxer->tot_pes_pad_bytes*8.0/dur_sec/1000) );
+               fprintf(stderr, "Done muxing - %d sec - average rate %d kbps "LLD" packets written\n", dur_sec, (u32) (bits/dur_sec/1000), muxer->tot_pck_sent);
+               fprintf(stderr, "\tPadding: "LLD" packets - "LLD" PES padded bytes (%g kbps)\n", muxer->tot_pad_sent, muxer->tot_pes_pad_bytes, (Double) (muxer->tot_pes_pad_bytes*8.0/dur_sec/1000) );
        }
 
 exit:
index 5ed59a1ad3786b65731511f1ee26e76d3bfe4e61..3951be02460bc7688256c15eeb5114b4ccc5de58 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2000-200X
+ *                     Authors: Jean Le Feuvre, Cyril Concolato, Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mp42ts application
index c82e22b196a10b9a76408e64d9e1ae972d1b3571..a248ab4f36922cd844433e9bae583192da31e518 100644 (file)
@@ -15,7 +15,10 @@ LDFLAGS+=-pg
 endif
 
 #common obj
-OBJS= main.o filedump.o fileimport.o live.o
+OBJS=main.o filedump.o fileimport.o 
+ifeq ($(DISABLE_STREAMING),no)
+OBJS+=live.o
+endif
 
 LINKFLAGS=-L../../bin/gcc -L../../extra_lib/lib/gcc
 
@@ -59,11 +62,6 @@ all: $(PROG)
 $(PROG): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(PROG)
 
index e7289b831f20c72f1e4ee70ff567f3e6760afed5..147426e889c256957c768558793e6884f5c466d9 100644 (file)
@@ -1,12 +1,13 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mp4box application
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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.
@@ -36,6 +37,9 @@
 #ifndef GPAC_DISABLE_BIFS
 #include <gpac/internal/bifs_dev.h>
 #endif
+#ifndef GPAC_DISABLE_VRML
+#include <gpac/nodes_mpeg4.h>
+#endif
 #include <gpac/constants.h>
 #include <gpac/avparse.h>
 #include <gpac/media_tools.h>
@@ -62,13 +66,13 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
 void PrintLanguages()
 {
        u32 i=0;
-       fprintf(stdout, "Supported ISO 639 languages and codes:\n\n");
+       fprintf(stderr, "Supported ISO 639 languages and codes:\n\n");
        while (GF_ISO639_Lang[i]) {
                if (!GF_ISO639_Lang[i+2][0]) {
                        i+=3;
                        continue;
                }
-               fprintf(stdout, "%s (%s - %s)\n", GF_ISO639_Lang[i], GF_ISO639_Lang[i+1], GF_ISO639_Lang[i+2]);
+               fprintf(stderr, "%s (%s - %s)\n", GF_ISO639_Lang[i], GF_ISO639_Lang[i+1], GF_ISO639_Lang[i+2]);
                i+=3;
        }
 }
@@ -113,7 +117,7 @@ GF_Err dump_cover_art(GF_ISOFile *file, char *inName)
        GF_Err e = gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COVER_ART, &tag, &tag_len);
        if (e!=GF_OK) {
                if (e==GF_URL_ERROR) {
-                       fprintf(stdout, "No cover art found\n");
+                       fprintf(stderr, "No cover art found\n");
                        return GF_OK;
                }
                return e;
@@ -171,6 +175,9 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log)
        load.fileName = file;
        load.ctx = ctx;
        load.swf_import_flags = swf_flags;
+    if (dump_mode == GF_SM_DUMP_SVG) {
+        load.swf_import_flags |= GF_SM_SWF_USE_SVG;
+    }
        load.swf_flatten_limit = swf_flatten_angle;
 
        ftype = get_file_type_by_ext(file);
@@ -178,7 +185,7 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log)
                load.isom = gf_isom_open(file, GF_ISOM_OPEN_READ, NULL);
                if (!load.isom) {
                        e = gf_isom_last_error(NULL);
-                       fprintf(stdout, "Error opening file: %s\n", gf_error_to_string(e));
+                       fprintf(stderr, "Error opening file: %s\n", gf_error_to_string(e));
                        gf_sm_del(ctx);
                        gf_sg_del(sg);
                        return e;
@@ -197,7 +204,7 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log)
                        e = gf_isom_last_error(NULL);
 
                if (e) {
-                       fprintf(stdout, "Error importing file: %s\n", gf_error_to_string(e));
+                       fprintf(stderr, "Error importing file: %s\n", gf_error_to_string(e));
                        gf_sm_del(ctx);
                        gf_sg_del(sg);
                        if (load.isom) gf_isom_delete(load.isom);
@@ -224,16 +231,16 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log)
        if (!e) {
                u32 count = gf_list_count(ctx->streams);
                if (count)
-                       fprintf(stdout, "Scene loaded - dumping %d systems streams\n", count);
+                       fprintf(stderr, "Scene loaded - dumping %d systems streams\n", count);
                else
-                       fprintf(stdout, "Scene loaded - dumping root scene\n");
+                       fprintf(stderr, "Scene loaded - dumping root scene\n");
 
                e = gf_sm_dump(ctx, inName, dump_mode);
        }
 
        gf_sm_del(ctx);
        gf_sg_del(sg);
-       if (e) fprintf(stdout, "Error loading scene: %s\n", gf_error_to_string(e));
+       if (e) fprintf(stderr, "Error loading scene: %s\n", gf_error_to_string(e));
        if (load.isom) gf_isom_delete(load.isom);
        return e;
 }
@@ -391,7 +398,7 @@ void dump_scene_stats(char *file, char *inName, u32 stat_level)
        if (get_file_type_by_ext(file) == 1) {
                load.isom = gf_isom_open(file, GF_ISOM_OPEN_READ, NULL);
                if (!load.isom) {
-                       fprintf(stdout, "Cannot open file: %s\n", gf_error_to_string(gf_isom_last_error(NULL)));
+                       fprintf(stderr, "Cannot open file: %s\n", gf_error_to_string(gf_isom_last_error(NULL)));
                        gf_sm_del(ctx);
                        gf_sg_del(scene_graph);
                        return;
@@ -409,11 +416,11 @@ void dump_scene_stats(char *file, char *inName, u32 stat_level)
                dump = gf_f64_open(szBuf, "wt");
                close = 1;
        } else {
-               dump = stdout;
+               dump = stderr;
                close = 0;
        }
 
-       fprintf(stdout, "Analysing Scene\n");
+       fprintf(stderr, "Analysing Scene\n");
 
        fprintf(dump, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
        fprintf(dump, "<!-- Scene Graph Statistics Generated by MP4Box - GPAC " GPAC_FULL_VERSION" -->\n");
@@ -483,12 +490,12 @@ exit:
        gf_sm_del(ctx);
        gf_sg_del(scene_graph);
        if (e) {
-               fprintf(stdout, "%s\n", gf_error_to_string(e));
+               fprintf(stderr, "%s\n", gf_error_to_string(e));
        } else {
                fprintf(dump, "</SceneStatistics>\n");
        }
        if (dump && close) fclose(dump);
-       fprintf(stdout, "done\n");
+       fprintf(stderr, "done\n");
 }
 #endif /*GPAC_DISABLE_SCENE_STATS*/
 
@@ -498,10 +505,10 @@ exit:
 
 static void PrintFixed(Fixed val, Bool add_space)
 {
-       if (add_space) fprintf(stdout, " ");
-       if (val==FIX_MIN) fprintf(stdout, "-I");
-       else if (val==FIX_MAX) fprintf(stdout, "+I");
-       else fprintf(stdout, "%g", FIX2FLT(val));
+       if (add_space) fprintf(stderr, " ");
+       if (val==FIX_MIN) fprintf(stderr, "-I");
+       else if (val==FIX_MAX) fprintf(stderr, "+I");
+       else fprintf(stderr, "%g", FIX2FLT(val));
 }
 
 static void PrintNodeSFField(u32 type, void *far_ptr)
@@ -509,16 +516,16 @@ static void PrintNodeSFField(u32 type, void *far_ptr)
        if (!far_ptr) return;
        switch (type) {
        case GF_SG_VRML_SFBOOL:
-               fprintf(stdout, "%s", (*(SFBool *)far_ptr) ? "TRUE" : "FALSE");
+               fprintf(stderr, "%s", (*(SFBool *)far_ptr) ? "TRUE" : "FALSE");
                break;
        case GF_SG_VRML_SFINT32:
-               fprintf(stdout, "%d", (*(SFInt32 *)far_ptr));
+               fprintf(stderr, "%d", (*(SFInt32 *)far_ptr));
                break;
        case GF_SG_VRML_SFFLOAT:
                PrintFixed((*(SFFloat *)far_ptr), 0);
                break;
        case GF_SG_VRML_SFTIME:
-               fprintf(stdout, "%g", (*(SFTime *)far_ptr));
+               fprintf(stderr, "%g", (*(SFTime *)far_ptr));
                break;
        case GF_SG_VRML_SFVEC2F:
                PrintFixed(((SFVec2f *)far_ptr)->x, 0);
@@ -542,9 +549,9 @@ static void PrintNodeSFField(u32 type, void *far_ptr)
                break;
        case GF_SG_VRML_SFSTRING:
                if (((SFString*)far_ptr)->buffer)
-                       fprintf(stdout, "\"%s\"", ((SFString*)far_ptr)->buffer);
+                       fprintf(stderr, "\"%s\"", ((SFString*)far_ptr)->buffer);
                else
-                       fprintf(stdout, "NULL");
+                       fprintf(stderr, "NULL");
                break;
        }
 }
@@ -553,7 +560,7 @@ static void PrintNodeSFField(u32 type, void *far_ptr)
 void PrintNode(const char *name, u32 graph_type)
 {
 #ifdef GPAC_DISABLE_VRML
-       fprintf(stdout, "VRML/MPEG-4/X3D scene graph is disabled in this build of GPAC\n");
+       fprintf(stderr, "VRML/MPEG-4/X3D scene graph is disabled in this build of GPAC\n");
        return;
 #else
        const char *nname, *std_name;
@@ -578,14 +585,14 @@ void PrintNode(const char *name, u32 graph_type)
 
        tag = 0;
        if (graph_type==2) {
-               fprintf(stdout, "SVG node printing is not supported\n");
+               fprintf(stderr, "SVG node printing is not supported\n");
                return;
        } else if (graph_type==1) {
 #ifndef GPAC_DISABLE_X3D
                tag = gf_node_x3d_type_by_class_name(name);
                std_name = "X3D";
 #else
-                fprintf(stdout, "X3D node printing is not supported (X3D support disabled)\n");
+                fprintf(stderr, "X3D node printing is not supported (X3D support disabled)\n");
                 return;
 #endif
        } else {
@@ -593,7 +600,7 @@ void PrintNode(const char *name, u32 graph_type)
                std_name = "MPEG4";
        }
        if (!tag) {
-               fprintf(stdout, "Unknown %s node %s\n", std_name, name);
+               fprintf(stderr, "Unknown %s node %s\n", std_name, name);
                return;
        }
 
@@ -602,7 +609,7 @@ void PrintNode(const char *name, u32 graph_type)
        gf_node_register(node, NULL);
        nname = gf_node_get_class_name(node);
        if (!node) {
-               fprintf(stdout, "Node %s not supported in current built\n", nname);
+               fprintf(stderr, "Node %s not supported in current built\n", nname);
                return;
        }
        nbF = gf_node_get_field_count(node);
@@ -610,10 +617,10 @@ void PrintNode(const char *name, u32 graph_type)
        if (is_nodefield) {
                u32 tfirst, tlast;
                if (gf_node_get_field_by_name(node, szField, &f) != GF_OK) {
-                       fprintf(stdout, "Field %s is not a member of node %s\n", szField, name);
+                       fprintf(stderr, "Field %s is not a member of node %s\n", szField, name);
                        return;
                }
-               fprintf(stdout, "Allowed nodes in %s.%s:\n", name, szField);
+               fprintf(stderr, "Allowed nodes in %s.%s:\n", name, szField);
                if (graph_type==1) {
                        tfirst = GF_NODE_RANGE_FIRST_X3D;
                        tlast = GF_NODE_RANGE_LAST_X3D;
@@ -627,7 +634,7 @@ void PrintNode(const char *name, u32 graph_type)
                        if (gf_node_in_table_by_tag(i, f.NDTtype)) {
                                const char *nname = gf_node_get_class_name(tmp);
                                if (nname && strcmp(nname, "Unknown Node")) {
-                                       fprintf(stdout, "\t%s\n", nname); 
+                                       fprintf(stderr, "\t%s\n", nname); 
                                }
                        }
                        gf_node_unregister(tmp, NULL);
@@ -635,52 +642,52 @@ void PrintNode(const char *name, u32 graph_type)
                return;
        }
 
-       fprintf(stdout, "Node Syntax:\n%s {\n", nname);
+       fprintf(stderr, "Node Syntax:\n%s {\n", nname);
 
        for (i=0; i<nbF; i++) {
                gf_node_get_field(node, i, &f);
                if (graph_type==2) {
-                       fprintf(stdout, "\t%s=\"...\"\n", f.name);
+                       fprintf(stderr, "\t%s=\"...\"\n", f.name);
                        continue;
                }
 
-               fprintf(stdout, "\t%s %s %s", gf_sg_vrml_get_event_type_name(f.eventType, 0), gf_sg_vrml_get_field_type_by_name(f.fieldType), f.name);
-               if (f.fieldType==GF_SG_VRML_SFNODE) fprintf(stdout, " NULL");
-               else if (f.fieldType==GF_SG_VRML_MFNODE) fprintf(stdout, " []");
+               fprintf(stderr, "\t%s %s %s", gf_sg_vrml_get_event_type_name(f.eventType, 0), gf_sg_vrml_get_field_type_by_name(f.fieldType), f.name);
+               if (f.fieldType==GF_SG_VRML_SFNODE) fprintf(stderr, " NULL");
+               else if (f.fieldType==GF_SG_VRML_MFNODE) fprintf(stderr, " []");
                else if (gf_sg_vrml_is_sf_field(f.fieldType)) {
-                       fprintf(stdout, " ");
+                       fprintf(stderr, " ");
                        PrintNodeSFField(f.fieldType, f.far_ptr);
                } else {
                        void *ptr;
                        u32 i, sftype;
                        GenMFField *mffield = (GenMFField *) f.far_ptr;
-                       fprintf(stdout, " [");
+                       fprintf(stderr, " [");
                        sftype = gf_sg_vrml_get_sf_type(f.fieldType);
                        for (i=0; i<mffield->count; i++) {
-                               if (i) fprintf(stdout, " ");
+                               if (i) fprintf(stderr, " ");
                                gf_sg_vrml_mf_get_item(f.far_ptr, f.fieldType, &ptr, i);
                                PrintNodeSFField(sftype, ptr);
                        }
-                       fprintf(stdout, "]");
+                       fprintf(stderr, "]");
                }
 #ifndef GPAC_DISABLE_BIFS
                if (gf_bifs_get_aq_info(node, i, &qt, &at, &bmin, &bmax, &nbBits)) {
                        if (qt) {
-                               fprintf(stdout, " #QP=%d", qt);
-                               if (qt==13) fprintf(stdout, " NbBits=%d", nbBits);
+                               fprintf(stderr, " #QP=%d", qt);
+                               if (qt==13) fprintf(stderr, " NbBits=%d", nbBits);
                                if (bmin && bmax) {
-                                       fprintf(stdout, " Bounds=[");
+                                       fprintf(stderr, " Bounds=[");
                                        PrintFixed(bmin, 0);
-                                       fprintf(stdout, ",");
+                                       fprintf(stderr, ",");
                                        PrintFixed(bmax, 0);
-                                       fprintf(stdout, "]");
+                                       fprintf(stderr, "]");
                                }
                        }
                }
 #endif /*GPAC_DISABLE_BIFS*/
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
        }
-       fprintf(stdout, "}\n\n");
+       fprintf(stderr, "}\n\n");
 
        gf_node_unregister(node, NULL);
        gf_sg_del(sg);
@@ -699,12 +706,12 @@ void PrintBuiltInNodes(u32 graph_type)
                 start_tag = GF_NODE_RANGE_FIRST_X3D;
                 end_tag = TAG_LastImplementedX3D;
 #else
-               fprintf(stdout, "X3D scene graph disabled in this build of GPAC\n");
+               fprintf(stderr, "X3D scene graph disabled in this build of GPAC\n");
                return;
 #endif
        } else if (graph_type==2) {
 #ifdef GPAC_DISABLE_SVG
-               fprintf(stdout, "SVG scene graph disabled in this build of GPAC\n");
+               fprintf(stderr, "SVG scene graph disabled in this build of GPAC\n");
                return;
 #else
                start_tag = GF_NODE_RANGE_FIRST_SVG;
@@ -712,7 +719,7 @@ void PrintBuiltInNodes(u32 graph_type)
 #endif
        } else {
 #ifdef GPAC_DISABLE_VRML
-               fprintf(stdout, "VRML/MPEG-4 scene graph disabled in this build of GPAC\n");
+               fprintf(stderr, "VRML/MPEG-4 scene graph disabled in this build of GPAC\n");
                return;
 #else
                start_tag = GF_NODE_RANGE_FIRST_MPEG4;
@@ -723,17 +730,17 @@ void PrintBuiltInNodes(u32 graph_type)
        sg = gf_sg_new();
        
        if (graph_type==1) {
-               fprintf(stdout, "Available X3D nodes in this build (dumping):\n");
+               fprintf(stderr, "Available X3D nodes in this build (dumping):\n");
        } else if (graph_type==2) {
-               fprintf(stdout, "Available SVG nodes in this build (dumping and LASeR coding):\n");
+               fprintf(stderr, "Available SVG nodes in this build (dumping and LASeR coding):\n");
        } else {
-               fprintf(stdout, "Available MPEG-4 nodes in this build (encoding/decoding/dumping):\n");
+               fprintf(stderr, "Available MPEG-4 nodes in this build (encoding/decoding/dumping):\n");
        }
        for (i=start_tag; i<end_tag; i++) {
                node = gf_node_new(sg, i);
                if (node) {
                        gf_node_register(node, NULL);
-                       fprintf(stdout, " %s\n", gf_node_get_class_name(node));
+                       fprintf(stderr, " %s\n", gf_node_get_class_name(node));
                        gf_node_unregister(node, NULL);
                        nb_in++;
                } else {
@@ -744,12 +751,12 @@ void PrintBuiltInNodes(u32 graph_type)
        }
        gf_sg_del(sg);
        if (graph_type==2) {
-               fprintf(stdout, "\n%d nodes supported\n", nb_in);
+               fprintf(stderr, "\n%d nodes supported\n", nb_in);
        } else {
-               fprintf(stdout, "\n%d nodes supported - %d nodes not supported\n", nb_in, nb_not_in);
+               fprintf(stderr, "\n%d nodes supported - %d nodes not supported\n", nb_in, nb_not_in);
        }
 #else
-       fprintf(stdout, "\nNo scene graph enabled in this MP4Box build\n");
+       fprintf(stderr, "\nNo scene graph enabled in this MP4Box build\n");
 #endif
 }
 
@@ -767,7 +774,7 @@ void dump_isom_xml(GF_ISOFile *file, char *inName)
                gf_isom_dump(file, dump);
                fclose(dump);
        } else {
-               gf_isom_dump(file, stdout);
+               gf_isom_dump(file, stderr);
        }
 }
 #endif
@@ -786,7 +793,7 @@ void dump_file_rtp(GF_ISOFile *file, char *inName)
                strcat(szBuf, "_rtp.xml");
                dump = gf_f64_open(szBuf, "wt");
        } else {
-               dump = stdout;
+               dump = stderr;
        }
 
        fprintf(dump, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
@@ -807,7 +814,7 @@ void dump_file_rtp(GF_ISOFile *file, char *inName)
 }
 #endif
 
-void dump_file_ts(GF_ISOFile *file, char *inName)
+void dump_file_timestamps(GF_ISOFile *file, char *inName)
 {
        u32 i, j, k, count;
        Bool has_error;
@@ -819,15 +826,16 @@ void dump_file_ts(GF_ISOFile *file, char *inName)
                strcat(szBuf, "_ts.txt");
                dump = gf_f64_open(szBuf, "wt");
        } else {
-               dump = stdout;
+               dump = stderr;
        }
 
        has_error = 0;
        for (i=0; i<gf_isom_get_track_count(file); i++) {       
-               Bool has_cts_offset = gf_isom_has_time_offset(file, i+1);
+               u32 has_cts_offset = gf_isom_has_time_offset(file, i+1);
 
                fprintf(dump, "#dumping track ID %d timing: Num DTS CTS Size RAP\n", gf_isom_get_track_id(file, i+1));
                count = gf_isom_get_sample_count(file, i+1);
+
                for (j=0; j<count; j++) {
                        u64 dts, cts;
                        GF_ISOSample *samp = gf_isom_get_sample_info(file, i+1, j+1, NULL, NULL);
@@ -861,7 +869,158 @@ void dump_file_ts(GF_ISOFile *file, char *inName)
                gf_set_progress("Analysing Track Timing", count, count);
        }
        if (inName) fclose(dump);
-       if (has_error) fprintf(stdout, "\tFile has CTTS table errors\n");
+       if (has_error) fprintf(stderr, "\tFile has CTTS table errors\n");
+}
+
+
+static void dump_nalu_type_name(FILE *dump, char *ptr, Bool is_svc)
+{
+       u8 type = ptr[0] & 0x1F;
+       u8 dependency_id, quality_id, temporal_id;
+       u8 track_ref_index;
+       u32 data_offset;
+       
+       fprintf(dump, "code=\"%d\" type=\"", type);
+       switch (type) {
+       case GF_AVC_NALU_NON_IDR_SLICE: fputs("Non IDR slice", dump); break;
+       case GF_AVC_NALU_DP_A_SLICE: fputs("DP Type A slice", dump); break;
+       case GF_AVC_NALU_DP_B_SLICE: fputs("DP Type B slice", dump); break;
+       case GF_AVC_NALU_DP_C_SLICE: fputs("DP Type C slice", dump); break;
+       case GF_AVC_NALU_IDR_SLICE: fputs("IDR slice", dump); break;
+       case GF_AVC_NALU_SEI: fputs("SEI Message", dump); break;
+       case GF_AVC_NALU_SEQ_PARAM: fputs("SequenceParameterSet", dump); break;
+       case GF_AVC_NALU_PIC_PARAM: fputs("PictureParameterSet", dump); break;
+       case GF_AVC_NALU_ACCESS_UNIT: fputs("AccessUnit delimiter", dump); break;
+       case GF_AVC_NALU_END_OF_SEQ: fputs("EndOfSequence", dump); break;
+       case GF_AVC_NALU_END_OF_STREAM: fputs("EndOfStream", dump); break;
+       case GF_AVC_NALU_FILLER_DATA: fputs("Filler data", dump); break;
+       case GF_AVC_NALU_SEQ_PARAM_EXT: fputs("SequenceParameterSetExtension", dump); break;
+       case GF_AVC_NALU_SVC_PREFIX_NALU: fputs("SVCPrefix", dump); break;
+       case GF_AVC_NALU_SVC_SUBSEQ_PARAM: fputs("SVCSubsequenceParameterSet", dump); break;
+       case GF_AVC_NALU_SLICE_AUX: fputs("Auxiliary Slice", dump); break;
+
+       case GF_AVC_NALU_SVC_SLICE: 
+               fputs(is_svc ? "SVCSlice" : "CodedSliceExtension", dump);
+               dependency_id = (ptr[2] & 0x70) >> 4;
+               quality_id = (ptr[2] & 0x0F);
+               temporal_id = (ptr[3] & 0xE0) >> 5;
+               fprintf(dump, "\" dependency_id=\"%d\" quality_id=\"%d\" temporal_id=\"%d", dependency_id, quality_id, temporal_id);
+               break;
+       case 30: fputs("SVCAggregator", dump); break;
+       case 31:
+               fputs("SVCExtractor", dump); 
+               track_ref_index = (u8) ptr[4];
+               data_offset = (ptr[6] << 12) + (ptr[7] << 8) + (ptr[8] << 4) + ptr[9];
+               fprintf(dump, "\" track_ref_index=\"%d\" data_offset=\"%d", track_ref_index, data_offset);
+               break;
+
+       default:
+               fputs("UNKNOWN", dump); break;
+       }
+       fputs("\"", dump);
+}
+
+void dump_file_nal(GF_ISOFile *file, u32 trackID, char *inName)
+{
+       u32 i, count, track, nalh_size;
+       FILE *dump;
+#ifndef GPAC_DISABLE_AV_PARSERS
+       GF_AVCConfig *avccfg, *svccfg;
+       GF_AVCConfigSlot *slc;
+#endif
+
+       if (inName) {
+               char szBuf[GF_MAX_PATH];
+               strcpy(szBuf, inName);
+               sprintf(szBuf, "%s_%d_nalu.xml", inName, trackID);
+               dump = gf_f64_open(szBuf, "wt");
+       } else {
+               dump = stderr;
+       }
+       track = gf_isom_get_track_by_id(file, trackID);
+
+       count = gf_isom_get_sample_count(file, track);
+
+       fprintf(dump, "<NALUTrack trackID=\"%d\" SampleCount=\"%d\">\n", trackID, count);
+
+#ifndef GPAC_DISABLE_AV_PARSERS
+       avccfg = gf_isom_avc_config_get(file, track, 1);
+       svccfg = gf_isom_svc_config_get(file, track, 1);
+       fprintf(dump, " <NALUConfig>\n");
+
+#define DUMP_ARRAY(arr, name)\
+       if (arr) {\
+               for (i=0; i<gf_list_count(arr); i++) {\
+                       slc = gf_list_get(arr, i);\
+                       fprintf(dump, "  <%s number=\"%d\" ", name, i+1);\
+                       dump_nalu_type_name(dump, slc->data , svccfg ? 1 : 0);\
+                       fprintf(dump, ">\n");\
+               }\
+       }\
+
+       nalh_size = 0;
+
+       if (avccfg) {
+               nalh_size = avccfg->nal_unit_size;
+
+               DUMP_ARRAY(avccfg->sequenceParameterSets, "AVCSPSArray")
+               DUMP_ARRAY(avccfg->pictureParameterSets, "AVCPPSArray")
+               DUMP_ARRAY(avccfg->sequenceParameterSetExtensions, "AVCSPSExArray")
+       }
+       if (svccfg) {
+               if (!nalh_size) nalh_size = svccfg->nal_unit_size;
+               DUMP_ARRAY(svccfg->sequenceParameterSets, "SVCSPSArray")
+               DUMP_ARRAY(svccfg->pictureParameterSets, "SVCPPSArray")
+       }
+#endif
+       fprintf(dump, " </NALUConfig>\n");
+
+       fprintf(dump, " <NALUSamples>\n");
+       for (i=0; i<count; i++) {
+               u64 dts, cts;
+               u32 size, nal_size, idx;
+               char *ptr;
+               GF_ISOSample *samp = gf_isom_get_sample(file, track, i+1, NULL);
+               dts = samp->DTS;
+               cts = dts + (s32) samp->CTS_Offset;
+
+               fprintf(dump, "  <Sample number=\"%d\" DTS=\""LLD"\" CTS=\""LLD"\" size=\"%d\" RAP=\"%d\" >\n", i+1, dts, cts, samp->dataLength, samp->IsRAP);
+               if (cts<dts) fprintf(dump, "<!-- NEGATIVE CTS OFFSET! -->\n"); 
+       
+               idx = 1;
+               ptr = samp->data;
+               size = samp->dataLength;
+               while (size) {
+                       u32 v = nalh_size;
+                       nal_size = 0;
+                       while (v) {
+                               nal_size |= (u8) *ptr;
+                               ptr++;
+                               v-=1;
+                               if (v) nal_size<<=8;
+                       }
+                       if (nalh_size + nal_size > size) {
+                               fprintf(dump, "   <!-- NALU number %d is corrupted: size is %d but only %d remains -->\n", idx, nal_size, size);
+                               break;
+                       } else {
+                               fprintf(dump, "   <NALU number=\"%d\" size=\"%d\" ", idx, nal_size);
+                               dump_nalu_type_name(dump, ptr, svccfg ? 1 : 0);
+                               fprintf(dump, "/>\n");
+                       }
+                       idx++;
+                       ptr+=nal_size;
+                       size -= nal_size + nalh_size;
+               }
+               fprintf(dump, "  </Sample>\n");
+               gf_isom_sample_del(&samp);
+
+               fprintf(dump, "\n");
+               gf_set_progress("Analysing Track NALUs", i+1, count);
+       }
+       fprintf(dump, " </NALUSamples>\n");
+       fprintf(dump, "</NALUTrack>\n");
+
+       if (inName) fclose(dump);
 }
 
 #ifndef GPAC_DISABLE_ISOM_DUMP
@@ -877,7 +1036,7 @@ void dump_file_ismacryp(GF_ISOFile *file, char *inName)
                strcat(szBuf, "_ismacryp.xml");
                dump = gf_f64_open(szBuf, "wt");
        } else {
-               dump = stdout;
+               dump = stderr;
        }
 
        fprintf(dump, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
@@ -910,7 +1069,7 @@ void dump_timed_text_track(GF_ISOFile *file, u32 trackID, char *inName, Bool is_
 
        track = gf_isom_get_track_by_id(file, trackID);
        if (!track) {
-               fprintf(stdout, "Cannot find track ID %d\n", trackID);
+               fprintf(stderr, "Cannot find track ID %d\n", trackID);
                return;
        }
 
@@ -919,7 +1078,7 @@ void dump_timed_text_track(GF_ISOFile *file, u32 trackID, char *inName, Bool is_
        case GF_ISOM_MEDIA_SUBT:
                break;
        default:
-               fprintf(stdout, "Track ID %d is not a 3GPP text track\n", trackID);
+               fprintf(stderr, "Track ID %d is not a 3GPP text track\n", trackID);
                return;
        }
 
@@ -935,8 +1094,8 @@ void dump_timed_text_track(GF_ISOFile *file, u32 trackID, char *inName, Bool is_
        e = gf_isom_text_dump(file, track, dump, dump_type);
        if (inName) fclose(dump);
 
-       if (e) fprintf(stdout, "Conversion failed (%s)\n", gf_error_to_string(e));
-       else fprintf(stdout, "Conversion done\n");
+       if (e) fprintf(stderr, "Conversion failed (%s)\n", gf_error_to_string(e));
+       else fprintf(stderr, "Conversion done\n");
 }
 
 #endif /*GPAC_DISABLE_ISOM_DUMP*/
@@ -958,7 +1117,7 @@ void DumpSDP(GF_ISOFile *file, char *inName)
                strcat(szBuf, "_sdp.txt");
                dump = gf_f64_open(szBuf, "wt");
        } else {
-               dump = stdout;
+               dump = stderr;
                fprintf(dump, "* File SDP content *\n\n");
        }
        //get the movie SDP
@@ -981,6 +1140,10 @@ void DumpSDP(GF_ISOFile *file, char *inName)
 static char *format_duration(u64 dur, u32 timescale, char *szDur)
 {
        u32 h, m, s, ms;
+       if ((dur==(u64) -1) || (dur==(u32) -1))  {
+               strcpy(szDur, "Unknown");
+               return szDur;
+       }
        dur = (u64) (( ((Double) (s64) dur)/timescale)*1000);
        h = (u32) (dur / 3600000);
        m = (u32) (dur/ 60000) - h*60;
@@ -1055,27 +1218,27 @@ static void DumpMetaItem(GF_ISOFile *file, Bool root_meta, u32 tk_num, char *nam
 
        count = gf_isom_get_meta_item_count(file, root_meta, tk_num);
        primary_id = gf_isom_get_meta_primary_item_id(file, root_meta, tk_num);
-       fprintf(stdout, "%s type: \"%s\" - %d resource item(s)\n", name, gf_4cc_to_str(brand), (count+(primary_id>0)));
+       fprintf(stderr, "%s type: \"%s\" - %d resource item(s)\n", name, gf_4cc_to_str(brand), (count+(primary_id>0)));
        switch (gf_isom_has_meta_xml(file, root_meta, tk_num)) {
-       case 1: fprintf(stdout, "Meta has XML resource\n"); break;
-       case 2: fprintf(stdout, "Meta has BinaryXML resource\n"); break;
+       case 1: fprintf(stderr, "Meta has XML resource\n"); break;
+       case 2: fprintf(stderr, "Meta has BinaryXML resource\n"); break;
        }
        if (primary_id) {
-               fprintf(stdout, "Primary Item - ID %d\n", primary_id); 
+               fprintf(stderr, "Primary Item - ID %d\n", primary_id); 
        } 
        for (i=0; i<count; i++) {
                const char *it_name, *mime, *enc, *url, *urn;
                Bool self_ref;
                u32 ID;
                gf_isom_get_meta_item_info(file, root_meta, tk_num, i+1, &ID, NULL, &self_ref, &it_name, &mime, &enc, &url, &urn);
-               fprintf(stdout, "Item #%d - ID %d", i+1, ID);
-               if (self_ref) fprintf(stdout, " - Self-Reference");
-               else if (it_name) fprintf(stdout, " - Name: %s", it_name);
-               if (mime) fprintf(stdout, " - MimeType: %s", mime);
-               if (enc) fprintf(stdout, " - ContentEncoding: %s", enc);
-               fprintf(stdout, "\n");
-               if (url) fprintf(stdout, "URL: %s\n", url);
-               if (urn) fprintf(stdout, "URN: %s\n", urn);
+               fprintf(stderr, "Item #%d - ID %d", i+1, ID);
+               if (self_ref) fprintf(stderr, " - Self-Reference");
+               else if (it_name) fprintf(stderr, " - Name: %s", it_name);
+               if (mime) fprintf(stderr, " - MimeType: %s", mime);
+               if (enc) fprintf(stderr, " - ContentEncoding: %s", enc);
+               fprintf(stderr, "\n");
+               if (url) fprintf(stderr, "URL: %s\n", url);
+               if (urn) fprintf(stderr, "URN: %s\n", urn);
        }
 }
 
@@ -1083,7 +1246,7 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
 {
        Float scale;
        Bool is_od_track = 0;
-       u32 trackNum, i, j, max_rate, rate, ts, mtype, msub_type, timescale, sr, nb_ch, count, alt_group, nb_groups;
+       u32 trackNum, i, j, max_rate, rate, ts, mtype, msub_type, timescale, sr, nb_ch, count, alt_group, nb_groups, nb_edits;
        u64 time_slice, dur, size;
        u8 bps;
        GF_ESD *esd;
@@ -1091,39 +1254,43 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
 
        trackNum = gf_isom_get_track_by_id(file, trackID);
        if (!trackNum) {
-               fprintf(stdout, "No track with ID %d found\n", trackID);
+               fprintf(stderr, "No track with ID %d found\n", trackID);
                return;
        }
 
        timescale = gf_isom_get_media_timescale(file, trackNum);
-       fprintf(stdout, "Track # %d Info - TrackID %d - TimeScale %d - Duration %s\n", trackNum, trackID, timescale, format_duration(gf_isom_get_media_duration(file, trackNum), timescale, szDur));
-       if (gf_isom_is_track_in_root_od(file, trackNum) ) fprintf(stdout, "Track is present in Root OD\n");
-       if (!gf_isom_is_track_enabled(file, trackNum))  fprintf(stdout, "Track is disabled\n");
+       fprintf(stderr, "Track # %d Info - TrackID %d - TimeScale %d - Media Duration %s\n", trackNum, trackID, timescale, format_duration(gf_isom_get_media_duration(file, trackNum), timescale, szDur));
+       nb_edits = gf_isom_get_edit_segment_count(file, trackNum);
+       if (nb_edits)
+               fprintf(stderr, "Track has %d edit lists: track duration is %s\n", nb_edits, format_duration(gf_isom_get_track_duration(file, trackNum), gf_isom_get_timescale(file), szDur));
+
+       if (gf_isom_is_track_in_root_od(file, trackNum) ) fprintf(stderr, "Track is present in Root OD\n");
+       if (!gf_isom_is_track_enabled(file, trackNum))  fprintf(stderr, "Track is disabled\n");
        gf_isom_get_media_language(file, trackNum, sType);
-       fprintf(stdout, "Media Info: Language \"%s\" - ", GetLanguage(sType) );
+       fprintf(stderr, "Media Info: Language \"%s\" - ", GetLanguage(sType) );
        mtype = gf_isom_get_media_type(file, trackNum);
-       fprintf(stdout, "Type \"%s:", gf_4cc_to_str(mtype));
+       fprintf(stderr, "Type \"%s:", gf_4cc_to_str(mtype));
        msub_type = gf_isom_get_mpeg4_subtype(file, trackNum, 1);
        if (!msub_type) msub_type = gf_isom_get_media_subtype(file, trackNum, 1);
-       fprintf(stdout, "%s\" - %d samples\n", gf_4cc_to_str(msub_type), gf_isom_get_sample_count(file, trackNum));
+       fprintf(stderr, "%s\" - %d samples\n", gf_4cc_to_str(msub_type), gf_isom_get_sample_count(file, trackNum));
        
        if (!gf_isom_is_self_contained(file, trackNum, 1)) {
                const char *url, *urn;
                gf_isom_get_data_reference(file, trackNum, 1, &url, &urn);
-               fprintf(stdout, "Media Data Location: %s\n", url ? url : urn);
+               fprintf(stderr, "Media Data Location: %s\n", url ? url : urn);
        }
 
        if (full_dump) {
                const char *handler_name;
                gf_isom_get_handler_name(file, trackNum, &handler_name);
-               fprintf(stdout, "Handler name: %s\n", handler_name);
+               fprintf(stderr, "Handler name: %s\n", handler_name);
        }
 
        if (mtype==GF_ISOM_MEDIA_VISUAL) {
                s32 tx, ty;
                u32 w, h;
                gf_isom_get_track_layout_info(file, trackNum, &w, &h, &tx, &ty, NULL);
-               fprintf(stdout, "Visual Track layout: x=%d y=%d width=%d height=%d\n", tx, ty, w, h);
+               fprintf(stderr, "Visual Track layout: x=%d y=%d width=%d height=%d\n", tx, ty, w, h);
        }
 
        gf_isom_get_audio_info(file, trackNum, 1, &sr, &nb_ch, &bps);
@@ -1138,14 +1305,14 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
        )  {
                esd = gf_isom_get_esd(file, trackNum, 1);
                if (!esd) {
-                       fprintf(stdout, "WARNING: Broken MPEG-4 Track\n");
+                       fprintf(stderr, "WARNING: Broken MPEG-4 Track\n");
                } else {
                        const char *st = gf_odf_stream_type_name(esd->decoderConfig->streamType);
                        if (st) {
-                               fprintf(stdout, "MPEG-4 Config%s%s Stream - ObjectTypeIndication 0x%02x\n",
+                               fprintf(stderr, "MPEG-4 Config%s%s Stream - ObjectTypeIndication 0x%02x\n",
                                                        full_dump ? "\n\t" : ": ", st, esd->decoderConfig->objectTypeIndication);
                        } else {
-                               fprintf(stdout, "MPEG-4 Config%sStream Type 0x%02x - ObjectTypeIndication 0x%02x\n",
+                               fprintf(stderr, "MPEG-4 Config%sStream Type 0x%02x - ObjectTypeIndication 0x%02x\n",
                                                        full_dump ? "\n\t" : ": ", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication);
                        }
                        if (esd->decoderConfig->streamType==GF_STREAM_OD) 
@@ -1159,18 +1326,18 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
 #ifndef GPAC_DISABLE_AV_PARSERS
                                        GF_M4VDecSpecInfo dsi;
                                        gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);
-                                       if (full_dump) fprintf(stdout, "\t");
+                                       if (full_dump) fprintf(stderr, "\t");
                                        w = dsi.width;
                                        h = dsi.height;
-                                       fprintf(stdout, "MPEG-4 Visual Size %d x %d - %s\n", w, h, gf_m4v_get_profile_name(dsi.VideoPL));
+                                       fprintf(stderr, "MPEG-4 Visual Size %d x %d - %s\n", w, h, gf_m4v_get_profile_name(dsi.VideoPL));
                                        if (dsi.par_den && dsi.par_num) {
                                                u32 tw, th;
                                                gf_isom_get_track_layout_info(file, trackNum, &tw, &th, NULL, NULL, NULL);
-                                               fprintf(stdout, "Pixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", dsi.par_num, dsi.par_den, tw, th);
+                                               fprintf(stderr, "Pixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", dsi.par_num, dsi.par_den, tw, th);
                                        }
 #else
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       fprintf(stdout, "MPEG-4 Visual Size %d x %d\n", w, h);
+                                       fprintf(stderr, "MPEG-4 Visual Size %d x %d\n", w, h);
 #endif
 
                                } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) {
@@ -1181,41 +1348,44 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
 #endif
 
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       if (full_dump) fprintf(stdout, "\t");
-                                       fprintf(stdout, "AVC/H264 Video - Visual Size %d x %d\n", w, h);
+                                       if (full_dump) fprintf(stderr, "\t");
+                                       fprintf(stderr, "AVC/H264 Video - Visual Size %d x %d\n", w, h);
 #ifndef GPAC_DISABLE_AV_PARSERS
                                        avccfg = gf_isom_avc_config_get(file, trackNum, 1);
                                        svccfg = gf_isom_svc_config_get(file, trackNum, 1);
                                        if (!avccfg && !svccfg) {
-                                               fprintf(stdout, "\n\n\tNon-compliant AVC track: SPS/PPS not found in sample description\n");
+                                               fprintf(stderr, "\n\n\tNon-compliant AVC track: SPS/PPS not found in sample description\n");
                                        } else if (avccfg) {
-                                               fprintf(stdout, "\tAVC Info: %d SPS - %d PPS", gf_list_count(avccfg->sequenceParameterSets) , gf_list_count(avccfg->pictureParameterSets) );
-                                               fprintf(stdout, " - Profile %s @ Level %g\n", gf_avc_get_profile_name(avccfg->AVCProfileIndication), ((Double)avccfg->AVCLevelIndication)/10.0 );
-                                               fprintf(stdout, "\tNAL Unit length bits: %d\n", 8*avccfg->nal_unit_size);
+                                               fprintf(stderr, "\tAVC Info: %d SPS - %d PPS", gf_list_count(avccfg->sequenceParameterSets) , gf_list_count(avccfg->pictureParameterSets) );
+                                               fprintf(stderr, " - Profile %s @ Level %g\n", gf_avc_get_profile_name(avccfg->AVCProfileIndication), ((Double)avccfg->AVCLevelIndication)/10.0 );
+                                               fprintf(stderr, "\tNAL Unit length bits: %d\n", 8*avccfg->nal_unit_size);
                                                slc = gf_list_get(avccfg->sequenceParameterSets, 0);
                                                if (slc) {
                                                        gf_avc_get_sps_info(slc->data, slc->size, NULL, NULL, NULL, &par_n, &par_d);
                                                        if ((par_n>0) && (par_d>0)) {
                                                                u32 tw, th;
                                                                gf_isom_get_track_layout_info(file, trackNum, &tw, &th, NULL, NULL, NULL);
-                                                               fprintf(stdout, "\tPixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th);
+                                                               fprintf(stderr, "\tPixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th);
                                                        }
                                                }
+                                               if (avccfg->chroma_bit_depth) {
+                                                       fprintf(stderr, "\tChroma format %d - Luma bit depth %d - chroma bot depth %d\n", avccfg->chroma_format, avccfg->luma_bit_depth, avccfg->chroma_bit_depth);
+                                               }
                                                gf_odf_avc_cfg_del(avccfg);
                                        }
                                        if (svccfg) {
-                                               fprintf(stdout, "\n\tSVC Info: %d SPS - %d PPS - Profile %s @ Level %g\n", gf_list_count(svccfg->sequenceParameterSets) , gf_list_count(svccfg->pictureParameterSets), gf_avc_get_profile_name(svccfg->AVCProfileIndication), ((Double)svccfg->AVCLevelIndication)/10.0 );
-                                               fprintf(stdout, "\tSVC NAL Unit length bits: %d\n", 8*svccfg->nal_unit_size);
+                                               fprintf(stderr, "\n\tSVC Info: %d SPS - %d PPS - Profile %s @ Level %g\n", gf_list_count(svccfg->sequenceParameterSets) , gf_list_count(svccfg->pictureParameterSets), gf_avc_get_profile_name(svccfg->AVCProfileIndication), ((Double)svccfg->AVCLevelIndication)/10.0 );
+                                               fprintf(stderr, "\tSVC NAL Unit length bits: %d\n", 8*svccfg->nal_unit_size);
                                                for (i=0; i<gf_list_count(svccfg->sequenceParameterSets); i++) {
                                                        slc = gf_list_get(svccfg->sequenceParameterSets, i);
                                                        if (slc) {
                                                                u32 s_w, s_h, sps_id;
                                                                gf_avc_get_sps_info(slc->data, slc->size, &sps_id, &s_w, &s_h, &par_n, &par_d);
-                                                               fprintf(stdout, "\t\tSSPS ID %d - Visual Size %d x %d\n", sps_id, s_w, s_h);
+                                                               fprintf(stderr, "\t\tSSPS ID %d - Visual Size %d x %d\n", sps_id, s_w, s_h);
                                                                if ((par_n>0) && (par_d>0)) {
                                                                        u32 tw, th;
                                                                        gf_isom_get_track_layout_info(file, trackNum, &tw, &th, NULL, NULL, NULL);
-                                                                       fprintf(stdout, "\tPixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th);
+                                                                       fprintf(stderr, "\tPixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th);
                                                                }
                                                        }
                                                }
@@ -1227,30 +1397,30 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
                                else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_MEDIA_OGG) {
                                        char *szName;
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       if (full_dump) fprintf(stdout, "\t");
+                                       if (full_dump) fprintf(stderr, "\t");
                                        if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[3], "theora", 6)) szName = "Theora";
                                        else szName = "Unknown";
-                                       fprintf(stdout, "Ogg/%s video / GPAC Mux  - Visual Size %d x %d\n", szName, w, h);
+                                       fprintf(stderr, "Ogg/%s video / GPAC Mux  - Visual Size %d x %d\n", szName, w, h);
                                }
                                else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG) {
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       fprintf(stdout, "JPEG Stream - Visual Size %d x %d\n", w, h);
+                                       fprintf(stderr, "JPEG Stream - Visual Size %d x %d\n", w, h);
                                }
                                else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_PNG) {
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       fprintf(stdout, "PNG Stream - Visual Size %d x %d\n", w, h);
+                                       fprintf(stderr, "PNG Stream - Visual Size %d x %d\n", w, h);
                                }
                                else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG_2000) {
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       fprintf(stdout, "JPEG2000 Stream - Visual Size %d x %d\n", w, h);
+                                       fprintf(stderr, "JPEG2000 Stream - Visual Size %d x %d\n", w, h);
                                }
                                if (!w || !h) {
                                        gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-                                       if (full_dump) fprintf(stdout, "\t");
-                                       fprintf(stdout, "Visual Size %d x %d\n", w, h);
+                                       if (full_dump) fprintf(stderr, "\t");
+                                       fprintf(stderr, "Visual Size %d x %d\n", w, h);
                                }
                                if (gf_isom_get_rvc_config(file, trackNum, 1, &rvc_predef, NULL, NULL, NULL)==GF_OK) {
-                                       fprintf(stdout, "Has RVC signaled - Predefined configuration %d\n", rvc_predef);
+                                       fprintf(stderr, "Has RVC signaled - Predefined configuration %d\n", rvc_predef);
                                }
 
                        } else if (esd->decoderConfig->streamType==GF_STREAM_AUDIO) {
@@ -1271,29 +1441,29 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
                                                e = GF_NON_COMPLIANT_BITSTREAM;
                                        else
                                                e = gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg);
-                                       if (full_dump) fprintf(stdout, "\t");
-                                       if (e) fprintf(stdout, "Corrupted AAC Config\n");
+                                       if (full_dump) fprintf(stderr, "\t");
+                                       if (e) fprintf(stderr, "Corrupted AAC Config\n");
                                        else {
-                                               fprintf(stdout, "MPEG-%d Audio %s - %d Channel(s) - SampleRate %d", is_mp2 ? 2 : 4, gf_m4a_object_type_name(a_cfg.base_object_type), a_cfg.nb_chan, a_cfg.base_sr);
-                                               if (a_cfg.has_sbr) fprintf(stdout, " - SBR SampleRate %d", a_cfg.sbr_sr);
-                                               if (a_cfg.has_ps) fprintf(stdout, " - PS");
-                                               fprintf(stdout, "\n");
+                                               fprintf(stderr, "MPEG-%d Audio %s - %d Channel(s) - SampleRate %d", is_mp2 ? 2 : 4, gf_m4a_object_type_name(a_cfg.base_object_type), a_cfg.nb_chan, a_cfg.base_sr);
+                                               if (a_cfg.has_sbr) fprintf(stderr, " - SBR SampleRate %d", a_cfg.sbr_sr);
+                                               if (a_cfg.has_ps) fprintf(stderr, " - PS");
+                                               fprintf(stderr, "\n");
                                        }
 #else
-                                       fprintf(stdout, "MPEG-2/4 Audio - %d Channels - SampleRate %d\n", nb_ch, sr);
+                                       fprintf(stderr, "MPEG-2/4 Audio - %d Channels - SampleRate %d\n", nb_ch, sr);
 #endif
                                        break;
                                case GPAC_OTI_AUDIO_MPEG2_PART3:
                                case GPAC_OTI_AUDIO_MPEG1:
                                        if (msub_type == GF_ISOM_SUBTYPE_MPEG4_CRYP) {
-                                               fprintf(stdout, "MPEG-1/2 Audio - %d Channels - SampleRate %d\n", nb_ch, sr);
+                                               fprintf(stderr, "MPEG-1/2 Audio - %d Channels - SampleRate %d\n", nb_ch, sr);
                                        } else {
 #ifndef GPAC_DISABLE_AV_PARSERS
                                                GF_ISOSample *samp = gf_isom_get_sample(file, trackNum, 1, &oti);
                                                if (samp) {
                                                        oti = GF_4CC((u8)samp->data[0], (u8)samp->data[1], (u8)samp->data[2], (u8)samp->data[3]);
-                                                       if (full_dump) fprintf(stdout, "\t");
-                                                       fprintf(stdout, "%s Audio - %d Channel(s) - SampleRate %d - Layer %d\n",
+                                                       if (full_dump) fprintf(stderr, "\t");
+                                                       fprintf(stderr, "%s Audio - %d Channel(s) - SampleRate %d - Layer %d\n",
                                                                gf_mp3_version_name(oti),
                                                                gf_mp3_num_channels(oti), 
                                                                gf_mp3_sampling_rate(oti), 
@@ -1301,10 +1471,10 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
                                                        );
                                                        gf_isom_sample_del(&samp);
                                                } else {
-                                                       fprintf(stdout, "\n\tError fetching sample: %s\n", gf_error_to_string(gf_isom_last_error(file)) );
+                                                       fprintf(stderr, "\n\tError fetching sample: %s\n", gf_error_to_string(gf_isom_last_error(file)) );
                                                }
 #else
-                                               fprintf(stdout, "MPEG-1/2 Audio - %d Channels - SampleRate %d\n", nb_ch, sr);
+                                               fprintf(stderr, "MPEG-1/2 Audio - %d Channels - SampleRate %d\n", nb_ch, sr);
 #endif
                                        }
                                        break;
@@ -1312,23 +1482,23 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
                                case GPAC_OTI_MEDIA_OGG:
                                {
                                        char *szName;
-                                       if (full_dump) fprintf(stdout, "\t");
+                                       if (full_dump) fprintf(stderr, "\t");
                                        if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[3], "vorbis", 6)) szName = "Vorbis";
                                        else if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[2], "Speex", 5)) szName = "Speex";
                                        else if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[2], "Flac", 4)) szName = "Flac";
                                        else szName = "Unknown";
-                                       fprintf(stdout, "Ogg/%s audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", szName, sr, nb_ch);
+                                       fprintf(stderr, "Ogg/%s audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", szName, sr, nb_ch);
                                }
                                        break;
-                               case GPAC_OTI_AUDIO_EVRC_VOICE: fprintf(stdout, "EVRC Audio - Sample Rate 8000 - 1 channel\n"); break;
-                               case GPAC_OTI_AUDIO_SMV_VOICE: fprintf(stdout, "SMV Audio - Sample Rate 8000 - 1 channel\n"); break;
-                               case GPAC_OTI_AUDIO_13K_VOICE: fprintf(stdout, "QCELP Audio - Sample Rate 8000 - 1 channel\n"); break;
+                               case GPAC_OTI_AUDIO_EVRC_VOICE: fprintf(stderr, "EVRC Audio - Sample Rate 8000 - 1 channel\n"); break;
+                               case GPAC_OTI_AUDIO_SMV_VOICE: fprintf(stderr, "SMV Audio - Sample Rate 8000 - 1 channel\n"); break;
+                               case GPAC_OTI_AUDIO_13K_VOICE: fprintf(stderr, "QCELP Audio - Sample Rate 8000 - 1 channel\n"); break;
                                /*packetVideo hack for EVRC...*/
                                case 0xD1: 
                                        if (esd->decoderConfig->decoderSpecificInfo && (esd->decoderConfig->decoderSpecificInfo->dataLength==8)
                                        && !strnicmp(esd->decoderConfig->decoderSpecificInfo->data, "pvmm", 4)) {
-                                               if (full_dump) fprintf(stdout, "\t");
-                                               fprintf(stdout, "EVRC Audio (PacketVideo Mux) - Sample Rate 8000 - 1 channel\n"); 
+                                               if (full_dump) fprintf(stderr, "\t");
+                                               fprintf(stderr, "EVRC Audio (PacketVideo Mux) - Sample Rate 8000 - 1 channel\n"); 
                                        }
                                        break;
                                }
@@ -1336,45 +1506,45 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
                        else if (esd->decoderConfig->streamType==GF_STREAM_SCENE) {
                                if (esd->decoderConfig->objectTypeIndication<=4) {
                                        GF_BIFSConfig *b_cfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication);
-                                       fprintf(stdout, "BIFS Scene description - %s stream\n", b_cfg->elementaryMasks ? "Animation" : "Command"); 
+                                       fprintf(stderr, "BIFS Scene description - %s stream\n", b_cfg->elementaryMasks ? "Animation" : "Command"); 
                                        if (full_dump && !b_cfg->elementaryMasks) {
-                                               fprintf(stdout, "\tWidth %d Height %d Pixel Metrics %s\n", b_cfg->pixelWidth, b_cfg->pixelHeight, b_cfg->pixelMetrics ? "yes" : "no"); 
+                                               fprintf(stderr, "\tWidth %d Height %d Pixel Metrics %s\n", b_cfg->pixelWidth, b_cfg->pixelHeight, b_cfg->pixelMetrics ? "yes" : "no"); 
                                        }
                                        gf_odf_desc_del((GF_Descriptor *)b_cfg);
                                } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_AFX) {
                                        u8 tag = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data[0] : 0xFF;
                                        const char *afxtype = gf_afx_get_type_description(tag);
-                                       fprintf(stdout, "AFX Stream - type %s (%d)\n", afxtype, tag); 
+                                       fprintf(stderr, "AFX Stream - type %s (%d)\n", afxtype, tag); 
                                } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_FONT) {
-                                       fprintf(stdout, "Font Data stream\n"); 
+                                       fprintf(stderr, "Font Data stream\n"); 
                                } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_LASER) {
                                        GF_LASERConfig l_cfg;
                                        gf_odf_get_laser_config(esd->decoderConfig->decoderSpecificInfo, &l_cfg);
-                                       fprintf(stdout, "LASER Stream - %s\n", l_cfg.newSceneIndicator ? "Full Scene" : "Scene Segment"); 
+                                       fprintf(stderr, "LASER Stream - %s\n", l_cfg.newSceneIndicator ? "Full Scene" : "Scene Segment"); 
                                } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_TEXT_MPEG4) {
-                                       fprintf(stdout, "MPEG-4 Streaming Text stream\n"); 
+                                       fprintf(stderr, "MPEG-4 Streaming Text stream\n"); 
                                } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_SYNTHESIZED_TEXTURE) {
-                                       fprintf(stdout, "Synthetized Texture stream stream\n"); 
+                                       fprintf(stderr, "Synthetized Texture stream stream\n"); 
                                } else {
-                                       fprintf(stdout, "Unknown Systems stream OTI %d\n", esd->decoderConfig->objectTypeIndication); 
+                                       fprintf(stderr, "Unknown Systems stream OTI %d\n", esd->decoderConfig->objectTypeIndication); 
                                }
                        }
 
                        /*sync is only valid if we open all tracks to take care of default MP4 sync..*/
                        if (!full_dump) {
                                if (!esd->OCRESID || (esd->OCRESID == esd->ESID))
-                                       fprintf(stdout, "Self-synchronized\n");
+                                       fprintf(stderr, "Self-synchronized\n");
                                else
-                                       fprintf(stdout, "Synchronized on stream %d\n", esd->OCRESID);
+                                       fprintf(stderr, "Synchronized on stream %d\n", esd->OCRESID);
                        } else {
-                               fprintf(stdout, "\tDecoding Buffer size %d - Average bitrate %d kbps - Max Bitrate %d kbps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate/1000, esd->decoderConfig->maxBitrate/1000);
+                               fprintf(stderr, "\tDecoding Buffer size %d - Average bitrate %d kbps - Max Bitrate %d kbps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate/1000, esd->decoderConfig->maxBitrate/1000);
                                if (esd->dependsOnESID)
-                                       fprintf(stdout, "\tDepends on stream %d for decoding\n", esd->dependsOnESID);
+                                       fprintf(stderr, "\tDepends on stream %d for decoding\n", esd->dependsOnESID);
                                else
-                                       fprintf(stdout, "\tNo stream dependencies for decoding\n");
+                                       fprintf(stderr, "\tNo stream dependencies for decoding\n");
 
-                               fprintf(stdout, "\tStreamPriority %d\n", esd->streamPriority);
-                               if (esd->URLString) fprintf(stdout, "\tRemote Data Source %s\n", esd->URLString);
+                               fprintf(stderr, "\tStreamPriority %d\n", esd->streamPriority);
+                               if (esd->URLString) fprintf(stderr, "\tRemote Data Source %s\n", esd->URLString);
                        }
                        gf_odf_desc_del((GF_Descriptor *) esd);
 
@@ -1387,44 +1557,44 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
 
                                if (gf_isom_is_ismacryp_media(file, trackNum, 1)) {
                                        gf_isom_get_ismacryp_info(file, trackNum, 1, NULL, &scheme_type, &version, &scheme_URI, &KMS_URI, &use_sel_enc, &IV_size, NULL);
-                                       fprintf(stdout, "\n*Encrypted stream - ISMA scheme %s (version %d)\n", gf_4cc_to_str(scheme_type), version);
-                                       if (scheme_URI) fprintf(stdout, "scheme location: %s\n", scheme_URI);
+                                       fprintf(stderr, "\n*Encrypted stream - ISMA scheme %s (version %d)\n", gf_4cc_to_str(scheme_type), version);
+                                       if (scheme_URI) fprintf(stderr, "scheme location: %s\n", scheme_URI);
                                        if (KMS_URI) {
-                                               if (!strnicmp(KMS_URI, "(key)", 5)) fprintf(stdout, "KMS location: key in file\n");
-                                               else fprintf(stdout, "KMS location: %s\n", KMS_URI);
+                                               if (!strnicmp(KMS_URI, "(key)", 5)) fprintf(stderr, "KMS location: key in file\n");
+                                               else fprintf(stderr, "KMS location: %s\n", KMS_URI);
                                        }
-                                       fprintf(stdout, "Selective Encryption: %s\n", use_sel_enc ? "Yes" : "No");
-                                       if (IV_size) fprintf(stdout, "Initialization Vector size: %d bits\n", IV_size*8);
+                                       fprintf(stderr, "Selective Encryption: %s\n", use_sel_enc ? "Yes" : "No");
+                                       if (IV_size) fprintf(stderr, "Initialization Vector size: %d bits\n", IV_size*8);
                                } else if (gf_isom_is_omadrm_media(file, trackNum, 1)) {
                                        const char *textHdrs;
                                        u32 enc_type, hdr_len;
                                        u64 orig_len;
-                                       fprintf(stdout, "\n*Encrypted stream - OMA DRM\n");
+                                       fprintf(stderr, "\n*Encrypted stream - OMA DRM\n");
                                        gf_isom_get_omadrm_info(file, trackNum, 1, NULL, NULL, NULL, &scheme_URI, &KMS_URI, &textHdrs, &hdr_len, &orig_len, &enc_type, &use_sel_enc, &IV_size, NULL);
-                                       fprintf(stdout, "Rights Issuer: %s\n", KMS_URI);
-                                       fprintf(stdout, "Content ID: %s\n", scheme_URI);
+                                       fprintf(stderr, "Rights Issuer: %s\n", KMS_URI);
+                                       fprintf(stderr, "Content ID: %s\n", scheme_URI);
                                        if (textHdrs) {
                                                u32 i, offset;
                                                const char *start = textHdrs;
-                                               fprintf(stdout, "OMA Textual Headers:\n");
+                                               fprintf(stderr, "OMA Textual Headers:\n");
                                                i=offset=0;
                                                while (i<hdr_len) {
                                                        if (start[i]==0) {
-                                                               fprintf(stdout, "\t%s\n", start+offset);
+                                                               fprintf(stderr, "\t%s\n", start+offset);
                                                                offset=i+1;
                                                        }
                                                        i++;
                                                }
-                                               fprintf(stdout, "\t%s\n", start+offset);
+                                               fprintf(stderr, "\t%s\n", start+offset);
                                        }
-                                       if (orig_len) fprintf(stdout, "Original media size "LLD"\n", LLD_CAST orig_len);
-                                       fprintf(stdout, "Encryption algorithm %s\n", (enc_type==1) ? "AEA 128 CBC" : (enc_type ? "AEA 128 CTR" : "None"));
+                                       if (orig_len) fprintf(stderr, "Original media size "LLD"\n", LLD_CAST orig_len);
+                                       fprintf(stderr, "Encryption algorithm %s\n", (enc_type==1) ? "AEA 128 CBC" : (enc_type ? "AEA 128 CTR" : "None"));
 
 
-                                       fprintf(stdout, "Selective Encryption: %s\n", use_sel_enc ? "Yes" : "No");
-                                       if (IV_size) fprintf(stdout, "Initialization Vector size: %d bits\n", IV_size*8);
+                                       fprintf(stderr, "Selective Encryption: %s\n", use_sel_enc ? "Yes" : "No");
+                                       if (IV_size) fprintf(stderr, "Initialization Vector size: %d bits\n", IV_size*8);
                                } else {
-                                       fprintf(stdout, "\n*Encrypted stream - unknown scheme %s\n", gf_4cc_to_str(gf_isom_is_media_encrypted(file, trackNum, 1) ));
+                                       fprintf(stderr, "\n*Encrypted stream - unknown scheme %s\n", gf_4cc_to_str(gf_isom_is_media_encrypted(file, trackNum, 1) ));
                                }
                        }
 
@@ -1432,101 +1602,103 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
        } else if (msub_type == GF_ISOM_SUBTYPE_3GP_H263) {
                u32 w, h;
                gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-               fprintf(stdout, "\t3GPP H263 stream - Resolution %d x %d\n", w, h);
+               fprintf(stderr, "\t3GPP H263 stream - Resolution %d x %d\n", w, h);
        } else if (msub_type == GF_4CC('m','j','p','2')) {
                u32 w, h;
                gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
-               fprintf(stdout, "\tMotionJPEG2000 stream - Resolution %d x %d\n", w, h);
+               fprintf(stderr, "\tMotionJPEG2000 stream - Resolution %d x %d\n", w, h);
        } else if ((msub_type == GF_ISOM_SUBTYPE_3GP_AMR) || (msub_type == GF_ISOM_SUBTYPE_3GP_AMR_WB)) {
-               fprintf(stdout, "\t3GPP AMR%s stream - Sample Rate %d - %d channel(s) %d bits per samples\n", (msub_type == GF_ISOM_SUBTYPE_3GP_AMR_WB) ? " Wide Band" : "", sr, nb_ch, (u32) bps);
+               fprintf(stderr, "\t3GPP AMR%s stream - Sample Rate %d - %d channel(s) %d bits per samples\n", (msub_type == GF_ISOM_SUBTYPE_3GP_AMR_WB) ? " Wide Band" : "", sr, nb_ch, (u32) bps);
        } else if (msub_type == GF_ISOM_SUBTYPE_3GP_EVRC) {
-               fprintf(stdout, "\t3GPP EVRC stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps);
+               fprintf(stderr, "\t3GPP EVRC stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps);
        } else if (msub_type == GF_ISOM_SUBTYPE_3GP_QCELP) {
-               fprintf(stdout, "\t3GPP QCELP stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps);
+               fprintf(stderr, "\t3GPP QCELP stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps);
        } else if (msub_type == GF_ISOM_SUBTYPE_AC3) {
                u32 br = 0;
                Bool lfe = 0;
+               Bool is_ec3 = 0;
 #ifndef GPAC_DISABLE_AV_PARSERS
                GF_AC3Config *ac3 = gf_isom_ac3_config_get(file, trackNum, 1);
                if (ac3) {
-                       nb_ch = gf_ac3_get_channels(ac3->acmod);
-                       br = gf_ac3_get_bitrate(ac3->brcode);
-                       lfe = ac3->lfon;
+                       nb_ch = gf_ac3_get_channels(ac3->streams[0].acmod);
+                       lfe = ac3->streams[0].lfon;
+                       br = ac3->is_ec3 ? ac3->brcode : gf_ac3_get_bitrate(ac3->brcode);
+                       is_ec3 = ac3->is_ec3;
                        gf_free(ac3);
                }
 #endif
-               fprintf(stdout, "\tAC3 stream - Sample Rate %d - %d%s channel(s) - bitrate %d\n", sr, nb_ch, lfe ? ".1" : "", br);
+               fprintf(stderr, "\t%s stream - Sample Rate %d - %d%s channel(s) - bitrate %d\n", is_ec3 ? "EC-3" : "AC-3", sr, nb_ch, lfe ? ".1" : "", br);
        } else if (msub_type == GF_ISOM_SUBTYPE_3GP_SMV) {
-               fprintf(stdout, "\t3GPP SMV stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps);
+               fprintf(stderr, "\t3GPP SMV stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps);
        } else if (msub_type == GF_ISOM_SUBTYPE_3GP_DIMS) {
                u32 w, h;
                GF_DIMSDescription dims;
                gf_isom_get_visual_info(file, trackNum, 1, &w, &h);
 
                gf_isom_get_dims_description(file, trackNum, 1, &dims);
-               fprintf(stdout, "\t3GPP DIMS stream - size %d x %d - Profile %d - Level %d\n", w, h, dims.profile, dims.level);
-               fprintf(stdout, "\tpathComponents: %d - useFullRequestHost: %s\n", dims.pathComponents, dims.fullRequestHost ? "yes" : "no");
-               fprintf(stdout, "\tstream type: %s - redundant: %s\n", dims.streamType ? "primary" : "secondary", (dims.containsRedundant==1) ? "main" : ((dims.containsRedundant==2) ? "redundant" : "main+redundant") );
-               if (dims.textEncoding[0]) fprintf(stdout, "\ttext encoding %s\n", dims.textEncoding);
-               if (dims.contentEncoding[0]) fprintf(stdout, "\tcontent encoding %s\n", dims.contentEncoding);
-               if (dims.content_script_types) fprintf(stdout, "\tscript languages %s\n", dims.content_script_types);
+               fprintf(stderr, "\t3GPP DIMS stream - size %d x %d - Profile %d - Level %d\n", w, h, dims.profile, dims.level);
+               fprintf(stderr, "\tpathComponents: %d - useFullRequestHost: %s\n", dims.pathComponents, dims.fullRequestHost ? "yes" : "no");
+               fprintf(stderr, "\tstream type: %s - redundant: %s\n", dims.streamType ? "primary" : "secondary", (dims.containsRedundant==1) ? "main" : ((dims.containsRedundant==2) ? "redundant" : "main+redundant") );
+               if (dims.textEncoding[0]) fprintf(stderr, "\ttext encoding %s\n", dims.textEncoding);
+               if (dims.contentEncoding[0]) fprintf(stderr, "\tcontent encoding %s\n", dims.contentEncoding);
+               if (dims.content_script_types) fprintf(stderr, "\tscript languages %s\n", dims.content_script_types);
        } else if (mtype==GF_ISOM_MEDIA_HINT) {
                u32 refTrack;
                s32 i, refCount = gf_isom_get_reference_count(file, trackNum, GF_ISOM_REF_HINT);
                if (refCount) {
-                       fprintf(stdout, "Streaming Hint Track for track%s ", (refCount>1) ? "s" :"");
+                       fprintf(stderr, "Streaming Hint Track for track%s ", (refCount>1) ? "s" :"");
                        for (i=0; i<refCount; i++) {
                                gf_isom_get_reference(file, trackNum, GF_ISOM_REF_HINT, i+1, &refTrack);
-                               if (i) fprintf(stdout, " - ");
-                               fprintf(stdout, "ID %d", gf_isom_get_track_id(file, refTrack));
+                               if (i) fprintf(stderr, " - ");
+                               fprintf(stderr, "ID %d", gf_isom_get_track_id(file, refTrack));
                        }
-                       fprintf(stdout, "\n");
+                       fprintf(stderr, "\n");
                } else {
-                       fprintf(stdout, "Streaming Hint Track (no refs)\n");
+                       fprintf(stderr, "Streaming Hint Track (no refs)\n");
                }
 #ifndef GPAC_DISABLE_ISOM_HINTING
                refCount = gf_isom_get_payt_count(file, trackNum);
                for (i=0;i<refCount;i++) {
                        const char *name = gf_isom_get_payt_info(file, trackNum, i+1, &refTrack);
-                       fprintf(stdout, "\tPayload ID %d: type %s\n", refTrack, name);
+                       fprintf(stderr, "\tPayload ID %d: type %s\n", refTrack, name);
                }
 #endif
        } else if (mtype==GF_ISOM_MEDIA_FLASH) {
-               fprintf(stdout, "Macromedia Flash Movie\n");
+               fprintf(stderr, "Macromedia Flash Movie\n");
        } else if ((mtype==GF_ISOM_MEDIA_TEXT) || (mtype==GF_ISOM_MEDIA_SUBT)) {
                u32 w, h;
                s16 l;
                s32 tx, ty;
                gf_isom_get_track_layout_info(file, trackNum, &w, &h, &tx, &ty, &l);
-               fprintf(stdout, "3GPP/MPEG-4 Timed Text - Size %d x %d - Translation X=%d Y=%d - Layer %d\n", w, h, tx, ty, l);
+               fprintf(stderr, "3GPP/MPEG-4 Timed Text - Size %d x %d - Translation X=%d Y=%d - Layer %d\n", w, h, tx, ty, l);
        } else if (mtype == GF_ISOM_MEDIA_META) {
                Bool is_xml = 0;
                const char *mime_or_namespace = NULL;
                const char *content_encoding = NULL;
                const char *schema_loc = NULL;
                gf_isom_get_timed_meta_data_info(file, trackNum, 1, &is_xml, &mime_or_namespace, &content_encoding, &schema_loc);
-               fprintf(stdout, "%s Metadata stream\n\t%s %s\n\tencoding %s", is_xml ? "Xml" : "Text", is_xml ? "namespace" : "mime-type", mime_or_namespace, content_encoding);
+               fprintf(stderr, "%s Metadata stream\n\t%s %s\n\tencoding %s", is_xml ? "Xml" : "Text", is_xml ? "namespace" : "mime-type", mime_or_namespace, content_encoding);
                if (is_xml && schema_loc != NULL)
-                       fprintf(stdout, "\n\tschema %s\n", schema_loc);
-               fprintf(stdout, "\n");
+                       fprintf(stderr, "\n\tschema %s\n", schema_loc);
+               fprintf(stderr, "\n");
        } else {
                GF_GenericSampleDescription *udesc = gf_isom_get_generic_sample_description(file, trackNum, 1);
                if (udesc) {
                        if (mtype==GF_ISOM_MEDIA_VISUAL) {
-                               fprintf(stdout, "Visual Track - Compressor \"%s\" - Resolution %d x %d\n", udesc->compressor_name, udesc->width, udesc->height);
+                               fprintf(stderr, "Visual Track - Compressor \"%s\" - Resolution %d x %d\n", udesc->compressor_name, udesc->width, udesc->height);
                        } else if (mtype==GF_ISOM_MEDIA_AUDIO) {
-                               fprintf(stdout, "Audio Track - Sample Rate %d - %d channel(s)\n", udesc->samplerate, udesc->nb_channels);
+                               fprintf(stderr, "Audio Track - Sample Rate %d - %d channel(s)\n", udesc->samplerate, udesc->nb_channels);
                        } else {
-                               fprintf(stdout, "Unknown media type\n");
+                               fprintf(stderr, "Unknown media type\n");
                        }
-                       fprintf(stdout, "\tVendor code \"%s\" - Version %d - revision %d\n", gf_4cc_to_str(udesc->vendor_code), udesc->version, udesc->revision);
+                       fprintf(stderr, "\tVendor code \"%s\" - Version %d - revision %d\n", gf_4cc_to_str(udesc->vendor_code), udesc->version, udesc->revision);
                        if (udesc->extension_buf) {
-                               fprintf(stdout, "\tCodec configuration data size: %d bytes\n", udesc->extension_buf_size);
+                               fprintf(stderr, "\tCodec configuration data size: %d bytes\n", udesc->extension_buf_size);
                                gf_free(udesc->extension_buf);
                        }
                        gf_free(udesc);
                } else {
-                       fprintf(stdout, "Unknown track type\n");
+                       fprintf(stderr, "Unknown track type\n");
                }
        }
 
@@ -1534,29 +1706,29 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
 
        gf_isom_get_track_switch_group_count(file, trackNum, &alt_group, &nb_groups);
        if (alt_group) {
-               fprintf(stdout, "Alternate Group ID %d\n", alt_group);
+               fprintf(stderr, "Alternate Group ID %d\n", alt_group);
                for (i=0; i<nb_groups; i++) {
                        u32 nb_crit, switchGroupID; 
                        const u32 *criterias = gf_isom_get_track_switch_parameter(file, trackNum, i+1, &switchGroupID, &nb_crit);
                        if (!nb_crit) {
-                               fprintf(stdout, "\tNo criteria in %s group\n", switchGroupID ? "switch" : "alternate");
+                               fprintf(stderr, "\tNo criteria in %s group\n", switchGroupID ? "switch" : "alternate");
                        } else {
                                if (switchGroupID) {
-                                       fprintf(stdout, "\tSwitchGroup ID %d criterias: ", switchGroupID);
+                                       fprintf(stderr, "\tSwitchGroup ID %d criterias: ", switchGroupID);
                                } else {
-                                       fprintf(stdout, "\tAlternate Group criterias: ");
+                                       fprintf(stderr, "\tAlternate Group criterias: ");
                                }
                                for (j=0; j<nb_crit; j++) {
-                                       if (j) fprintf(stdout, " ");
-                                       fprintf(stdout, "%s", gf_4cc_to_str(criterias[j]) );
+                                       if (j) fprintf(stderr, " ");
+                                       fprintf(stderr, "%s", gf_4cc_to_str(criterias[j]) );
                                }
-                               fprintf(stdout, "\n");
+                               fprintf(stderr, "\n");
                        }
                }
        }
 
        if (!full_dump) {
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
                return;
        }
 
@@ -1581,13 +1753,13 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
                }
                gf_isom_sample_del(&samp);
        }
-       fprintf(stdout, "\nComputed info from media:\n");
+       fprintf(stderr, "\nComputed info from media:\n");
        scale = 1000;
        scale /= ts;
        dur = (u64) (scale * (s64)dur);
-       fprintf(stdout, "\tTotal size "LLU" bytes - Total samples duration "LLU" ms\n", size, dur);
+       fprintf(stderr, "\tTotal size "LLU" bytes - Total samples duration "LLU" ms\n", size, dur);
        if (!dur) {
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
                return;
        }
        /*rate in byte, dur is in ms*/
@@ -1596,28 +1768,28 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump)
        if (rate >= 1500) {
                rate /= 1000;
                max_rate /= 1000;
-               fprintf(stdout, "\tAverage rate %d kbps - Max Rate %d kbps\n", rate, max_rate);
+               fprintf(stderr, "\tAverage rate %d kbps - Max Rate %d kbps\n", rate, max_rate);
        } else {
-               fprintf(stdout, "\tAverage rate %d bps - Max Rate %d bps\n", rate, max_rate);
+               fprintf(stderr, "\tAverage rate %d bps - Max Rate %d bps\n", rate, max_rate);
        }
 
        {
                u32 dmin, dmax, davg, smin, smax, savg;
                gf_isom_get_chunks_infos(file, trackNum, &dmin, &davg, &dmax, &smin, &savg, &smax);
-               fprintf(stdout, "\tChunk durations: min %d ms - max %d ms - average %d ms\n", (1000*dmin)/ts, (1000*dmax)/ts, (1000*davg)/ts);
-               fprintf(stdout, "\tChunk sizes (bytes): min %d - max %d - average %d\n", smin, smax, savg);
+               fprintf(stderr, "\tChunk durations: min %d ms - max %d ms - average %d ms\n", (1000*dmin)/ts, (1000*dmax)/ts, (1000*davg)/ts);
+               fprintf(stderr, "\tChunk sizes (bytes): min %d - max %d - average %d\n", smin, smax, savg);
        }
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
 
        count = gf_isom_get_chapter_count(file, trackNum);
        if (count) {
                char szDur[20];
                const char *name;
                u64 time;
-               fprintf(stdout, "\nChapters:\n");
+               fprintf(stderr, "\nChapters:\n");
                for (j=0; j<count; j++) {
                        gf_isom_get_chapter(file, trackNum, j+1, &time, &name);
-                       fprintf(stdout, "\tChapter #%d - %s - \"%s\"\n", j+1, format_duration(time, 1000, szDur), name);
+                       fprintf(stderr, "\tChapter #%d - %s - \"%s\"\n", j+1, format_duration(time, 1000, szDur), name);
                }
        }
 }
@@ -1668,28 +1840,36 @@ void DumpMovieInfo(GF_ISOFile *file)
        DumpMetaItem(file, 1, 0, "Root Meta");
        if (!gf_isom_has_movie(file)) {
         if (gf_isom_has_segment(file, &brand, &min)) {
-            fprintf(stdout, "File is a segment: \n");
-            fprintf(stdout, "\tSegment Brand %s - version %d\n", gf_4cc_to_str(brand), min);
+            fprintf(stderr, "File is a segment: \n");
+            fprintf(stderr, "\tSegment Brand %s - version %d\n", gf_4cc_to_str(brand), min);
         } else {
-                   fprintf(stdout, "File has no movie (moov) - static data container\n");
+                   fprintf(stderr, "File has no movie (moov) - static data container\n");
         }
                return;
        }
 
        timescale = gf_isom_get_timescale(file);
-       fprintf(stdout, "* Movie Info *\n\tTimescale %d - Duration %s\n\tFragmented File %s - %d track(s)\n",
-               timescale, format_duration(gf_isom_get_duration(file), timescale, szDur), gf_isom_is_fragmented(file) ? "yes" : "no", gf_isom_get_track_count(file));
+       fprintf(stderr, "* Movie Info *\n\tTimescale %d - Duration %s\n\t%d track(s)\n",
+               timescale, format_duration(gf_isom_get_duration(file), timescale, szDur), gf_isom_get_track_count(file));
+       
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
+       if (gf_isom_is_fragmented(file)) {
+               fprintf(stderr, "\tFragmented File: yes - duration %s\n%d fragments - %d SegmentIndexes\n", format_duration(gf_isom_get_fragmented_duration(file), timescale, szDur), gf_isom_get_fragments_count(file, 0) , gf_isom_get_fragments_count(file, 1) );
+       } else {
+               fprintf(stderr, "\tFragmented File: no\n");
+       }
+#endif
 
        if (gf_isom_moov_first(file))
-               fprintf(stdout, "\tFile suitable for progressive download (moov before mdat)\n");
+               fprintf(stderr, "\tFile suitable for progressive download (moov before mdat)\n");
 
        if (gf_isom_get_brand_info(file, &brand, &min, NULL) == GF_OK) {
-               fprintf(stdout, "\tFile Brand %s - version %d\n", gf_4cc_to_str(brand), min);
+               fprintf(stderr, "\tFile Brand %s - version %d\n", gf_4cc_to_str(brand), min);
        }
        gf_isom_get_creation_time(file, &create, &modif);
-       fprintf(stdout, "\tCreated: %s", format_date(create, szDur));
-       //fprintf(stdout, "\tModified: %s", format_date(modif, szDur));
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\tCreated: %s", format_date(create, szDur));
+       //fprintf(stderr, "\tModified: %s", format_date(modif, szDur));
+       fprintf(stderr, "\n");
 
        DumpMetaItem(file, 0, 0, "Moov Meta");
 
@@ -1697,28 +1877,28 @@ void DumpMovieInfo(GF_ISOFile *file)
        if (iod) {
                u32 desc_size = gf_odf_desc_size((GF_Descriptor *)iod);
                if (iod->tag == GF_ODF_IOD_TAG) {
-                       fprintf(stdout, "File has root IOD (%d bytes)\n", desc_size);
-                       fprintf(stdout, "Scene PL 0x%02x - Graphics PL 0x%02x - OD PL 0x%02x\n", iod->scene_profileAndLevel, iod->graphics_profileAndLevel, iod->OD_profileAndLevel);
-                       fprintf(stdout, "Visual PL: %s (0x%02x)\n", gf_m4v_get_profile_name(iod->visual_profileAndLevel), iod->visual_profileAndLevel);
-                       fprintf(stdout, "Audio PL: %s (0x%02x)\n", gf_m4a_get_profile_name(iod->audio_profileAndLevel), iod->audio_profileAndLevel);
-                       //fprintf(stdout, "inline profiles included %s\n", iod->inlineProfileFlag ? "yes" : "no");
+                       fprintf(stderr, "File has root IOD (%d bytes)\n", desc_size);
+                       fprintf(stderr, "Scene PL 0x%02x - Graphics PL 0x%02x - OD PL 0x%02x\n", iod->scene_profileAndLevel, iod->graphics_profileAndLevel, iod->OD_profileAndLevel);
+                       fprintf(stderr, "Visual PL: %s (0x%02x)\n", gf_m4v_get_profile_name(iod->visual_profileAndLevel), iod->visual_profileAndLevel);
+                       fprintf(stderr, "Audio PL: %s (0x%02x)\n", gf_m4a_get_profile_name(iod->audio_profileAndLevel), iod->audio_profileAndLevel);
+                       //fprintf(stderr, "inline profiles included %s\n", iod->inlineProfileFlag ? "yes" : "no");
                } else {
-                       fprintf(stdout, "File has root OD (%d bytes)\n", desc_size);
+                       fprintf(stderr, "File has root OD (%d bytes)\n", desc_size);
                }
-               if (!gf_list_count(iod->ESDescriptors)) fprintf(stdout, "No streams included in root OD\n");
+               if (!gf_list_count(iod->ESDescriptors)) fprintf(stderr, "No streams included in root OD\n");
                gf_odf_desc_del((GF_Descriptor *) iod);
        } else {
-               fprintf(stdout, "File has no MPEG4 IOD/OD\n");
+               fprintf(stderr, "File has no MPEG4 IOD/OD\n");
        }
-       if (gf_isom_is_JPEG2000(file)) fprintf(stdout, "File is JPEG 2000\n");
+       if (gf_isom_is_JPEG2000(file)) fprintf(stderr, "File is JPEG 2000\n");
 
        count = gf_isom_get_copyright_count(file);
        if (count) {
                const char *lang, *note;
-               fprintf(stdout, "\nCopyrights:\n");
+               fprintf(stderr, "\nCopyrights:\n");
                for (i=0; i<count; i++) {
                        gf_isom_get_copyright(file, i+1, &lang, &note);
-                       fprintf(stdout, "\t(%s) %s\n", lang, note);
+                       fprintf(stderr, "\t(%s) %s\n", lang, note);
                }
        }
        
@@ -1727,56 +1907,56 @@ void DumpMovieInfo(GF_ISOFile *file)
                char szDur[20];
                const char *name;
                u64 time;
-               fprintf(stdout, "\nChapters:\n");
+               fprintf(stderr, "\nChapters:\n");
                for (i=0; i<count; i++) {
                        gf_isom_get_chapter(file, 0, i+1, &time, &name);
-                       fprintf(stdout, "\tChapter #%d - %s - \"%s\"\n", i+1, format_duration(time, 1000, szDur), name);
+                       fprintf(stderr, "\tChapter #%d - %s - \"%s\"\n", i+1, format_duration(time, 1000, szDur), name);
                }
        }
 
        if (gf_isom_apple_get_tag(file, 0, &tag, &tag_len) == GF_OK) {
-               fprintf(stdout, "\niTunes Info:\n");
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_NAME, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tName: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ARTIST, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tArtist: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ALBUM, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tAlbum: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMMENT, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tComment: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tTrack: %d / %d\n", tag[3], tag[5]);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMPOSER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tComposer: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_WRITER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tWriter: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ALBUM_ARTIST, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tAlbum Artist: %s\n", tag);
+               fprintf(stderr, "\niTunes Info:\n");
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_NAME, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tName: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ARTIST, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tArtist: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ALBUM, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tAlbum: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMMENT, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tComment: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tTrack: %d / %d\n", tag[3], tag[5]);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMPOSER, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tComposer: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_WRITER, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tWriter: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ALBUM_ARTIST, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tAlbum Artist: %s\n", tag);
                
                if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GENRE, &tag, &tag_len)==GF_OK) {
                        if (tag[0]) {
-                               fprintf(stdout, "\tGenre: %s\n", tag);
+                               fprintf(stderr, "\tGenre: %s\n", tag);
                        } else {
-                               fprintf(stdout, "\tGenre: %s\n", id3_get_genre(((u8*)tag)[1]));
+                               fprintf(stderr, "\tGenre: %s\n", id3_get_genre(((u8*)tag)[1]));
                        }
                }
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMPILATION, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tCompilation: %s\n", tag[0] ? "Yes" : "No");
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GAPLESS, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tGapless album: %s\n", tag[0] ? "Yes" : "No");
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMPILATION, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tCompilation: %s\n", tag[0] ? "Yes" : "No");
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GAPLESS, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tGapless album: %s\n", tag[0] ? "Yes" : "No");
                
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_CREATED, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tCreated: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_DISK, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tDisk: %d / %d\n", tag[3], tag[5]);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TOOL, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tEncoder Software: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ENCODER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tEncoded by: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_CREATED, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tCreated: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_DISK, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tDisk: %d / %d\n", tag[3], tag[5]);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TOOL, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tEncoder Software: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ENCODER, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tEncoded by: %s\n", tag);
                if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TEMPO, &tag, &tag_len)==GF_OK) {
                        if (tag[0]) {
-                               fprintf(stdout, "\tTempo (BPM): %s\n", tag);
+                               fprintf(stderr, "\tTempo (BPM): %s\n", tag);
                        } else {
-                               fprintf(stdout, "\tTempo (BPM): %d\n", tag[1]);
+                               fprintf(stderr, "\tTempo (BPM): %d\n", tag[1]);
                        }
                }
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACKNUMBER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tTrackNumber: %d / %d\n", tag[3], tag[5]);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tTrack: %s\n", tag);
-               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GROUP, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tGroup: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACKNUMBER, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tTrackNumber: %d / %d\n", tag[3], tag[5]);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tTrack: %s\n", tag);
+               if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GROUP, &tag, &tag_len)==GF_OK) fprintf(stderr, "\tGroup: %s\n", tag);
 
                if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COVER_ART, &tag, &tag_len)==GF_OK) {
-                       if (tag_len>>31) fprintf(stdout, "\tCover Art: PNG File\n");
-                       else fprintf(stdout, "\tCover Art: JPEG File\n");
+                       if (tag_len>>31) fprintf(stderr, "\tCover Art: PNG File\n");
+                       else fprintf(stderr, "\tCover Art: JPEG File\n");
                }
        }
 
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
        for (i=0; i<gf_isom_get_track_count(file); i++) {
                DumpTrackInfo(file, gf_isom_get_track_id(file, i+1), 0);
        }
@@ -1786,112 +1966,7 @@ void DumpMovieInfo(GF_ISOFile *file)
 
 
 #ifndef GPAC_DISABLE_MPEG2TS
-#include <gpac/internal/isomedia_dev.h>
 
-typedef struct
-{      
-       Bool start_indexing;
-
-       /* For indexing the TS*/
-       Double segment_duration;
-       Bool segment_at_rap;
-       u32 subsegs_per_segment;
-       char *seg_name;
-       char *seg_ext;
-       Bool use_url_template;
-       char *init_seg_name;
-       Bool single_segment;
-
-       u32 segment_index;
-
-       FILE *index_file;
-       char index_file_name[100];
-       GF_BitStream *index_bs;
-
-       char mpd_file_name[100];
-       FILE *mpd_file;
-       /* temporary file to store the MPD segment description before writing the header */
-       FILE *mpd_segs;
-
-       u32 represantation_idx;
-
-       u32 reference_pid;
-       GF_M2TS_PES *reference_stream;
-       
-       u32 nb_pes_in_segment;
-       /* earliest presentation time for the whole segment */
-       u64 first_PTS;
-
-       /* earliest presentation time for the subsegment being processed */
-       u64 base_PTS;
-       /* byte offset for the start of subsegment being processed */
-       u32 base_offset;
-       /* last presentation time for the subsegment being processed (before the next subsegment is started) */
-       u64 last_PTS;
-       /* last decoding time for the subsegment being processed */
-       u64 last_DTS;
-       /* byte offset for the last PES packet for the subsegment being processed */
-       u32 last_offset;
-
-       /* earliest presentation time for the previous subsegment */
-       u64 prev_base_PTS;
-       /* byte offset for the start of the previous subsegment */
-       u32 prev_base_offset;
-       /* last presentation time for the previous subsegment */
-       u64 prev_last_PTS;
-       /* byte offset for the last PES packet for the previous subsegment */
-       u32 prev_last_offset;
-
-       /* indicates if the current subsegment contains a SAP and its SAP type*/
-       u32 SAP_type;
-       /* indicates if the first PES in the current subsegment is a SAP*/
-       Bool first_pes_sap;
-       /* Presentation time for the first RAP encountered in the subsegment */
-       u64 first_SAP_PTS;
-       /* byte offset for the first RAP encountered in the subsegment */
-       u32 first_SAP_offset;
-       u64 prev_last_SAP_PTS;
-       u32 prev_last_SAP_offset;
-       u64 last_SAP_PTS;
-       u32 last_SAP_offset;
-
-       /*Interpolated PCR value for the pcrb*/
-       u64 interpolated_pcr_value;
-       u64 last_pcr_value;
-
-       /* information about the first PAT found in the subsegment */
-       u32 last_pat_position;
-       u32 first_pat_position;
-       u32 prev_last_pat_position;
-       Bool first_pat_position_valid;
-       u32 pat_version;
-
-       /* information about the first CAT found in the subsegment */
-       u32 last_cat_position;
-       u32 first_cat_position;
-       u32 prev_last_cat_position;
-       Bool first_cat_position_valid;
-       u32 cat_version;
-
-       /* information about the first PMT found in the subsegment */
-       u32 last_pmt_position;
-       u32 first_pmt_position;
-       u32 prev_last_pmt_position;
-       Bool first_pmt_position_valid;
-       u32 pmt_version;
-
-       /* information about the first PCR found in the subsegment */
-       u32 last_pcr_position;
-       u32 first_pcr_position;
-       Bool first_pcr_position_valid;
-       u32 prev_last_pcr_position;
-
-       //GF_List *sidxs;
-       GF_SegmentIndexBox *sidx;
-       
-       //GF_List *pcrbs;
-       GF_PcrInfoBox *pcrb;
-} GF_M2TS_IndexingInfo;
 
 typedef struct
 {
@@ -1915,202 +1990,9 @@ typedef struct
        u32 dump_pid;
        Bool has_seen_pat;
 
-       GF_M2TS_IndexingInfo index_info;
-
 } GF_M2TS_Dump;
 
-/* Initializes an SIDX */
-static GF_SegmentIndexBox *m2ts_sidx_new(u32 pid, u64 PTS, u64 position)
-{                                              
-       GF_SegmentIndexBox *sidx = (GF_SegmentIndexBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_SIDX);
-       sidx->reference_ID = pid;
-       /* timestamps in MPEG-2 are expressed in 90 kHz timescale */
-       sidx->timescale = 90000;
-       /* first encountered PTS on the PID for this subsegment */
-       sidx->earliest_presentation_time = PTS;
-       sidx->first_offset = position;
-       return sidx;
-}
-
-static void m2ts_sidx_add_entry(GF_SegmentIndexBox *sidx, Bool ref_type, 
-                                                               u32 size, u32 duration, Bool first_is_SAP, u32 sap_type, u32 RAP_delta_time)
-{
-       GF_SIDXReference *ref;
-       sidx->nb_refs++;
-       sidx->refs = gf_realloc(sidx->refs, sidx->nb_refs*sizeof(GF_SIDXReference));
-       ref = &(sidx->refs[sidx->nb_refs-1]);
-       ref->reference_type = ref_type;
-       ref->reference_size = size;
-       ref->subsegment_duration = duration;
-       ref->starts_with_SAP = first_is_SAP;
-       ref->SAP_type = sap_type;
-       ref->SAP_delta_time = (sap_type ? RAP_delta_time: 0);
-}
-
-static void m2ts_pcrb_add_entry(GF_PcrInfoBox *pcrb, u64 interpolatedPCR)
-{
-       pcrb->subsegment_count++;
-       pcrb->pcr_values = gf_realloc(pcrb->pcr_values, pcrb->subsegment_count*sizeof(u64));
-       
-       pcrb->pcr_values[pcrb->subsegment_count-1] = interpolatedPCR;
-}
-
-static void m2ts_sidx_update_prev_entry_duration(GF_SegmentIndexBox *sidx, u32 duration)
-{
-       GF_SIDXReference *ref;
-       if (sidx->nb_refs == 0) return;
-       ref = &(sidx->refs[sidx->nb_refs-1]);
-       ref->subsegment_duration = duration;
-}
-
-static void m2ts_sidx_finalize_size(GF_M2TS_IndexingInfo *index_info, u64 file_size)
-{
-       GF_SIDXReference *ref;
-       if (index_info->sidx->nb_refs == 0) return;
-       ref = &(index_info->sidx->refs[index_info->sidx->nb_refs-1]);
-       ref->reference_size = (u32)(file_size - index_info->prev_base_offset);
-
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Subsegment: position-range ajdustment:%d-%d (%d bytes)\n", index_info->prev_base_offset, (u32)file_size, ref->reference_size));
-}
-
-static void m2ts_sidx_flush_entry(GF_M2TS_IndexingInfo *index_info) 
-{
-       u32 size; 
-       u32 duration, prev_duration; 
-       u32 SAP_delta_time; 
-       u32 SAP_offset;
-
-       u32 end_offset;
-
-       if (!index_info->sidx) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Segment: Reference PID: %d, EPTime: "LLU", Start Offset: %d bytes\n", index_info->reference_pid, index_info->base_PTS, index_info->base_offset));
-               index_info->sidx = m2ts_sidx_new(index_info->reference_pid, index_info->base_PTS, index_info->base_offset);
-       }
-       
-       if (!index_info->pcrb) {
-               index_info->pcrb = (GF_PcrInfoBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_PCRB);
-       }
-
-       /* determine the end of the current index */
-       if (index_info->segment_at_rap) {
-               /*split at PAT*/
-               end_offset = index_info->last_pat_position;
-       } else {
-               /* split at PES header */
-               end_offset = index_info->last_offset; 
-       }
-
-       /* close the current index */ 
-       size = (u32)(end_offset - index_info->base_offset);
-       duration = (u32)(index_info->last_PTS - index_info->base_PTS);
-       SAP_delta_time= (u32)(index_info->first_SAP_PTS - index_info->base_PTS);
-       SAP_offset = (u32)(index_info->first_SAP_offset - index_info->base_offset);
-       m2ts_sidx_add_entry(index_info->sidx, 0, size, duration, index_info->first_pes_sap, index_info->SAP_type, SAP_delta_time);
-       m2ts_pcrb_add_entry(index_info->pcrb, index_info->interpolated_pcr_value);
-
-       /* adjust the previous index duration */
-       if (index_info->sidx->nb_refs > 0 && (index_info->base_PTS < index_info->prev_last_PTS) ) {
-               prev_duration = (u32)(index_info->base_PTS-index_info->prev_base_PTS);
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("           time-range adj.: %.03f-%.03f / %.03f sec.\n",               
-                       (index_info->prev_base_PTS - index_info->first_PTS)/90000.0, 
-                       (index_info->base_PTS - index_info->first_PTS)/90000.0, prev_duration/90000.0);
-               m2ts_sidx_update_prev_entry_duration(index_info->sidx, prev_duration));
-       }
-
-       /* Printing result */
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Subsegment:"));
-       //time-range:position-range: 
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (" %.03f-%0.3f / %.03f sec., %d-%d / %d bytes, ",
-               (index_info->base_PTS - index_info->first_PTS)/90000.0, 
-               (index_info->last_PTS - index_info->first_PTS)/90000.0, duration/90000.0,
-               index_info->base_offset, end_offset, size));
-       if (index_info->SAP_type) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("RAP @ %.03f sec. / %d bytes", (index_info->first_SAP_PTS - index_info->first_PTS)/90000.0, 
-                       SAP_offset));
-       }
-       if (index_info->first_pat_position_valid) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", PAT @ %d bytes", (u32)(index_info->first_pat_position - index_info->base_offset)));
-       } else {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No PAT"));
-       }
-       if (index_info->first_cat_position_valid) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", CAT @ %d bytes", (u32)(index_info->first_cat_position - index_info->base_offset)));
-       } else {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No CAT"));
-       }
-       if (index_info->first_pmt_position_valid) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", PMT @ %d bytes", (u32)(index_info->first_pmt_position - index_info->base_offset)));
-       } else {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No PMT"));
-       }
-       if (index_info->first_pcr_position_valid) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", PCR @ %d bytes", (u32)(index_info->first_pcr_position - index_info->base_offset)));
-       } else {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No PCR"));
-       }
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\n"));
-
-       /* save the current values for later adjustments */
-       index_info->prev_last_SAP_PTS = index_info->last_SAP_PTS;
-       index_info->prev_last_SAP_offset = index_info->last_SAP_offset;
-       index_info->prev_last_PTS = index_info->last_PTS;
-       index_info->prev_last_offset = index_info->last_offset;
-       index_info->prev_base_PTS = index_info->base_PTS;
-       index_info->base_PTS = index_info->last_PTS;
-       index_info->prev_base_offset = index_info->base_offset;
-       index_info->prev_last_pat_position = index_info->last_pat_position;
-       index_info->prev_last_cat_position = index_info->last_cat_position;
-       index_info->prev_last_pmt_position = index_info->last_pmt_position;
-       index_info->prev_last_pcr_position = index_info->last_pcr_position;
-       
-       /* update the values for the new index*/
-       index_info->base_offset = end_offset;
-       index_info->SAP_type = 0;
-       index_info->first_SAP_PTS = 0;
-       index_info->first_SAP_offset = 0;
-       index_info->first_pes_sap = 0;
-       index_info->nb_pes_in_segment = 0;
-       index_info->last_DTS = 0;
-
-       if (index_info->last_pat_position >= index_info->base_offset) {
-               index_info->first_pat_position_valid = 1;
-               index_info->first_pat_position = index_info->last_pat_position;
-       } else {
-               index_info->first_pat_position_valid = 0;
-               index_info->first_pat_position = 0;
-       }
-       if (index_info->last_cat_position >= index_info->base_offset) {
-               index_info->first_cat_position_valid = 1;
-               index_info->first_cat_position = index_info->last_cat_position;
-       } else {
-               index_info->first_cat_position_valid = 0;
-               index_info->first_cat_position = 0;
-       }
-       if (index_info->last_pmt_position >= index_info->base_offset) {
-               index_info->first_pmt_position_valid = 1;
-               index_info->first_pmt_position = index_info->last_pmt_position;
-       } else {
-               index_info->first_pmt_position_valid = 0;
-               index_info->first_pmt_position = 0;
-       }
-       if (index_info->last_pcr_position >= index_info->base_offset) {
-               index_info->first_pcr_position_valid = 1;
-               index_info->first_pcr_position = index_info->last_pcr_position;
-       } else {
-               index_info->first_pcr_position_valid = 0;
-               index_info->first_pcr_position = 0;
-       }
-}
 
-static void m2ts_check_indexing(GF_M2TS_IndexingInfo *index_info)
-{
-       u32 delta_time = (u32)(index_info->last_PTS - index_info->base_PTS);
-       u32 segment_duration = (u32)(index_info->segment_duration*90000);
-       /* we need to create an SIDX entry when the duration of the previous entry is too big */
-       if (delta_time >= segment_duration) {
-               m2ts_sidx_flush_entry(index_info);
-       } 
-}
 
 static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) 
 {
@@ -2118,29 +2000,14 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
        GF_M2TS_Program *prog;
        GF_M2TS_PES_PCK *pck;
        GF_M2TS_Dump *dumper = (GF_M2TS_Dump *)ts->user;
-       GF_M2TS_IndexingInfo *index_info = &dumper->index_info;
 
        switch (evt_type) {
        case GF_M2TS_EVT_PAT_FOUND:
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pat_position_valid) {
-                               index_info->first_pat_position_valid = 1;
-                               index_info->first_pat_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pat_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, 0);
                }
                break;
        case GF_M2TS_EVT_PAT_UPDATE:
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pat_position_valid) {
-                               index_info->first_pat_position_valid = 1;
-                               index_info->first_pat_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pat_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, 0);
                }
@@ -2149,50 +2016,22 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                /* WARNING: We detect the pat on a repetition, probably to ensure that we also have seen all the PMT 
                   To be checked */
                dumper->has_seen_pat = 1;
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pat_position_valid) {
-                               index_info->first_pat_position_valid = 1;
-                               index_info->first_pat_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pat_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, 0);
                }
-//             fprintf(stdout, "Repeated PAT found - %d programs\n", gf_list_count(ts->programs) );
+//             fprintf(stderr, "Repeated PAT found - %d programs\n", gf_list_count(ts->programs) );
                break;
        case GF_M2TS_EVT_CAT_FOUND:
-               if (index_info->start_indexing) {
-                       if (!index_info->first_cat_position_valid) {
-                               index_info->first_cat_position_valid = 1;
-                               index_info->first_cat_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_cat_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, 0);
                }
                break;
        case GF_M2TS_EVT_CAT_UPDATE:
-               if (index_info->start_indexing) {
-                       if (!index_info->first_cat_position_valid) {
-                               index_info->first_cat_position_valid = 1;
-                               index_info->first_cat_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_cat_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, 0);
                }
                break;
        case GF_M2TS_EVT_CAT_REPEAT:
-               if (index_info->start_indexing) {
-                       if (!index_info->first_cat_position_valid) {
-                               index_info->first_cat_position_valid = 1;
-                               index_info->first_cat_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_cat_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, 0);
                }
@@ -2201,13 +2040,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                prog = (GF_M2TS_Program*)par;
                if (gf_list_count(ts->programs)>1 && prog->number!=dumper->prog_number)
                        break;
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pmt_position_valid) {
-                               index_info->first_pmt_position_valid = 1;
-                               index_info->first_pmt_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pmt_position = (ts->pck_number-1)*188;
-               }
+               
                count = gf_list_count(prog->streams);
 
                GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Program number %d found - %d streams:\n", prog->number, count));
@@ -2222,11 +2055,6 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                                if (pes->mpeg4_es_id) GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (" - MPEG-4 ES ID %d", pes->mpeg4_es_id));
                                GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\n"));
                        } 
-                       if (es->pid == prog->pcr_pid) {
-                               /* we create indexing information on the stream used for carrying the PCR */
-                               index_info->reference_pid = prog->pcr_pid;
-                               index_info->reference_stream = (GF_M2TS_PES *)es;
-                       }
                }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, prog->pmt_pid);
@@ -2236,13 +2064,6 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                prog = (GF_M2TS_Program*)par;
                if (gf_list_count(ts->programs)>1 && prog->number!=dumper->prog_number)
                        break;
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pmt_position_valid) {
-                               index_info->first_pmt_position_valid = 1;
-                               index_info->first_pmt_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pmt_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, prog->pmt_pid);
                }
@@ -2251,13 +2072,6 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                prog = (GF_M2TS_Program*)par;
                if (gf_list_count(ts->programs)>1 && prog->number!=dumper->prog_number)
                        break;
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pmt_position_valid) {
-                               index_info->first_pmt_position_valid = 1;
-                               index_info->first_pmt_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pmt_position = (ts->pck_number-1)*188;
-               }
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\n", ts->pck_number, prog->pmt_pid);
                }
@@ -2297,66 +2111,37 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                        /*FIXME : not used GF_M2TS_Program *prog = pes->program; */
                        /* Interpolated PCR value for the TS packet containing the PES header start */
                        u64 interpolated_pcr_value = 0;
-                       if (pes->last_pcr_value && pes->before_last_pcr_value && pes->last_pcr_value > pes->before_last_pcr_value) {
+                       if (pes->last_pcr_value && pes->before_last_pcr_value_pck_number && pes->last_pcr_value > pes->before_last_pcr_value) {
                                u32 delta_pcr_pck_num = pes->last_pcr_value_pck_number - pes->before_last_pcr_value_pck_number;
                                u32 delta_pts_pcr_pck_num = pes->pes_start_packet_number - pes->last_pcr_value_pck_number;
                                u64 delta_pcr_value = pes->last_pcr_value - pes->before_last_pcr_value; 
+                               if ((pes->pes_start_packet_number > pes->last_pcr_value_pck_number)
+                                       && (pes->last_pcr_value > pes->before_last_pcr_value)) {
+                                       
+                                               pes->last_pcr_value = pes->before_last_pcr_value;
+                               }
                                /* we can compute the interpolated pcr value for the packet containing the PES header */
                                interpolated_pcr_value = pes->last_pcr_value + (u64)((delta_pcr_value*delta_pts_pcr_pck_num*1.0)/delta_pcr_pck_num);
-                               index_info->interpolated_pcr_value = interpolated_pcr_value;
-                               index_info->last_pcr_value = pes->last_pcr_value;
                        }
                        
                        if (dumper->timestamps_info_file) {
+                               Double diff;
                                fprintf(dumper->timestamps_info_file, "%u\t%d\t", pck->stream->pes_start_packet_number, pck->stream->pid);
                                if (interpolated_pcr_value) fprintf(dumper->timestamps_info_file, "%f", interpolated_pcr_value/(300.0 * 90000));
                                fprintf(dumper->timestamps_info_file, "\t");
                                if (pck->DTS) fprintf(dumper->timestamps_info_file, "%f", (pck->DTS / 90000.0));
-                               fprintf(dumper->timestamps_info_file, "\t%f\t%d\t%d\n", pck->PTS / 90000.0, (pck->flags & GF_M2TS_PES_PCK_RAP ? 1 : 0), (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY ? 1 : 0));
-                       }
-               }
-               if (index_info->start_indexing) {
-                       /* we process packets only for the given PID */
-                       if (pck->stream->pid != index_info->reference_pid) {
-                               break;
-                       } else {
-                               if (index_info->last_DTS != pck->DTS) {
-                                       index_info->last_DTS = pck->DTS;
-                                       index_info->nb_pes_in_segment++;
-                               }
-
-                               /* we store the fact that there is at least a RAP for the index
-                               and we store the PTS of the first encountered RAP in the index*/
-                               if (pck->flags & GF_M2TS_PES_PCK_RAP) {
-                                       index_info->SAP_type = 1;
-                                       if (!index_info->first_SAP_PTS || (index_info->first_SAP_PTS > pck->PTS)) {
-                                               index_info->first_SAP_PTS = pck->PTS;
-                                               index_info->first_SAP_offset = (pck->stream->pes_start_packet_number-1)*188;
-                                       }
-                                       index_info->last_SAP_PTS = pck->PTS;
-                                       index_info->last_SAP_offset = (pck->stream->pes_start_packet_number-1)*188;
-
-                                       if (index_info->nb_pes_in_segment==1) {
-                                               index_info->first_pes_sap = 1;
-                                       }
-                               }
-                               /* we need to know the earliest PTS value (RAP or not) in the index*/
-                               if (!index_info->base_PTS || (index_info->base_PTS > pck->PTS)) {
-                                       index_info->base_PTS = pck->PTS;
-                               }
-                               /* we need to know the earliest PTS value for the whole file (segment) */
-                               if (!index_info->first_PTS || (index_info->first_PTS > pck->PTS)) {
-                                       index_info->first_PTS = pck->PTS;
-                               }
-                               if (pck->PTS > index_info->last_PTS) {
-                                       /* we use the last PTS for first approximation of the duration */
-                                       index_info->last_PTS = pck->PTS;
-                                       index_info->last_offset = (index_info->reference_stream->pes_start_packet_number-1)*188;
+                               fprintf(dumper->timestamps_info_file, "\t%f\t%d\t%d", pck->PTS / 90000.0, (pck->flags & GF_M2TS_PES_PCK_RAP ? 1 : 0), (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY ? 1 : 0));
+                               if (interpolated_pcr_value) {
+                                       diff = (pck->DTS ? pck->DTS : pck->PTS) / 90000.0;
+                                       diff -= pes->last_pcr_value / (300.0 * 90000);
+                                       fprintf(dumper->timestamps_info_file, "\t%f\n", diff);
+                                       if (diff<0) fprintf(stderr, "Warning: detected PTS/DTS value less than current PCR of %g sec\n", diff);
+                               } else {
+                                       fprintf(dumper->timestamps_info_file, "\t\n");
                                }
-
-                               m2ts_check_indexing(index_info);
                        }
                }
+
                if (dumper->has_seen_pat && dumper->pes_out && (dumper->dump_pid == pck->stream->pid)) {
                        gf_fwrite(pck->data, pck->data_len, 1, dumper->pes_out);
                }
@@ -2368,13 +2153,6 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                if (dumper->timestamps_info_file) {
                        fprintf(dumper->timestamps_info_file, "%u\t%d\t%f\t\t\t\t%d\n", pck->stream->program->last_pcr_value_pck_number, pck->stream->pid, pck->PTS / (300*90000.0), (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY ? 1 : 0));
                }
-               if (index_info->start_indexing) {
-                       if (!index_info->first_pcr_position_valid) {
-                               index_info->first_pcr_position_valid = 1;
-                               index_info->first_pcr_position = (ts->pck_number-1)*188;
-                       }
-                       index_info->last_pcr_position = (ts->pck_number-1)*188;
-               }
                break;
        case GF_M2TS_EVT_SL_PCK:
 #if 0
@@ -2407,216 +2185,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
        }
 }
 
-static void mpd_duration(Double duration, char *duration_string)
-{
-       u32 h, m;
-       Double s;
-
-       h = (u32) (duration/3600);
-       m = (u32) (duration-h*60)/60;
-       s = (duration - h*3600 - m*60);
-       if (h) sprintf(duration_string, "PT%dH%dM%.2fS", h, m, s);      
-       else if (m) sprintf(duration_string, "PT%dM%.2fS", m, s);       
-       else if (s) sprintf(duration_string, "PT%.2fS", s);     
-       else sprintf(duration_string, "PT0S");  
-}
-
-static void mpd_start(GF_M2TS_IndexingInfo *index_info, Bool on_demand, const char *media_file_name, 
-                          Double file_duration, Bool split_seg_at_rap, u64 file_size, Double bufferTime)
-{
-       char duration_string[100];
-       char buffer_string[100];
-       u32 bandwidth, i;
-#ifndef GPAC_DISABLE_MEDIA_IMPORT
-       GF_MediaImporter import;
-#endif
-       char szCodecs[1000];
-       u32 width, height, sample_rate, nb_channels, langCode;
-       GF_Err e;
-       FILE *mpd = index_info->mpd_file;
-
-       /*get codecs*/  
-#ifndef GPAC_DISABLE_MEDIA_IMPORT
-       memset(&import, 0, sizeof(GF_MediaImporter));
-       import.trackID = 0;
-       import.flags = GF_IMPORT_PROBE_ONLY;
-       import.in_name = (char *)media_file_name;
-       e = gf_media_import(&import);
-#else
-       fprintf(stdout, "Warning: generating MPD without media import support\n");
-#endif
-       strcpy(szCodecs, "");
-       width = height = sample_rate = nb_channels = langCode = 0;
-
-
-       bandwidth = (u32) (file_size * 8 / file_duration);      
-       mpd_duration(file_duration, duration_string);
-       mpd_duration(bufferTime, buffer_string);
-
-       if (!index_info->represantation_idx) {
-               fprintf(mpd, "<MPD type=\"%s\" xmlns=\"urn:mpeg:DASH:schema:MPD:2011\" profiles=\"urn:mpeg:dash:profile:mp2t-main:2011\" minBufferTime=\"%s\">\n", (on_demand ? "static": "dynamic"), buffer_string);
-               fprintf(mpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n");
-               fprintf(mpd, "  <Title>MPD for file %s generated with GPAC %s</Title>\n", media_file_name, GPAC_FULL_VERSION);
-               fprintf(mpd, " </ProgramInformation>\n");
-               fprintf(mpd, " <Period start=\"PT0S\" duration=\"%s\" minBufferTime=\"%s\">\n", duration_string, buffer_string);        
-               fprintf(mpd, "  <AdaptationSet segmentAlignment=\"true\" bitstreamSwitching=\"true\" subsegmentAlignment=\"true\">\n");
-       }
-
-       if (!e) {
-#ifndef GPAC_DISABLE_MEDIA_IMPORT
-               for (i=0; i<import.nb_tracks;i++) {
-                       if (strlen(import.tk_info[i].szCodecProfile)) {
-                               if (strlen(szCodecs)) strcat(szCodecs, ",");
-                               strcat(szCodecs, import.tk_info[i].szCodecProfile);
-                       }
-
-                       if (import.tk_info[i].type==GF_ISOM_MEDIA_VISUAL) {
-                               if (!width) width = import.tk_info[i].video_info.width;
-                               if (!height) height = import.tk_info[i].video_info.height;
-                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"video\"/>\n", import.tk_info[i].track_num);
-                       }
-                       else if (import.tk_info[i].type==GF_ISOM_MEDIA_AUDIO) {
-                               if (!sample_rate) sample_rate = import.tk_info[i].audio_info.sample_rate;
-                               if (!nb_channels) nb_channels = import.tk_info[i].audio_info.nb_channels;
-                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"audio\"/>\n", import.tk_info[i].track_num);
-                       }
-                       if (!langCode && import.tk_info[i].lang) langCode = import.tk_info[i].lang;
-               }
-#endif
-       }
-
-       fprintf(mpd, "   <Representation id=\"%d\" mimeType=\"video/mp2t\" codecs=\"%s\"", index_info->represantation_idx+1, szCodecs);
-       if (width && height) fprintf(mpd, " width=\"%d\" height=\"%d\"", width, height);
-       if (sample_rate && nb_channels) fprintf(mpd, " sampleRate=\"%d\" numChannels=\"%d\"", sample_rate, nb_channels);
-       if (langCode) fprintf(mpd, " lang=\"%s\"", gf_4cc_to_str(langCode) );
-       fprintf(mpd, " startWithRAP=\"%s\"", split_seg_at_rap ? "1" : "false");
-       fprintf(mpd, " bandwidth=\"%d\"", bandwidth);
-       fprintf(mpd, ">\n");
-
-}
-
-void mpd_end(FILE *mpd, Bool is_last_rep)
-{
-    fprintf(mpd, "   </Representation>\n");
-       if (is_last_rep) {
-               fprintf(mpd, "  </AdaptationSet>\n");
-               fprintf(mpd, " </Period>\n");
-               fprintf(mpd, "</MPD>");
-       }
-}
-
-static void write_mpd_segment_info(GF_M2TS_IndexingInfo *index_info, char *media_file_name)
-{
-       char *sep, SegName[GF_MAX_PATH];
-       u32 i;
-       u64 start;
-
-       if (!index_info->seg_name) {
-               fprintf(index_info->mpd_file, "    <BaseURL>%s</BaseURL>\n", media_file_name);
-       }
-
-       if (index_info->single_segment) {
-               fprintf(index_info->mpd_file, "    <SegmentBase>\n");
-               fprintf(index_info->mpd_file, "     <RepresentationIndex>%s</RepresentationIndex>\n", index_info->index_file_name);
-               fprintf(index_info->mpd_file, "    </SegmentBase>\n");
-               return;
-       } 
-
-       if (index_info->seg_name) {
-               char *mfile = strrchr(media_file_name, '/');
-               if (!mfile) mfile = strrchr(media_file_name, '\\');
-               if (mfile) mfile += 1;
-               else mfile = media_file_name;
-
-               if (strstr(index_info->seg_name, "%s")) {
-                       sprintf(SegName, index_info->seg_name, mfile);
-               } else {
-                       strcpy(SegName, index_info->seg_name);
-               }
-               sep = strrchr(SegName, '.');
-               if (sep) sep[0] = 0;
-       }
-
-       if (index_info->seg_name && index_info->use_url_template) {
-               fprintf(index_info->mpd_file, "    <SegmentTemplate timescale=\"1000\" duration=\"%d\" startNumber=\"0\" media=\"%s$Number$.%s\" >\n", (u32) (1000*index_info->segment_duration), SegName, index_info->seg_ext); 
-       } else {
-               fprintf(index_info->mpd_file, "    <SegmentList timescale=\"1000\" duration=\"%d\">\n", (u32) (1000*index_info->segment_duration)); 
-       }
-       /* add startIndex for live scenarios */
-       
-       if (index_info->init_seg_name) {
-               fprintf(index_info->mpd_file, "     <Initialization sourceURL=\"%s\"/>\n", index_info->init_seg_name);
-       }
-
-
-       fprintf(index_info->mpd_file, "     <RepresentationIndex>%s</RepresentationIndex>\n", index_info->index_file_name); 
-
-       if (!index_info->seg_name) {
-               start=index_info->sidx->first_offset;
-               for (i=0; i<index_info->sidx->nb_refs; i++) {
-                       GF_SIDXReference *ref = &index_info->sidx->refs[i];
-                       fprintf(index_info->mpd_file, "     <SegmentURL mediaRange=\""LLD"-"LLD"\"/>\n", start, start+ref->reference_size-1);
-                       start += ref->reference_size;
-               }
-       } else {
-               FILE *src, *dst;
-               u64 pos, end;
-               src= gf_f64_open(media_file_name, "rb");
-               start=index_info->sidx->first_offset;
-               for (i=0; i<index_info->sidx->nb_refs; i++) {
-                       char szFile[GF_MAX_PATH], buf[4096];
-                       GF_SIDXReference *ref = &index_info->sidx->refs[i];
-
-                       strcpy(szFile, SegName);
-                       sprintf(buf, "%d", index_info->segment_index);
-                       strcat(szFile, buf);
-                       strcat(szFile, ".ts");
-
-                       if (index_info->use_url_template!=2) {
-                               dst = gf_f64_open(szFile, "wb");
-
-                               gf_f64_seek(src, start, SEEK_SET);
-                               pos = start;
-                               end = start+ref->reference_size;
-                               while (pos<end) {
-                                       u32 res;
-                                       u32 to_read = 4096;
-                                       if (pos+4096 >= end) {
-                                               to_read = (u32) (end-pos);
-                                       }
-                                       res = fread(buf, 1, to_read, src);
-                                       if (res==to_read) {
-                                               res = fwrite(buf, 1, to_read, dst);
-                                       }
-                                       if (res!=to_read) {
-                                               fprintf(stderr, "IO error while Extracting segment %03d / %03d\r", i+1, index_info->sidx->nb_refs);
-                                               break;
-                                       }
-                                       pos += res;
-                               }
-                               fclose(dst);
-                       }
-                       start += ref->reference_size;
-                       index_info->segment_index++;
-
-                       if (!index_info->use_url_template) 
-                               fprintf(index_info->mpd_file, "     <SegmentURL media=\"%s\"/>\n", szFile);
-
-                       fprintf(stdout, "Extracting segment %03d / %03d\r", i+1, index_info->sidx->nb_refs);
-               }
-               fclose(src);
-       }               
-//             fprintf(index_info->mpd_file, "     <SegmentURL media=\"%s\" index=\"%s\"/>\n", media_file_name, index_info->index_file_name);
-       if (index_info->seg_name && index_info->use_url_template) {
-               fprintf(index_info->mpd_file, "    </SegmentTemplate>\n");
-       } else {
-               fprintf(index_info->mpd_file, "    </SegmentList>\n");
-       }
-}
-
-void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num, 
-                                  Double dash_duration, Bool seg_at_rap, u32 subseg_per_seg,
-                                  char *seg_name, char *seg_ext, Bool use_url_template, Bool single_segment, u32 representation_idx, Bool is_last_rep)
+void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num)
 {
        char data[188];
        GF_M2TS_Dump dumper;
@@ -2633,51 +2202,13 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num,
        }
        ts = gf_m2ts_demux_new();
        ts->on_event = on_m2ts_dump_event;
+       ts->notify_pes_timing = 1;
        memset(&dumper, 0, sizeof(GF_M2TS_Dump));
        ts->user = &dumper;
        dumper.prog_number = prog_num;
 
-
-       if (dash_duration) {
-               char *c, *f;
-               dumper.index_info.segment_duration = dash_duration;
-               dumper.index_info.segment_at_rap = seg_at_rap;
-               dumper.index_info.subsegs_per_segment = subseg_per_seg;
-               dumper.index_info.use_url_template = use_url_template;
-               dumper.index_info.init_seg_name = NULL;
-               dumper.index_info.single_segment = single_segment;
-               dumper.index_info.seg_name = seg_name;
-               dumper.index_info.seg_ext = seg_ext ? seg_ext : "ts";
-               
-               c = strrchr(mpeg2ts_file, '.');
-               if (c) *c = 0;
-               f = strrchr(mpeg2ts_file, '/');
-               if (!f) f = strrchr(mpeg2ts_file, '\\');
-               sprintf(dumper.index_info.index_file_name, "%s_index.%s", f ? f+1 : mpeg2ts_file, (seg_ext?seg_ext:"didx"));
-               if (c) *c = '.';
-               
-               dumper.index_info.index_file = NULL;
-               dumper.index_info.index_bs = NULL;
-               if (dumper.index_info.use_url_template!=2) {
-#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-                       dumper.index_info.index_file = gf_f64_open(dumper.index_info.index_file_name, "wb");
-                       dumper.index_info.index_bs = gf_bs_from_file(dumper.index_info.index_file, GF_BITSTREAM_WRITE);
-                       {
-                               GF_SegmentTypeBox *styp = (GF_SegmentTypeBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_STYP);
-                               styp->majorBrand = GF_4CC('r','i','s','x');
-                               styp->minorVersion = 0;
-                               styp->altBrand = (u32*)gf_malloc(sizeof(u32));
-                               styp->altBrand[0] = styp->majorBrand;
-                               styp->altCount = 1;
-                               gf_isom_box_size((GF_Box *)styp);
-                               gf_isom_box_write((GF_Box *)styp, dumper.index_info.index_bs);
-                               gf_isom_box_del((GF_Box *)styp);
-                       }
-#endif
-               }
-       }
        /*PES dumping*/
-       else if (out_name) {
+       if (out_name) {
                char *pid = strrchr(out_name, '#');
                if (pid) {
                        dumper.dump_pid = atoi(pid+1);
@@ -2708,41 +2239,23 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num,
                gf_m2ts_process_data(ts, data, size);
                if (dumper.has_seen_pat) break;
        }
+       dumper.has_seen_pat = 1;
 
-       if (prog_num && !dash_duration) {
+       if (prog_num) {
                sprintf(dumper.timestamps_info_name, "%s_prog_%d_timestamps.txt", mpeg2ts_file, prog_num/*, mpeg2ts_file*/);
                dumper.timestamps_info_file = gf_f64_open(dumper.timestamps_info_name, "wt");
                if (!dumper.timestamps_info_file) {
                        fprintf(stderr, "Cannot open file %s\n", dumper.timestamps_info_name);
                        return;
                }
-               fprintf(dumper.timestamps_info_file, "PCK#\tPID\tPCR\tDTS\tPTS\tRAP\tDiscontinuity\n");
+               fprintf(dumper.timestamps_info_file, "PCK#\tPID\tPCR\tDTS\tPTS\tRAP\tDiscontinuity\tDTS-PCR Diff\n");
        }
 
        gf_m2ts_reset_parsers(ts);
        gf_f64_seek(src, 0, SEEK_SET);
        fdone = 0;
-       if (dumper.index_info.segment_duration) {
-               char *sep;
-               dumper.index_info.start_indexing = 1;
-               fprintf(stderr, "Starting indexing ...\n");
-               if (out_name) {
-                       strcpy(dumper.index_info.mpd_file_name, out_name);
-               } else {
-                       sep = strrchr(mpeg2ts_file, '/');
-                       if (!sep) sep = strrchr(mpeg2ts_file, '\\');
-                       strcpy(dumper.index_info.mpd_file_name, sep ? sep+1 : mpeg2ts_file);
-                       sep = strrchr(dumper.index_info.mpd_file_name, '.');
-                       if (sep) sep[0] = 0;
-                       strcat(dumper.index_info.mpd_file_name, ".mpd");
-               }
-               if (!representation_idx) {
-                       dumper.index_info.mpd_file = gf_f64_open(dumper.index_info.mpd_file_name, "wt");
-               } else {
-                       dumper.index_info.mpd_file = gf_f64_open(dumper.index_info.mpd_file_name, "a+t");
-               }
-               dumper.index_info.represantation_idx = representation_idx;
-       }
+
+
        while (!feof(src)) {
                size = fread(data, 1, 188, src);
                if (size<188) break;
@@ -2753,19 +2266,6 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num,
                gf_set_progress("MPEG-2 TS Parsing", fdone, fsize);
        }
 
-       if (dumper.index_info.segment_duration) {
-               u64 file_size;
-               /* flush SIDX entry for the last packets */
-               m2ts_sidx_flush_entry(&dumper.index_info);
-               gf_f64_seek(src, 0, SEEK_END);
-               file_size = gf_f64_tell(src);
-               m2ts_sidx_finalize_size(&dumper.index_info, file_size);
-               fprintf(stderr, "Indexing done (1 sidx, %d entries).\n", dumper.index_info.sidx->nb_refs);
-
-               mpd_start(&dumper.index_info, 1, mpeg2ts_file, (dumper.index_info.last_PTS-dumper.index_info.first_PTS)/90000.0, dumper.index_info.segment_at_rap, file_size, dumper.index_info.segment_duration/4);
-               write_mpd_segment_info(&dumper.index_info, mpeg2ts_file);
-               mpd_end(dumper.index_info.mpd_file, is_last_rep);
-       }
 
        fclose(src);
        gf_m2ts_demux_del(ts);
@@ -2778,24 +2278,10 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num,
        }
 #endif
        if (dumper.timestamps_info_file) fclose(dumper.timestamps_info_file);
-       if (dumper.index_info.sidx) {
-               gf_isom_box_size((GF_Box *)dumper.index_info.sidx);
-               if (dumper.index_info.index_bs) gf_isom_box_write((GF_Box *)dumper.index_info.sidx, dumper.index_info.index_bs);
-               gf_isom_box_del((GF_Box *)dumper.index_info.sidx);
-               }
-       
-               // ToDo: Should be configurable by some switch
-               if (dumper.index_info.pcrb) {
-               gf_isom_box_size((GF_Box *)dumper.index_info.pcrb);
-               if (dumper.index_info.index_bs) gf_isom_box_write((GF_Box *)dumper.index_info.pcrb, dumper.index_info.index_bs);
-               gf_isom_box_del((GF_Box *)dumper.index_info.pcrb);
 
-       }
-       if (dumper.index_info.mpd_file) fclose(dumper.index_info.mpd_file);
-       if (dumper.index_info.index_file) fclose(dumper.index_info.index_file);
-       if (dumper.index_info.index_bs) gf_bs_del(dumper.index_info.index_bs);
 }
 
+
 #endif /*GPAC_DISABLE_MPEG2TS*/
 
 
index e7ccf0340ad2d7dd69f446d6ea4cb791e1b35c3b..e1976a8ee0864533eb3e27681a66b949e2b7d512 100644 (file)
@@ -1,12 +1,13 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mp4box application
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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.
 #ifndef GPAC_DISABLE_BIFS
 #include <gpac/bifs.h>
 #endif
+#ifndef GPAC_DISABLE_VRML
+#include <gpac/nodes_mpeg4.h>
+#endif
+
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
 #include <gpac/xml.h>
@@ -69,109 +74,118 @@ void convert_file_info(char *inName, u32 trackID)
        import.flags = GF_IMPORT_PROBE_ONLY;
        e = gf_media_import(&import);
        if (e) {
-               fprintf(stdout, "Error probing file %s: %s\n", inName, gf_error_to_string(e));
+               fprintf(stderr, "Error probing file %s: %s\n", inName, gf_error_to_string(e));
                return;
        }
        if (trackID) {
-               fprintf(stdout, "Import probing results for track %s#%d:\n", inName, trackID);
+               fprintf(stderr, "Import probing results for track %s#%d:\n", inName, trackID);
        } else {
-               fprintf(stdout, "Import probing results for %s:\n", inName);
+               fprintf(stderr, "Import probing results for %s:\n", inName);
                if (!import.nb_tracks) {
-                       fprintf(stdout, "File has no selectable tracks\n");
+                       fprintf(stderr, "File has no selectable tracks\n");
                        return;
                }
-               fprintf(stdout, "File has %d tracks\n", import.nb_tracks);
+               fprintf(stderr, "File has %d tracks\n", import.nb_tracks);
        }
        found = 0;
        for (i=0; i<import.nb_tracks; i++) {
                if (trackID && (trackID != import.tk_info[i].track_num)) continue;
-               if (!trackID) fprintf(stdout, "\tTrack %d type: ", import.tk_info[i].track_num);
-               else fprintf(stdout, "Track type: ");
+               if (!trackID) fprintf(stderr, "\tTrack %d type: ", import.tk_info[i].track_num);
+               else fprintf(stderr, "Track type: ");
 
                switch (import.tk_info[i].type) {
-               case GF_ISOM_MEDIA_VISUAL: fprintf(stdout, "Video (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
-               case GF_ISOM_MEDIA_AUDIO: fprintf(stdout, "Audio (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
-               case GF_ISOM_MEDIA_TEXT: fprintf(stdout, "Text (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
-               case GF_ISOM_MEDIA_SCENE: fprintf(stdout, "Scene (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
-               case GF_ISOM_MEDIA_OD: fprintf(stdout, "OD (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
-               default: fprintf(stdout, "Other (4CC: %s)", gf_4cc_to_str(import.tk_info[i].type)); break;
+               case GF_ISOM_MEDIA_VISUAL: fprintf(stderr, "Video (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
+               case GF_ISOM_MEDIA_AUDIO: fprintf(stderr, "Audio (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
+               case GF_ISOM_MEDIA_TEXT: fprintf(stderr, "Text (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
+               case GF_ISOM_MEDIA_SCENE: fprintf(stderr, "Scene (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
+               case GF_ISOM_MEDIA_OD: fprintf(stderr, "OD (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); break;
+               default: fprintf(stderr, "Other (4CC: %s)", gf_4cc_to_str(import.tk_info[i].type)); break;
                }
 
-               if (import.tk_info[i].lang) fprintf(stdout, " - lang %s", gf_4cc_to_str(import.tk_info[i].lang));
+               if (import.tk_info[i].lang) fprintf(stderr, " - lang %s", gf_4cc_to_str(import.tk_info[i].lang));
 
-               if (import.tk_info[i].mpeg4_es_id) fprintf(stdout, " - MPEG-4 ESID %d", import.tk_info[i].mpeg4_es_id);
+               if (import.tk_info[i].mpeg4_es_id) fprintf(stderr, " - MPEG-4 ESID %d", import.tk_info[i].mpeg4_es_id);
 
                if (import.tk_info[i].prog_num) {
                        if (!import.nb_progs) {
-                               fprintf(stdout, " - Program %d", import.tk_info[i].prog_num);
+                               fprintf(stderr, " - Program %d", import.tk_info[i].prog_num);
                        } else {
                                u32 j;
                                for (j=0; j<import.nb_progs; j++) {
                                        if (import.tk_info[i].prog_num != import.pg_info[j].number) continue;
-                                       fprintf(stdout, " - Program %s", import.pg_info[j].name);
+                                       fprintf(stderr, " - Program %s", import.pg_info[j].name);
                                        break;
                                }
                        }
                }
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
                if (!trackID) continue;
 
                if ((import.tk_info[i].type==GF_ISOM_MEDIA_VISUAL) 
                        && import.tk_info[i].video_info.width 
                        && import.tk_info[i].video_info.height
                        ) {
-                       fprintf(stdout, "Source: %s %dx%d", gf_4cc_to_str(import.tk_info[i].media_type), import.tk_info[i].video_info.width, import.tk_info[i].video_info.height);
-                       if (import.tk_info[i].video_info.FPS) fprintf(stdout, " @ %g FPS", import.tk_info[i].video_info.FPS);
-                       if (import.tk_info[i].video_info.par) fprintf(stdout, " PAR: %d:%d", import.tk_info[i].video_info.par >> 16, import.tk_info[i].video_info.par & 0xFFFF);
-                       fprintf(stdout, "\n");
+                       fprintf(stderr, "Source: %s %dx%d", gf_4cc_to_str(import.tk_info[i].media_type), import.tk_info[i].video_info.width, import.tk_info[i].video_info.height);
+                       if (import.tk_info[i].video_info.FPS) fprintf(stderr, " @ %g FPS", import.tk_info[i].video_info.FPS);
+                       if (import.tk_info[i].video_info.par) fprintf(stderr, " PAR: %d:%d", import.tk_info[i].video_info.par >> 16, import.tk_info[i].video_info.par & 0xFFFF);
+                       fprintf(stderr, "\n");
                }
                else if ((import.tk_info[i].type==GF_ISOM_MEDIA_AUDIO) && import.tk_info[i].audio_info.sample_rate) {
-                       fprintf(stdout, "Source: %s - SampleRate %d - %d channels\n", gf_4cc_to_str(import.tk_info[i].media_type), import.tk_info[i].audio_info.sample_rate, import.tk_info[i].audio_info.nb_channels);
+                       fprintf(stderr, "Source: %s - SampleRate %d - %d channels\n", gf_4cc_to_str(import.tk_info[i].media_type), import.tk_info[i].audio_info.sample_rate, import.tk_info[i].audio_info.nb_channels);
                } else {
-                       fprintf(stdout, "Source: %s\n", gf_4cc_to_str(import.tk_info[i].media_type));
+                       fprintf(stderr, "Source: %s\n", gf_4cc_to_str(import.tk_info[i].media_type));
                }
                        
 
-               fprintf(stdout, "\nImport Capabilities:\n");
-               if (import.tk_info[i].flags & GF_IMPORT_USE_DATAREF) fprintf(stdout, "\tCan use data referencing\n");
-               if (import.tk_info[i].flags & GF_IMPORT_NO_FRAME_DROP) fprintf(stdout, "\tCan use fixed FPS import\n");
-               if (import.tk_info[i].flags & GF_IMPORT_FORCE_PACKED) fprintf(stdout, "\tCan force packed bitstream import\n");
-               if (import.tk_info[i].flags & GF_IMPORT_OVERRIDE_FPS) fprintf(stdout, "\tCan override source frame rate\n");
-               if (import.tk_info[i].flags & (GF_IMPORT_SBR_IMPLICIT|GF_IMPORT_SBR_EXPLICIT)) fprintf(stdout, "\tCan use AAC-SBR signaling\n");
-               if (import.tk_info[i].flags & (GF_IMPORT_PS_IMPLICIT|GF_IMPORT_PS_EXPLICIT)) fprintf(stdout, "\tCan use AAC-PS signaling\n");
-               if (import.tk_info[i].flags & GF_IMPORT_FORCE_MPEG4) fprintf(stdout, "\tCan force MPEG-4 Systems signaling\n");
-               if (import.tk_info[i].flags & GF_IMPORT_3GPP_AGGREGATION) fprintf(stdout, "\tCan use 3GPP frame aggregation\n");
-               if (import.tk_info[i].flags & GF_IMPORT_NO_DURATION) fprintf(stdout, "\tCannot use duration-based import\n");
+               fprintf(stderr, "\nImport Capabilities:\n");
+               if (import.tk_info[i].flags & GF_IMPORT_USE_DATAREF) fprintf(stderr, "\tCan use data referencing\n");
+               if (import.tk_info[i].flags & GF_IMPORT_NO_FRAME_DROP) fprintf(stderr, "\tCan use fixed FPS import\n");
+               if (import.tk_info[i].flags & GF_IMPORT_FORCE_PACKED) fprintf(stderr, "\tCan force packed bitstream import\n");
+               if (import.tk_info[i].flags & GF_IMPORT_OVERRIDE_FPS) fprintf(stderr, "\tCan override source frame rate\n");
+               if (import.tk_info[i].flags & (GF_IMPORT_SBR_IMPLICIT|GF_IMPORT_SBR_EXPLICIT)) fprintf(stderr, "\tCan use AAC-SBR signaling\n");
+               if (import.tk_info[i].flags & (GF_IMPORT_PS_IMPLICIT|GF_IMPORT_PS_EXPLICIT)) fprintf(stderr, "\tCan use AAC-PS signaling\n");
+               if (import.tk_info[i].flags & GF_IMPORT_FORCE_MPEG4) fprintf(stderr, "\tCan force MPEG-4 Systems signaling\n");
+               if (import.tk_info[i].flags & GF_IMPORT_3GPP_AGGREGATION) fprintf(stderr, "\tCan use 3GPP frame aggregation\n");
+               if (import.tk_info[i].flags & GF_IMPORT_NO_DURATION) fprintf(stderr, "\tCannot use duration-based import\n");
 
                found = 1;
                break;
        }
-       fprintf(stdout, "\n");
-       if (!found && trackID) fprintf(stdout, "Cannot find track %d in file\n", trackID);
+       fprintf(stderr, "\n");
+       if (!found && trackID) fprintf(stderr, "Cannot find track %d in file\n", trackID);
 }
 
 GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample)
 {
-       u32 track_id, i, timescale, track, stype, profile, level;
+       u32 track_id, i, timescale, track, stype, profile, level, new_timescale, rescale, svc_mode;
        s32 par_d, par_n, prog_id, delay;
-       s32 tw, th, tx, ty;
-       Bool do_audio, do_video, do_all, disable, track_layout, chap_ref, is_chap, keep_handler;
-       u32 group, handler, rvc_predefined;
+       s32 tw, th, tx, ty, txtw, txth, txtx, txty;
+       Bool do_audio, do_video, do_all, disable, track_layout, text_layout, chap_ref, is_chap, is_chap_file, keep_handler, negative_cts_offset;
+       u32 group, handler, rvc_predefined, check_track_for_svc;
        const char *szLan;
        GF_Err e;
        GF_MediaImporter import;
-       char *ext, szName[1000], *handler_name, *rvc_config;
+       char *ext, szName[1000], *handler_name, *rvc_config, *chapter_name;
        rvc_predefined = 0;
+       chapter_name = NULL;
+       new_timescale = 1;
+       rescale = 0;
+       text_layout = 0;
+       /*0: merge all 
+         1: split base and all SVC in two tracks
+         2: split all base and SVC layers in dedicated tracks
+        */
+       svc_mode = 0;
 
        memset(&import, 0, sizeof(GF_MediaImporter));
 
        strcpy(szName, inName);
        ext = strrchr(inName, '.');
        if (!ext) {
-               fprintf(stdout, "Unknown input file type\n");
+               fprintf(stderr, "Unknown input file type\n");
                return GF_BAD_PARAM;
        }
-
+       is_chap_file = 0;
        handler = 0;
        disable = 0;
        chap_ref = 0;
@@ -182,8 +196,9 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
        group = 0;
        stype = 0;
        profile = level = 0;
+       negative_cts_offset = 0;
 
-       tw = th = tx = ty = 0;
+       tw = th = tx = ty = txtw = txth = txtx = txty = 0;
        par_d = par_n = -2;
        /*use ':' as separator, but beware DOS paths...*/
        ext = strchr(szName, ':');
@@ -211,6 +226,12 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                        }
                        else force_fps = atof(ext+5);
                }
+               else if (!strnicmp(ext+1, "timescale=", 10)) {
+                       new_timescale = atoi(ext+11);
+               }
+               else if (!strnicmp(ext+1, "rescale=", 8)) {
+                       rescale = atoi(ext+9);
+               }
                else if (!stricmp(ext+1, "chap")) is_chap = 1;
                else if (!stricmp(ext+1, "dref")) import_flags |= GF_IMPORT_USE_DATAREF;
                else if (!stricmp(ext+1, "nodrop")) import_flags |= GF_IMPORT_NO_FRAME_DROP;
@@ -246,7 +267,16 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                else if (!strnicmp(ext+1, "font=", 5)) import.fontName = gf_strdup(ext+6);
                else if (!strnicmp(ext+1, "size=", 5)) import.fontSize = atoi(ext+6);
                else if (!strnicmp(ext+1, "fmt=", 4)) import.streamFormat = gf_strdup(ext+5);
-               else if (!strnicmp(ext+1, "ext=", 4)) import.force_ext = gf_strdup(ext+5);
+               else if (!strnicmp(ext+1, "ext=", 4)) {
+                       /*extensions begin with '.'*/
+                       if (*(ext+5) == '.')
+                               import.force_ext = gf_strdup(ext+5);
+                       else {
+                               import.force_ext = gf_calloc(1+strlen(ext+5)+1, 1);
+                               import.force_ext[0] = '.';
+                               strcat(import.force_ext+1, ext+5);
+                       }
+               }
                else if (!strnicmp(ext+1, "disable", 7)) disable = 1;
                else if (!strnicmp(ext+1, "group=", 6)) {
                        group = atoi(ext+7);
@@ -263,11 +293,35 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                                tx = ty = 0;
                        }
                }
+               else if (!strnicmp(ext+1, "text_layout=", 12)) {
+                       if ( sscanf(ext+13, "%dx%dx%dx%d", &txtw, &txth, &txtx, &txty)==4) {
+                               text_layout = 1;
+                       } else if ( sscanf(ext+8, "%dx%d", &txtw, &txth)==2) {
+                               track_layout = 1;
+                               txtx = txty = 0;
+                       }
+               }
                else if (!strnicmp(ext+1, "stype=", 6)) {
                        stype = GF_4CC(ext[7], ext[8], ext[9], ext[10]);
                }
                else if (!strnicmp(ext+1, "profile=", 8)) profile = atoi(ext+9);
                else if (!strnicmp(ext+1, "level=", 6)) level = atoi(ext+7);
+               else if (!strnicmp(ext+1, "chapter=", 8)) chapter_name = gf_strdup(ext+9);
+               else if (!strnicmp(ext+1, "chapfile=", 9)) {
+                       chapter_name = gf_strdup(ext+10);
+                       is_chap_file=1;
+               }
+               /*force all composition offsets to be positive*/
+               else if (!strnicmp(ext+1, "negctts", 7)) negative_cts_offset = 1;
+               /*split SVC layers*/
+               else if (!strnicmp(ext+1, "svcmode=", 8)) {
+                       if (!stricmp(ext+9, "splitall"))
+                               svc_mode = 2;
+                       else if (!stricmp(ext+9, "splitbase"))
+                               svc_mode = 1;
+                       else if (!stricmp(ext+9, "merged"))
+                               svc_mode = 0;
+               }
 
                /*unrecognized, assume name has colon in it*/
                else {
@@ -351,12 +405,21 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                        if (!tw) tw = w;
                        if (!th) th = h;
                        if (ty==-1) ty = (h>(u32)th) ? h-th : 0;
-                       import.twidth = tw;
-                       import.theight = th;
+                       import.text_width = tw;
+                       import.text_height = th;
                }
                if (is_chap && chap_ref) import_flags |= GF_IMPORT_NO_TEXT_FLUSH;
        }
+       if (text_layout && txtw && txth) {
+               import.text_track_width = import.text_width ? import.text_width : txtw;
+               import.text_track_height = import.text_height ? import.text_height : txth;
+               import.text_width = txtw;
+               import.text_height = txth;
+               import.text_x = txtx;
+               import.text_y = txty;
+       }
 
+       check_track_for_svc = 0;
 
        import.dest = dest;
        import.video_fps = force_fps;
@@ -385,7 +448,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                                                //u64 seg_dur = (-delay)*gf_isom_get_media_timescale(import.dest, i+1) / 1000;
                                                gf_isom_append_edit_segment(import.dest, i+1, tk_dur-to_skip, to_skip, GF_ISOM_EDIT_NORMAL);
                                        } else {
-                                               fprintf(stdout, "Warning: request negative delay longer than track duration - ignoring\n");
+                                               fprintf(stderr, "Warning: request negative delay longer than track duration - ignoring\n");
                                        }
                                }
                        }
@@ -426,6 +489,12 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
 
                        if (gf_isom_get_media_subtype(import.dest, i+1, 1)== GF_4CC( 'm', 'p', '4', 's' ))
                                keep_sys_tracks = 1;
+
+                       gf_isom_set_composition_offset_mode(import.dest, i+1, negative_cts_offset);
+
+                       /*when importing SVC we ALWAYS have AVC+SVC single track mode*/
+                       if (gf_isom_get_avc_svc_type(import.dest, i+1, 1)==GF_ISOM_AVCTYPE_AVC_SVC)
+                               check_track_for_svc = i+1;
                }
        } else {
                for (i=0; i<import.nb_tracks; i++) {
@@ -468,7 +537,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                                                u64 media_time = (-delay)*gf_isom_get_media_timescale(import.dest, track) / 1000;
                                                gf_isom_append_edit_segment(import.dest, i+1, tk_dur-to_skip, media_time, GF_ISOM_EDIT_NORMAL);
                                        } else {
-                                               fprintf(stdout, "Warning: request negative delay longer than track duration - ignoring\n");
+                                               fprintf(stderr, "Warning: request negative delay longer than track duration - ignoring\n");
                                        }
                                }
                        }
@@ -510,6 +579,20 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                        if (gf_isom_get_mpeg4_subtype(import.dest, track, 1))
                                keep_sys_tracks = 1;
 
+                       if (new_timescale>1) {
+                               gf_isom_set_media_timescale(import.dest, track, new_timescale, 0);
+                       }
+                       if (rescale>1) {
+                               switch (gf_isom_get_media_type(import.dest, track)) {
+                               case GF_ISOM_MEDIA_AUDIO:
+                                       fprintf(stderr, "Cannot force media timescale for audio media types - ignoring\n");
+                                       break;
+                               default:
+                                       gf_isom_set_media_timescale(import.dest, track, rescale, 1);
+                                       break;
+                               }
+                       }
+
                        if (rvc_config) {
                                FILE *f = gf_f64_open(rvc_config, "rb");
                                if (f) {
@@ -532,14 +615,39 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc
                        } else if (rvc_predefined>0) {
                                gf_isom_set_rvc_config(import.dest, track, 1, rvc_predefined, NULL, NULL, 0);
                        }
+                       
+                       gf_isom_set_composition_offset_mode(import.dest, track, negative_cts_offset);
+
+                       /*when importing SVC we ALWAYS have AVC+SVC single track mode*/
+                       if (gf_isom_get_avc_svc_type(import.dest, track, 1)==GF_ISOM_AVCTYPE_AVC_SVC)
+                               check_track_for_svc = track;
+               }
+               if (track_id) fprintf(stderr, "WARNING: Track ID %d not found in file\n", track_id);
+               else if (do_video) fprintf(stderr, "WARNING: Video track not found\n");
+               else if (do_audio) fprintf(stderr, "WARNING: Audio track not found\n");
+       }
+
+       if (chapter_name) {
+               if (is_chap_file) {
+                       e = gf_media_import_chapters(import.dest, chapter_name, 0);
+               } else {
+                       e = gf_isom_add_chapter(import.dest, 0, 0, chapter_name);
+               }
+       }
+
+       if (check_track_for_svc) {
+               if (svc_mode) {
+                       e = gf_media_split_svc(import.dest, check_track_for_svc, (svc_mode==2) ? 1 : 0);
+                       if (e) goto exit;
+               } else {
+                       e = gf_media_merge_svc(import.dest, check_track_for_svc, 1);
+                       if (e) goto exit;
                }
-               if (track_id) fprintf(stdout, "WARNING: Track ID %d not found in file\n", track_id);
-               else if (do_video) fprintf(stdout, "WARNING: Video track not found\n");
-               else if (do_audio) fprintf(stdout, "WARNING: Audio track not found\n");
        }
 
 exit:
        if (handler_name) gf_free(handler_name);
+       if (chapter_name ) gf_free(chapter_name );
        if (import.fontName) gf_free(import.fontName);
        if (import.streamFormat) gf_free(import.streamFormat);
        if (import.force_ext) gf_free(import.force_ext);
@@ -569,7 +677,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
 {
        u32 i, count, nb_tk, needs_rap_sync, cur_file, conv_type, nb_tk_done, nb_samp, nb_done, di;
        Double max_dur, cur_file_time;
-       Bool do_add, all_duplicatable, size_exceeded, chunk_extraction, rap_split;
+       Bool do_add, all_duplicatable, size_exceeded, chunk_extraction, rap_split, split_until_end;
        GF_ISOFile *dest;
        GF_ISOSample *samp;
        GF_Err e;
@@ -578,10 +686,16 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
        Double chunk_start = (Double) chunk_start_time;
 
        chunk_extraction = (chunk_start>=0) ? 1 : 0;
-
+       split_until_end = 0;
        rap_split = 0;
        if (split_size_kb==(u32) -1) rap_split = 1;
        if (split_dur==-1) rap_split = 1;
+       else if (split_dur==-2) {
+               split_size_kb = 0;
+               split_until_end = 1;
+               split_dur = 0;
+       }
+
        if (rap_split) {
                split_size_kb = 0;
                split_dur = (double) GF_MAX_FLOAT;
@@ -646,12 +760,12 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                case GF_ISOM_MEDIA_MPEGJ:
                case GF_ISOM_MEDIA_MPEG7:
                case GF_ISOM_MEDIA_FLASH:
-                       fprintf(stdout, "WARNING: Track ID %d (type %s) not handled by spliter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype));
+                       fprintf(stderr, "WARNING: Track ID %d (type %s) not handled by spliter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype));
                        continue;
                default:
                        /*for all other track types, only split if more than one sample*/
                        if (gf_isom_get_sample_count(mp4, i+1)==1) {
-                               fprintf(stdout, "WARNING: Track ID %d (type %s) not handled by spliter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype));
+                               fprintf(stderr, "WARNING: Track ID %d (type %s) not handled by spliter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype));
                                continue;
                        }
                        tks[nb_tk].can_duplicate = 1;
@@ -673,7 +787,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                if (tks[nb_tk].has_non_raps) {
                        /*we don't support that*/
                        if (needs_rap_sync) {
-                               fprintf(stdout, "More than one track has non-sync points - cannot split file\n");
+                               fprintf(stderr, "More than one track has non-sync points - cannot split file\n");
                                gf_free(tks);
                                return GF_NOT_SUPPORTED;
                        }
@@ -683,24 +797,26 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                nb_tk++;
        }
        if (!nb_tk) {
-               fprintf(stdout, "No suitable tracks found for spliting file\n");
+               fprintf(stderr, "No suitable tracks found for spliting file\n");
                gf_free(tks);
                return GF_NOT_SUPPORTED;
        }
        if (chunk_start>=max_dur) {
-               fprintf(stdout, "Input file (%f) shorter than requested split start offset (%f)\n", max_dur, chunk_start);
+               fprintf(stderr, "Input file (%f) shorter than requested split start offset (%f)\n", max_dur, chunk_start);
                gf_free(tks);
                return GF_NOT_SUPPORTED;
        }
-       if (!rap_split && (max_dur<=split_dur)) {
-               fprintf(stdout, "Input file (%f) shorter than requested split duration (%f)\n", max_dur, split_dur);
+       if (split_until_end) {
+               split_dur = max_dur;
+       } else if (!rap_split && (max_dur<=split_dur)) {
+               fprintf(stderr, "Input file (%f) shorter than requested split duration (%f)\n", max_dur, split_dur);
                gf_free(tks);
                return GF_NOT_SUPPORTED;
        }
        if (needs_rap_sync) {
                tki = &tks[needs_rap_sync-1];
                if ((gf_isom_get_sync_point_count(mp4, tki->tk)==1) && (chunk_start != 0.0f)) {
-                       fprintf(stdout, "Not enough Random Access points in input file - cannot split\n");
+                       fprintf(stderr, "Not enough Random Access points in input file - cannot split\n");
                        gf_free(tks);
                        return GF_NOT_SUPPORTED;
                }
@@ -722,14 +838,14 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                        } else  {
                                e = gf_isom_get_sample_for_media_time(mp4, tki->tk, (u64) (chunk_start*tki->time_scale), &di, GF_ISOM_SEARCH_SYNC_BACKWARD, &samp, &sample_num);
                                if (e!=GF_OK) {
-                                       fprintf(stdout, "Cannot locate RAP in track ID %d for chunk extraction from %02.2f sec\n", gf_isom_get_track_id(mp4, tki->tk), chunk_start);
+                                       fprintf(stderr, "Cannot locate RAP in track ID %d for chunk extraction from %02.2f sec\n", gf_isom_get_track_id(mp4, tki->tk), chunk_start);
                                        gf_free(tks);
                                        return GF_NOT_SUPPORTED;
                                }
                                start = (Double) (s64) samp->DTS;
                                start /= tki->time_scale;
                                gf_isom_sample_del(&samp);
-                               fprintf(stdout, "Adjusting chunk start time to previous random access at %02.2f sec\n", start);
+                               fprintf(stderr, "Adjusting chunk start time to previous random access at %02.2f sec\n", start);
                                split_dur += (chunk_start - start);
                                chunk_start = start;
                        }
@@ -784,7 +900,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
 
                        e = gf_isom_clone_track(mp4, tki->tk, dest, 0, &tki->dst_tk);
                        if (e) {
-                               fprintf(stdout, "Error cloning track %d\n", tki->tk);
+                               fprintf(stderr, "Error cloning track %d\n", tki->tk);
                                goto err_exit;
                        }
                        /*use non-packet CTS offsets (faster add/remove)*/
@@ -868,7 +984,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                                gf_set_progress("Splitting", nb_done, nb_samp);
                                nb_done++;
                                if (e) {
-                                       fprintf(stdout, "Error cloning track %d sample %d\n", tki->tk, tki->last_sample);
+                                       fprintf(stderr, "Error cloning track %d sample %d\n", tki->tk, tki->last_sample);
                                        goto err_exit;
                                }
        
@@ -956,12 +1072,12 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                        }
                }
                if (file_split_dur == (Double) GF_MAX_FLOAT) {
-                       fprintf(stdout, "Cannot split file (duration too small or size too small)\n");
+                       fprintf(stderr, "Cannot split file (duration too small or size too small)\n");
                        goto err_exit;
                }
                if (chunk_extraction) {
                        if (adjust_split_end) {
-                               fprintf(stdout, "Adjusting chunk end time to previous random access at %02.2f sec\n", chunk_start + last_rap_sample_time);
+                               fprintf(stderr, "Adjusting chunk end time to previous random access at %02.2f sec\n", chunk_start + last_rap_sample_time);
                                file_split_dur = last_rap_sample_time;
                                sprintf(szFile, "%s_%d_%d%s", szName, (u32) chunk_start, (u32) (chunk_start+file_split_dur), ext);
                                gf_isom_set_final_name(dest, szFile);
@@ -971,7 +1087,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
 
                /*don't split if eq to copy...*/
                if (is_last && !cur_file && !chunk_start) {
-                       fprintf(stdout, "Cannot split file (Not enough sync samples, duration too large or size too big)\n");
+                       fprintf(stderr, "Cannot split file (Not enough sync samples, duration too large or size too big)\n");
                        goto err_exit;
                }
 
@@ -1046,9 +1162,9 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                }
 
                if (chunk_extraction) {
-                       fprintf(stdout, "Extracting chunk %s - duration %02.2fs (%02.2fs->%02.2fs)\n", szFile, file_split_dur, chunk_start, (chunk_start+split_dur));
+                       fprintf(stderr, "Extracting chunk %s - duration %02.2fs (%02.2fs->%02.2fs)\n", szFile, file_split_dur, chunk_start, (chunk_start+split_dur));
                } else {
-                       fprintf(stdout, "Storing split-file %s - duration %02.2f seconds\n", szFile, file_split_dur);
+                       fprintf(stderr, "Storing split-file %s - duration %02.2f seconds\n", szFile, file_split_dur);
                }
 
                /*repack CTSs*/
@@ -1072,7 +1188,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                        new_track_dur = gf_isom_get_track_duration(dest, tki->dst_tk);
                        count = gf_isom_get_edit_segment_count(mp4, tki->tk);
                        if (count>2) {
-                               fprintf(stdout, "Warning: %d edit segments - not supported while splitting (max 2) - ignoring extra\n", count);
+                               fprintf(stderr, "Warning: %d edit segments - not supported while splitting (max 2) - ignoring extra\n", count);
                                count=2;
                        }
                        for (j=0; j<count; j++) {
@@ -1081,7 +1197,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                        
                                gf_isom_get_edit_segment(mp4, tki->tk, j+1, &editTime, &segDur, &MediaTime, &mode);
                                if (!j && (mode!=GF_ISOM_EDIT_EMPTY) ) {
-                                       fprintf(stdout, "Warning: Edit list doesn't look like a track delay scheme - ignoring\n");
+                                       fprintf(stderr, "Warning: Edit list doesn't look like a track delay scheme - ignoring\n");
                                        break;
                                }
                                if (mode==GF_ISOM_EDIT_NORMAL) {
@@ -1123,7 +1239,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb,
                gf_isom_clone_pl_indications(mp4, dest);
                e = gf_isom_close(dest);
                dest = NULL;
-               if (e) fprintf(stdout, "Error storing file %s\n", gf_error_to_string(e));
+               if (e) fprintf(stderr, "Error storing file %s\n", gf_error_to_string(e));
                if (is_last || chunk_extraction) break;
                cur_file++;
        }
@@ -1134,23 +1250,39 @@ err_exit:
        return e;
 }
 
-GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat);
+GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines);
 
-GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat)
+GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines)
 {
        u32 i, j, count, nb_tracks, nb_samp, nb_done;
        GF_ISOFile *orig;
        GF_Err e;
+       char *opts, *multi_cat;
        Float ts_scale;
        Double dest_orig_dur;
        u32 dst_tk, tk_id, mtype;
        u64 insert_dts;
+       Bool is_isom;
        GF_ISOSample *samp;
+       Double aligned_to_DTS = 0;
 
-       if (strchr(fileName, '*')) return cat_multiple_files(dest, fileName, import_flags, force_fps, frames_per_sample, tmp_dir, force_cat);
+       if (strchr(fileName, '*')) return cat_multiple_files(dest, fileName, import_flags, force_fps, frames_per_sample, tmp_dir, force_cat, align_timelines);
+       
+       multi_cat = strchr(fileName, '+');
+       if (multi_cat) {
+               multi_cat[0] = 0;
+               multi_cat = &multi_cat[1];
+       }
+       opts = strchr(fileName, ':');
+       if (opts && (opts[1]=='\\')) 
+               opts = strchr(fileName, ':');
 
        e = GF_OK;
-       if (!gf_isom_probe_file(fileName)) {
+
+       /*if options are specified, reimport the file*/
+       is_isom = opts ? 0 : gf_isom_probe_file(fileName);
+
+       if (!is_isom || opts) {
                orig = gf_isom_open("temp", GF_ISOM_WRITE_EDIT, tmp_dir);
                e = import_file(orig, fileName, import_flags, force_fps, frames_per_sample);
                if (e) return e;
@@ -1159,6 +1291,20 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                orig = gf_isom_open(fileName, GF_ISOM_OPEN_EDIT, tmp_dir);
        }
 
+       while (multi_cat) {
+               char *sep = strchr(multi_cat, '+');
+               if (sep) sep[0] = 0;
+               
+               e = import_file(orig, multi_cat, import_flags, force_fps, frames_per_sample);
+               if (e) {
+                       gf_isom_delete(orig);
+                       return e;
+               }
+               if (!sep) break;
+               sep[0]=':';
+               multi_cat = sep+1;
+       }
+
        nb_samp = 0;
        nb_tracks = gf_isom_get_track_count(orig);
        for (i=0; i<nb_tracks; i++) {
@@ -1167,7 +1313,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                case GF_ISOM_MEDIA_HINT:
                case GF_ISOM_MEDIA_OD:
                case GF_ISOM_MEDIA_FLASH:
-                       fprintf(stdout, "WARNING: Track ID %d (type %s) not handled by concatenation - removing from destination\n", gf_isom_get_track_id(orig, i+1), gf_4cc_to_str(mtype));
+                       fprintf(stderr, "WARNING: Track ID %d (type %s) not handled by concatenation - removing from destination\n", gf_isom_get_track_id(orig, i+1), gf_4cc_to_str(mtype));
                        continue;
                case GF_ISOM_MEDIA_AUDIO:
                case GF_ISOM_MEDIA_TEXT:
@@ -1189,7 +1335,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                }
        }
        if (!nb_samp) {
-               fprintf(stdout, "No suitable media tracks to cat in %s - skipping\n", fileName);
+               fprintf(stderr, "No suitable media tracks to cat in %s - skipping\n", fileName);
                goto err_exit;
        }
        
@@ -1199,7 +1345,16 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
        }
        dest_orig_dur /= gf_isom_get_timescale(dest);
 
-       fprintf(stdout, "Appending file %s\n", fileName);
+       aligned_to_DTS = 0;
+       for (i=0; i<gf_isom_get_track_count(dest); i++) {
+               Double track_dur = (Double) gf_isom_get_media_duration(dest, i+1);
+               track_dur /= gf_isom_get_media_timescale(dest, i+1);
+               if (aligned_to_DTS < track_dur) {
+                       aligned_to_DTS = track_dur;
+               }
+       }
+
+       fprintf(stderr, "Appending file %s\n", fileName);
        nb_done = 0;
        for (i=0; i<nb_tracks; i++) {
                u64 last_DTS, dest_track_dur_before_cat;
@@ -1227,6 +1382,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                        if (!gf_isom_is_self_contained(orig, i+1, 1)) continue;
                        break;
                }
+
                dst_tk = 0;
                tk_id = gf_isom_get_track_id(orig, i+1);
                dst_tk = gf_isom_get_track_by_id(dest, tk_id);
@@ -1259,10 +1415,10 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                                avc_dst = gf_isom_avc_config_get(dest, dst_tk, 1);
                                
                                if (avc_src->AVCLevelIndication!=avc_dst->AVCLevelIndication) {
-                                       fprintf(stdout, "Cannot concatenate files: Different AVC Level Indication between source (%d) and destination (%d)\n", avc_src->AVCLevelIndication, avc_dst->AVCLevelIndication);
+                                       fprintf(stderr, "Cannot concatenate files: Different AVC Level Indication between source (%d) and destination (%d)\n", avc_src->AVCLevelIndication, avc_dst->AVCLevelIndication);
                                        dst_tk = 0;
                                } else if (avc_src->AVCProfileIndication!=avc_dst->AVCProfileIndication) {
-                                       fprintf(stdout, "Cannot concatenate files: Different AVC Profile Indication between source (%d) and destination (%d)\n", avc_src->AVCProfileIndication, avc_dst->AVCProfileIndication);
+                                       fprintf(stderr, "Cannot concatenate files: Different AVC Profile Indication between source (%d) and destination (%d)\n", avc_src->AVCProfileIndication, avc_dst->AVCProfileIndication);
                                        dst_tk = 0;
                                }
                                else {
@@ -1287,6 +1443,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                                                        }
                                                }
                                                if (!found) {
+                                                       fprintf(stderr, "WARNING: Concatenating track ID %d with different SPS - result file might be broken\n", tk_id);
                                                        gf_list_rem(avc_src->sequenceParameterSets, j);
                                                        j--;
                                                        gf_list_add(avc_dst->sequenceParameterSets, slc);
@@ -1305,23 +1462,22 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                                                        }
                                                }
                                                if (!found) {
+                                                       fprintf(stderr, "WARNING: Concatenating track ID %d with different PPS - result file might be broken\n", tk_id);
                                                        gf_list_rem(avc_src->pictureParameterSets, j);
                                                        j--;
                                                        gf_list_add(avc_dst->pictureParameterSets, slc);
                                                }
                                        }
-
                                        gf_isom_avc_config_update(dest, dst_tk, 1, avc_dst);
                                }
 
-
                                gf_odf_avc_cfg_del(avc_src);
                                gf_odf_avc_cfg_del(avc_dst);
                        }
 
                        if (!dst_tk && force_cat) {
                                dst_tk = gf_isom_get_track_by_id(dest, tk_id);
-                               fprintf(stdout, "WARNING: Concatenating track ID %d even though sample descriptions do not match\n", tk_id);
+                               fprintf(stderr, "WARNING: Concatenating track ID %d even though sample descriptions do not match\n", tk_id);
                        }
                }
 
@@ -1360,10 +1516,29 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                }
                /*looks like a new file*/
                if (!dst_tk) {
-                       fprintf(stdout, "No suitable destination track found - creating new one (type %s)\n", gf_4cc_to_str(mtype));
+                       fprintf(stderr, "No suitable destination track found - creating new one (type %s)\n", gf_4cc_to_str(mtype));
                        e = gf_isom_clone_track(orig, i+1, dest, 1, &dst_tk);
                        if (e) goto err_exit;
                        gf_isom_clone_pl_indications(orig, dest);
+
+                       if (align_timelines) {
+                               u32 max_timescale = 0;
+                               u32 dst_timescale = 0;
+                               u32 idx;
+                               for (idx=0; idx<nb_tracks; idx++) {
+                                       if (max_timescale < gf_isom_get_media_timescale(orig, idx+1)) 
+                                               max_timescale = gf_isom_get_media_timescale(orig, idx+1); 
+                               }
+                               if (dst_timescale < max_timescale) {
+                                       dst_timescale = gf_isom_get_media_timescale(dest, dst_tk); 
+                                       idx = max_timescale / dst_timescale;
+                                       if (dst_timescale * idx < max_timescale) idx ++;
+                                       dst_timescale *= idx;
+
+                                       gf_isom_set_media_timescale(dest, dst_tk, max_timescale, 0);
+                               }
+                       }
+
                        /*remove cloned edit list, as it will be rewritten after import*/
                        gf_isom_remove_edit_segments(dest, dst_tk);
                } else {
@@ -1371,9 +1546,11 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                }
 
                dest_track_dur_before_cat = gf_isom_get_media_duration(dest, dst_tk);
-
                count = gf_isom_get_sample_count(dest, dst_tk);
-               if (use_ts_dur && (count>1)) {
+
+               if (align_timelines) {
+                       insert_dts = (u64) (aligned_to_DTS * gf_isom_get_media_timescale(dest, dst_tk));
+               } else if (use_ts_dur && (count>1)) {
                        insert_dts = 2*gf_isom_get_sample_dts(dest, dst_tk, count) - gf_isom_get_sample_dts(dest, dst_tk, count-1);
                } else {
                        insert_dts = dest_track_dur_before_cat;
@@ -1431,6 +1608,12 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                }
 
                if (merge_edits) {
+                       /*convert from media time to track time*/
+                       Double rescale = (Float) gf_isom_get_timescale(dest);
+                       rescale /= (Float) gf_isom_get_media_timescale(dest, dst_tk);
+                       /*convert from orig to dst time scale*/
+                       rescale *= ts_scale;
+
                        /*get the first edit normal mode and add the new track dur*/
                        for (j=nb_edits; j>0; j--) {
                                u64 editTime, segmentDuration, mediaTime;
@@ -1438,14 +1621,18 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                                gf_isom_get_edit_segment(dest, dst_tk, j, &editTime, &segmentDuration, &mediaTime, &editMode);
 
                                if (editMode==GF_ISOM_EDIT_NORMAL) {
+                                       Double prev_dur = (Double) (s64) dest_track_dur_before_cat;
                                        Double dur = (Double) (s64) gf_isom_get_media_duration(orig, i+1);
-                                       /*convert to dst time scale*/
-                                       dur *= ts_scale;
 
-                                       /*convert to track time scale*/
-                                       ts_scale = (Float) gf_isom_get_timescale(dest);
-                                       ts_scale /= (Float) gf_isom_get_media_timescale(dest, dst_tk);
-                                       dur *= ts_scale;
+                                       dur *= rescale;
+                                       prev_dur *= rescale;
+                                       
+                                       /*safety test: some files have broken edit lists. If no more than 2 entries, check that the segment duration 
+                                       is less or equal to the movie duration*/
+                                       if (prev_dur < segmentDuration) {
+                                               fprintf(stderr, "Warning: suspicious edit list entry found: duration %g sec but longest track duration before cat is %g - fixing it\n", (Double) (s64) segmentDuration/1000.0, prev_dur/1000);
+                                               segmentDuration = (u64) (s64) ( (Double) (s64) (dest_track_dur_before_cat - mediaTime) * rescale ); 
+                                       }
 
                                        segmentDuration += (u64) (s64) dur;
                                        gf_isom_modify_edit_segment(dest, dst_tk, j, segmentDuration, mediaTime, editMode);
@@ -1519,7 +1706,7 @@ typedef struct
        Double force_fps;
        u32 frames_per_sample;
        char *tmp_dir;
-       Bool force_cat;
+       Bool force_cat, align_timelines;
 } CATEnum;
 
 Bool cat_enumerate(void *cbk, char *szName, char *szPath)
@@ -1535,12 +1722,12 @@ Bool cat_enumerate(void *cbk, char *szName, char *szPath)
        strcpy(szFileName, szName);
        strcat(szFileName, cat_enum->szOpt);
 
-       e = cat_isomedia_file(cat_enum->dest, szFileName, cat_enum->import_flags, cat_enum->force_fps, cat_enum->frames_per_sample, cat_enum->tmp_dir, cat_enum->force_cat);
+       e = cat_isomedia_file(cat_enum->dest, szFileName, cat_enum->import_flags, cat_enum->force_fps, cat_enum->frames_per_sample, cat_enum->tmp_dir, cat_enum->force_cat, cat_enum->align_timelines);
        if (e) return 1;
        return 0;
 }
 
-GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat)
+GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines)
 {
        CATEnum cat_enum;
        char *sep;
@@ -1551,6 +1738,7 @@ GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Do
        cat_enum.frames_per_sample = frames_per_sample;
        cat_enum.tmp_dir = tmp_dir;
        cat_enum.force_cat = force_cat;
+       cat_enum.align_timelines = align_timelines;
 
        strcpy(cat_enum.szPath, fileName);
        sep = strrchr(cat_enum.szPath, GF_PATH_SEPARATOR);
@@ -1584,6 +1772,9 @@ GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Do
 
 GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *logs) 
 {
+#ifdef GPAC_DISABLE_SMGR
+       return GF_NOT_SUPPORTED;
+#else
        GF_Err e;
        GF_SceneLoader load;
        GF_SceneManager *ctx;
@@ -1604,7 +1795,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
        e = gf_sm_load_init(&load);
        if (e<0) {
                gf_sm_load_done(&load);
-               fprintf(stdout, "Cannot load context %s - %s\n", in, gf_error_to_string(e));
+               fprintf(stderr, "Cannot load context %s - %s\n", in, gf_error_to_string(e));
                goto err_exit;
        }
        e = gf_sm_load_run(&load);
@@ -1612,7 +1803,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
 
 #ifndef GPAC_DISABLE_SCENE_STATS
        if (opts->auto_quant) {
-               fprintf(stdout, "Analysing Scene for Automatic Quantization\n");
+               fprintf(stderr, "Analysing Scene for Automatic Quantization\n");
                statsman = gf_sm_stats_new();
                e = gf_sm_stats_for_scene(statsman, ctx);
                if (!e) {
@@ -1620,24 +1811,24 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
                        /*LASeR*/
                        if (opts->auto_quant==1) {
                                if (opts->resolution > (s32)stats->frac_res_2d) {
-                                       fprintf(stdout, " Given resolution %d is (unnecessarily) too high, using %d instead.\n", opts->resolution, stats->frac_res_2d);
+                                       fprintf(stderr, " Given resolution %d is (unnecessarily) too high, using %d instead.\n", opts->resolution, stats->frac_res_2d);
                                        opts->resolution = stats->frac_res_2d;
                                } else if (stats->int_res_2d + opts->resolution <= 0) {
-                                       fprintf(stdout, " Given resolution %d is too low, using %d instead.\n", opts->resolution, stats->int_res_2d - 1);
+                                       fprintf(stderr, " Given resolution %d is too low, using %d instead.\n", opts->resolution, stats->int_res_2d - 1);
                                        opts->resolution = 1 - stats->int_res_2d;
                                }                               
                                opts->coord_bits = stats->int_res_2d + opts->resolution;
-                               fprintf(stdout, " Coordinates & Lengths encoded using ");
-                               if (opts->resolution < 0) fprintf(stdout, "only the %d most significant bits (of %d).\n", opts->coord_bits, stats->int_res_2d);
-                               else fprintf(stdout, "a %d.%d representation\n", stats->int_res_2d, opts->resolution);
+                               fprintf(stderr, " Coordinates & Lengths encoded using ");
+                               if (opts->resolution < 0) fprintf(stderr, "only the %d most significant bits (of %d).\n", opts->coord_bits, stats->int_res_2d);
+                               else fprintf(stderr, "a %d.%d representation\n", stats->int_res_2d, opts->resolution);
 
-                               fprintf(stdout, " Matrix Scale & Skew Coefficients ");
+                               fprintf(stderr, " Matrix Scale & Skew Coefficients ");
                                if (opts->coord_bits - 8 < stats->scale_int_res_2d) {
                                        opts->scale_bits = stats->scale_int_res_2d - opts->coord_bits + 8;
-                                       fprintf(stdout, "encoded using a %d.8 representation\n", stats->scale_int_res_2d);
+                                       fprintf(stderr, "encoded using a %d.8 representation\n", stats->scale_int_res_2d);
                                } else  {
                                        opts->scale_bits = 0;
-                                       fprintf(stdout, "encoded using a %d.8 representation\n", opts->coord_bits - 8);
+                                       fprintf(stderr, "encoded using a %d.8 representation\n", opts->coord_bits - 8);
                                }
                        } 
 #ifndef GPAC_DISABLE_VRML
@@ -1684,7 +1875,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
 #endif /*GPAC_DISABLE_SCENE_STATS*/
 
        if (e<0) {
-               fprintf(stdout, "Error loading file %s\n", gf_error_to_string(e));
+               fprintf(stderr, "Error loading file %s\n", gf_error_to_string(e));
                goto err_exit;
        } else {
                gf_log_cbk prev_logs = NULL;
@@ -1709,6 +1900,8 @@ err_exit:
        gf_sm_del(ctx);
        gf_sg_del(sg);
        return e;
+
+#endif /*GPAC_DISABLE_SMGR*/
 }
 #endif /*GPAC_DISABLE_SCENE_ENCODER*/
 
@@ -1725,6 +1918,7 @@ static u32 GetNbBits(u32 MaxVal)
        return k;
 }
 
+#ifndef GPAC_DISABLE_SMGR
 GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCallback)(GF_ISOSample *))
 {
        GF_Err                  e;
@@ -1815,15 +2009,15 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa
                /*NO CHANGE TO BIFSC otherwise the generated update will not match the input context*/
                nbb = GetNbBits(ctx->max_node_id);
                if (!bcfg->nodeIDbits) bcfg->nodeIDbits=nbb;
-               if (bcfg->nodeIDbits<nbb) fprintf(stdout, "Warning: BIFSConfig.NodeIDBits TOO SMALL\n");
+               if (bcfg->nodeIDbits<nbb) fprintf(stderr, "Warning: BIFSConfig.NodeIDBits TOO SMALL\n");
 
                nbb = GetNbBits(ctx->max_route_id);
                if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb;
-               if (bcfg->routeIDbits<nbb) fprintf(stdout, "Warning: BIFSConfig.RouteIDBits TOO SMALL\n");
+               if (bcfg->routeIDbits<nbb) fprintf(stderr, "Warning: BIFSConfig.RouteIDBits TOO SMALL\n");
 
                nbb = GetNbBits(ctx->max_proto_id);
                if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb;
-               if (bcfg->protoIDbits<nbb) fprintf(stdout, "Warning: BIFSConfig.ProtoIDBits TOO SMALL\n");
+               if (bcfg->protoIDbits<nbb) fprintf(stderr, "Warning: BIFSConfig.ProtoIDBits TOO SMALL\n");
 
                /*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/
                encode_names = 0;
@@ -1862,6 +2056,8 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa
        gf_bifs_encoder_del(bifsenc);
        return e;
 }
+#endif /*GPAC_DISABLE_SMGR*/
+
 
 #endif /*GPAC_DISABLE_BIFS_ENC*/
 
@@ -1875,8 +2071,8 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa
  */
 GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *outputContext, const char *tmpdir) 
 {
-#if defined(GPAC_DISABLE_BIFS_ENC) || defined(GPAC_DISABLE_SCENE_ENCODER) || defined (GPAC_DISABLE_SCENE_DUMP)
-       fprintf(stdout, "BIFS encoding is not supported in this build of GPAC\n");
+#if defined(GPAC_DISABLE_SMGR) || defined(GPAC_DISABLE_BIFS_ENC) || defined(GPAC_DISABLE_SCENE_ENCODER) || defined (GPAC_DISABLE_SCENE_DUMP)
+       fprintf(stderr, "BIFS encoding is not supported in this build of GPAC\n");
        return GF_NOT_SUPPORTED;
 #else
        GF_Err e;
@@ -1896,7 +2092,7 @@ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *ou
        if (!e) e = gf_sm_load_run(&load);
        gf_sm_load_done(&load);
        if (e) {
-               fprintf(stdout, "Cannot load context %s - %s\n", inputContext, gf_error_to_string(e));
+               fprintf(stderr, "Cannot load context %s - %s\n", inputContext, gf_error_to_string(e));
                goto exit;
        }
 
@@ -1913,10 +2109,10 @@ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *ou
        if (!e) e = gf_sm_load_run(&load);
        gf_sm_load_done(&load);
        if (e) {
-               fprintf(stdout, "Cannot load chunk context %s - %s\n", chunkFile, gf_error_to_string(e));
+               fprintf(stderr, "Cannot load chunk context %s - %s\n", chunkFile, gf_error_to_string(e));
                goto exit;
        }
-       fprintf(stdout, "Context and chunks loaded\n");
+       fprintf(stderr, "Context and chunks loaded\n");
 
        /* Assumes that the first AU contains only one command a SceneReplace and 
           that is not part of the current chunk */
@@ -1972,6 +2168,7 @@ exit:
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
 
+#ifndef GPAC_DISABLE_CORE_TOOLS
 void sax_node_start(void *sax_cbck, const char *node_name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
 {
        char szCheck[100];
@@ -2024,12 +2221,12 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool ma
 
        type = gf_xml_get_root_type(file_name, &e);
        if (!type) {
-               fprintf(stdout, "Cannot process XML file %s: %s\n", file_name, gf_error_to_string(e) );
+               fprintf(stderr, "Cannot process XML file %s: %s\n", file_name, gf_error_to_string(e) );
                return NULL;
        }
        if (make_wgt) {
                if (strcmp(type, "widget")) {
-                       fprintf(stdout, "XML Root type %s differs from \"widget\" \n", type);
+                       fprintf(stderr, "XML Root type %s differs from \"widget\" \n", type);
                        gf_free(type);
                        return NULL;
                }
@@ -2078,7 +2275,7 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool ma
                else if (!stricmp(type, "xmt-a")) mtype = ascii ? GF_4CC('x','m','t','a') : GF_4CC('x','m','t','z');
        }
        if (!mtype) {
-               fprintf(stdout, "Missing 4CC code for meta name - please use ABCD:fileName\n");
+               fprintf(stderr, "Missing 4CC code for meta name - please use ABCD:fileName\n");
                e = GF_BAD_PARAM;
                goto exit;
        }
@@ -2100,7 +2297,7 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool ma
                        fclose(test);
                        if (gf_isom_probe_file(item)) {
                                if (isom_src) {
-                                       fprintf(stdout, "Cannot package several IsoMedia files together\n");
+                                       fprintf(stderr, "Cannot package several IsoMedia files together\n");
                                        e = GF_NOT_SUPPORTED;
                                        goto exit;
                                }
@@ -2181,6 +2378,14 @@ exit:
        }
        return file;
 }
+#else
+GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool make_wgt)
+{
+       fprintf(stderr, "XML Not supported in this build of GPAC - cannot package file\n");
+       return NULL;
+}
+#endif //#ifndef GPAC_DISABLE_CORE_TOOLS
+
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
index 0b577c830f03cfe400a55fdd299a75cb2bd9f107..ef2869cfb9bf104abe7f7e57c307471164cc8bcc 100644 (file)
@@ -1,14 +1,15 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Telecom ParisTech 2010-
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *                     Authors: Jean Le Feuvre
  *
  *  This file is part of GPAC / mp4box application
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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.
@@ -46,7 +47,7 @@
 
 void PrintStreamerUsage()
 {
-       fprintf(stdout, "File Streamer Options\n"
+       fprintf(stderr, "File Streamer Options\n"
                        "\n"
                        "MP4Box can stream ISO files to RTP. The streamer currently doesn't support\n"
                        "data carrouselling and will therefore not handle BIFS and OD streams properly.\n"
@@ -82,7 +83,7 @@ int stream_file_rtp(int argc, char **argv)
                char *arg = argv[i];
 
                if (arg[0] != '-') {
-                       if (inName) { fprintf(stdout, "Error - 2 input names specified, please check usage\n"); return 1; }
+                       if (inName) { fprintf(stderr, "Error - 2 input names specified, please check usage\n"); return 1; }
                        inName = arg;
                }
                else if (!stricmp(arg, "-noloop")) loop = 0;
@@ -96,7 +97,7 @@ int stream_file_rtp(int argc, char **argv)
        }
 
        if (!gf_isom_probe_file(inName)) {
-               fprintf(stdout, "File %s is not a valid ISO Media file and cannot be streamed\n", inName);
+               fprintf(stderr, "File %s is not a valid ISO Media file and cannot be streamed\n", inName);
                return 1;
        }
 
@@ -106,10 +107,10 @@ int stream_file_rtp(int argc, char **argv)
 
        file_streamer = gf_isom_streamer_new(inName, ip_dest, port, loop, force_mpeg4, path_mtu, ttl, ifce_addr);
        if (!file_streamer) {
-               fprintf(stdout, "Cannot create file streamer\n");
+               fprintf(stderr, "Cannot create file streamer\n");
        } else {
                u32 check = 50;
-               fprintf(stdout, "Starting streaming %s to %s:%d\n", inName, ip_dest, port);
+               fprintf(stderr, "Starting streaming %s to %s:%d\n", inName, ip_dest, port);
                gf_isom_streamer_write_sdp(file_streamer, sdp_file);
 
                while (1) {
@@ -132,7 +133,7 @@ int stream_file_rtp(int argc, char **argv)
 
 void PrintLiveUsage()
 {
-       fprintf(stdout
+       fprintf(stderr
 
                "Live scene encoder options:\n"
                "-dst=IP    destination IP - default: NULL\n"
@@ -244,7 +245,7 @@ static void live_session_callback(void *calling_object, u16 ESID, char *data, u3
                                rtpch->carousel_size = size;
                                rtpch->carousel_ts = ts;
                                rtpch->time_at_carousel_store = gf_sys_clock();
-                               fprintf(stdout, "\nStream %d: Storing new carousel TS "LLD", %d bytes\n", ESID, ts, size);
+                               fprintf(stderr, "\nStream %d: Storing new carousel TS "LLD", %d bytes\n", ESID, ts, size);
                        }
                        /*send data*/
                        else {
@@ -257,7 +258,7 @@ static void live_session_callback(void *calling_object, u16 ESID, char *data, u3
 
                                gf_rtp_streamer_send_au_with_sn(rtpch->rtp, data, size, ts, ts, rap, critical);
 
-                               fprintf(stdout, "Stream %d: Sending update at TS "LLD", %d bytes - RAP %d - critical %d\n", ESID, ts, size, rap, critical);
+                               fprintf(stderr, "Stream %d: Sending update at TS "LLD", %d bytes - RAP %d - critical %d\n", ESID, ts, size, rap, critical);
                                rtpch->rap = rtpch->critical = 0;
 
                                if (rtpch->manual_rtcp) gf_rtp_streamer_send_rtcp(rtpch->rtp, 0, 0);
@@ -277,7 +278,7 @@ static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch)
 
                        gf_rtp_streamer_send_au_with_sn(ch->rtp, ch->carousel_data, ch->carousel_size, ts, ts, 1, 0);
                        ch->last_carousel_time = now - livesess->start_time;
-                       fprintf(stdout, "Stream %d: Sending carousel at TS "LLD", %d bytes\n", ch->ESID, ts, ch->carousel_size);
+                       fprintf(stderr, "Stream %d: Sending carousel at TS "LLD", %d bytes\n", ch->ESID, ts, ch->carousel_size);
 
                        if (ch->manual_rtcp) {
                                ts = ch->carousel_ts + ch->timescale * ( gf_sys_clock() - ch->init_time + ch->ts_delta)/1000;
@@ -295,7 +296,7 @@ static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch)
                                }
                                gf_rtp_streamer_send_au_with_sn(ch->rtp, ch->carousel_data, ch->carousel_size, ts, ts, 1, 0);
                                ch->last_carousel_time = now - livesess->start_time;
-                               fprintf(stdout, "Stream %d: Sending carousel at TS "LLD"        , %d bytes\n", ch->ESID, ts, ch->carousel_size);
+                               fprintf(stderr, "Stream %d: Sending carousel at TS "LLD"        , %d bytes\n", ch->ESID, ts, ch->carousel_size);
 
                                if (ch->manual_rtcp) {
                                        ts = ch->carousel_ts + ch->timescale*(gf_sys_clock()-ch->init_time + ch->ts_delta)/1000;
@@ -480,7 +481,7 @@ int live_session(int argc, char **argv)
         else if (!strnicmp(arg, "-tcp=", 5)) { sk_port = atoi(arg+5); udp = 0; }               
        }
        if (!filename) {
-               fprintf(stdout, "Missing filename\n");
+               fprintf(stderr, "Missing filename\n");
                PrintLiveUsage();
                return 1;
        }
@@ -489,7 +490,7 @@ int live_session(int argc, char **argv)
 
        livesess.seng = gf_seng_init(&livesess, filename, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0);
     if (!livesess.seng) {
-               fprintf(stdout, "Cannot create scene engine\n");
+               fprintf(stderr, "Cannot create scene engine\n");
                return 1;
     }
        if (livesess.streams) live_session_setup(&livesess, dst, dst_port, path_mtu, ttl, ifce_addr, sdp_name);
@@ -520,7 +521,7 @@ int live_session(int argc, char **argv)
                                sscanf(arg, "-rap=ESID=%u:%u", &id, &period);
                                e = gf_seng_enable_aggregation(livesess.seng, id, 1);
                                if (e) {
-                                       fprintf(stdout, "Cannot enable aggregation on stream %u: %s\n", id, gf_error_to_string(e));
+                                       fprintf(stderr, "Cannot enable aggregation on stream %u: %s\n", id, gf_error_to_string(e));
                                        goto exit;
                                }
                        } else {
@@ -572,7 +573,7 @@ int live_session(int argc, char **argv)
                                {
                                        GF_Err e;
                                        char szCom[8192];
-                                       fprintf(stdout, "Enter command to send:\n");
+                                       fprintf(stderr, "Enter command to send:\n");
                                        szCom[0] = 0;
                                        if (1 > scanf("%[^\t\n]", szCom)){
                                            fprintf(stderr, "No command entered properly, aborting.\n");
@@ -581,7 +582,7 @@ int live_session(int argc, char **argv)
                                        /*stdin flush bug*/
                                        while (getchar()!='\n') {}
                                        e = gf_seng_encode_from_string(livesess.seng, 0, 0, szCom, live_session_callback);
-                                       if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e));
+                                       if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
                                        e = gf_seng_aggregate_context(livesess.seng, 0);
                                        livesess.critical = 0;
                                        update_context = 1;
@@ -593,7 +594,7 @@ int live_session(int argc, char **argv)
                                {
                                        GF_Err e;
                                        char szCom[8192];
-                                       fprintf(stdout, "Enter command to send:\n");
+                                       fprintf(stderr, "Enter command to send:\n");
                                        szCom[0] = 0;
                                        if (1 > scanf("%[^\t\n]", szCom)){
                                            printf("No command entered properly, aborting.\n");
@@ -602,7 +603,7 @@ int live_session(int argc, char **argv)
                                        /*stdin flush bug*/
                                        while (getchar()!='\n') {}
                                        e = gf_seng_encode_from_string(livesess.seng, 0, 1, szCom, live_session_callback);
-                                       if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e));
+                                       if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
                                        livesess.critical = 0;                          
                                        e = gf_seng_aggregate_context(livesess.seng, 0);
 
@@ -612,13 +613,13 @@ int live_session(int argc, char **argv)
                                case 'p':
                                {
                                        char rad[GF_MAX_PATH];
-                                       fprintf(stdout, "Enter output file name - \"std\" for stdout: ");
+                                       fprintf(stderr, "Enter output file name - \"std\" for stderr: ");
                                        if (1 > scanf("%s", rad)){
                                            fprintf(stderr, "No ouput file name entered, aborting.\n");
                                            break;
                                        }
                                        e = gf_seng_save_context(livesess.seng, !strcmp(rad, "std") ? NULL : rad);
-                                       fprintf(stdout, "Dump done (%s)\n", gf_error_to_string(e));
+                                       fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e));
                                }
                                        break;
                                case 'F':
@@ -637,7 +638,7 @@ int live_session(int argc, char **argv)
                        if (mod_time != last_src_modif) {
                                FILE *srcf;
                                char flag_buf[201], *flag;
-                               fprintf(stdout, "Update file modified - processing\n");
+                               fprintf(stderr, "Update file modified - processing\n");
                                last_src_modif = mod_time;
 
                                srcf = gf_f64_open(src_name, "rt");
@@ -689,7 +690,7 @@ int live_session(int argc, char **argv)
                                }
 
                                e = gf_seng_encode_from_file(livesess.seng, es_id, aggregate_au ? 0 : 1, src_name, live_session_callback);
-                               if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e));
+                               if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
                                e = gf_seng_aggregate_context(livesess.seng, 0);
 
                                update_context = no_rap ? 0 : 1;
@@ -766,7 +767,7 @@ int live_session(int argc, char **argv)
 
                                if (update_length) {
                                        e = gf_seng_encode_from_string(livesess.seng, es_id, aggregate_au ? 0 : 1, update_buffer, live_session_callback);
-                                       if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e));
+                                       if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
                                        e = gf_seng_aggregate_context(livesess.seng, 0);
 
                                        update_context = 1;
index 54e0e0e086ac56cb7ca637b74dca7fdff03c13f4..2051753a97cfa3b15e3e7c2e10c9600faeafdb05 100644 (file)
@@ -1,12 +1,13 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mp4box application
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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.
@@ -24,6 +25,7 @@
 
 
 #include <gpac/download.h>
+#include <gpac/network.h>
 
 #ifndef GPAC_DISABLE_SMGR
 #include <gpac/scene_manager.h>
 
 #else
 
+#if defined(WIN32) && !defined(_WIN32_WCE)
+#include <io.h>
+#include <fcntl.h>
+#endif
+
 #include <gpac/media_tools.h>
 
 /*RTP packetizer flags*/
@@ -63,8 +70,8 @@ void convert_file_info(char *inName, u32 trackID);
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
 GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample);
-GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start, Bool adjust_split_end, char *outName, const char *tmpdir);
-GF_Err cat_isomedia_file(GF_ISOFile *mp4, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat);
+GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double interleaving_time, Double chunk_start, Bool adjust_split_end, char *outName, const char *tmpdir);
+GF_Err cat_isomedia_file(GF_ISOFile *mp4, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines);
 
 #if !defined(GPAC_DISABLE_SCENE_ENCODER)
 GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *logs);
@@ -101,7 +108,8 @@ void dump_file_rtp(GF_ISOFile *file, char *inName);
 void DumpSDP(GF_ISOFile *file, char *inName);
 #endif
 
-void dump_file_ts(GF_ISOFile *file, char *inName);
+void dump_file_timestamps(GF_ISOFile *file, char *inName);
+void dump_file_nal(GF_ISOFile *file, u32 trackID, char *inName);
 
 #ifndef GPAC_DISABLE_ISOM_DUMP
 void dump_file_ismacryp(GF_ISOFile *file, char *inName);
@@ -115,9 +123,7 @@ void PrintLanguages();
 const char *GetLanguageCode(char *lang);
 
 #ifndef GPAC_DISABLE_MPEG2TS
-void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name, Bool prog_num, 
-                                  Double dash_duration, Bool seg_at_rap, u32 subseg_per_seg,
-                                  char *seg_name, char *seg_ext, Bool use_url_template, Bool single_segment, u32 representation_idx, Bool last_rep);
+void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name, Bool prog_num);
 #endif 
 
 
@@ -169,15 +175,15 @@ u32 nb_itunes_tags = sizeof(itags) / sizeof(itunes_tag);
 
 void PrintVersion()
 {
-       fprintf(stdout, "MP4Box - GPAC version " GPAC_FULL_VERSION "\n"
-               "GPAC Copyright: (c) Jean Le Feuvre 2000-2005\n\t\t(c) ENST 2005-200X\n"
+       fprintf(stderr, "MP4Box - GPAC version " GPAC_FULL_VERSION "\n"
+               "GPAC Copyright (c) Telecom ParisTech 2000-2012\n"
                "GPAC Configuration: " GPAC_CONFIGURATION "\n"
                "Features: %s\n", gpac_features());
 }
 
 void PrintGeneralUsage()
 {
-       fprintf(stdout, "General Options:\n"
+       fprintf(stderr, "General Options:\n"
 #ifdef GPAC_MEMORY_TRACKING
                        " -mem-track:  enables memory tracker\n"        
 #endif
@@ -197,6 +203,7 @@ void PrintGeneralUsage()
                        "                       * Note: By default input (MP4,3GP) file is overwritten\n"
                        " -tmp dirname         specifies directory for temporary file creation\n"
                        "                       * Note: Default temp dir is OS-dependent\n"
+                       " -write-buffer SIZE   specifies write buffer in bytes for ISOBMF files\n"
                        " -no-sys              removes all MPEG-4 Systems info except IOD (profiles)\n"
                        "                       * Note: Set by default whith '-add' and '-cat'\n"
                        " -no-iod              removes InitialObjectDescriptor from file\n"
@@ -252,33 +259,67 @@ void PrintGeneralUsage()
                        " -group-clean         removes all group information from all tracks\n"
                " -group-single        puts all tracks in a single group\n"
                        " -ref id:XXXX:refID   adds a reference of type 4CC from track ID to track refID\n"
-                       "\n"
-                       " -dash dur            enables DASH-ing of the file with a segment duration of DUR\n"
+                       "\n");
+}
+
+void PrintDASHUsage()
+{
+       fprintf(stderr, "DASH Options:\n"
+                       " -dash dur            enables DASH-ing of the file(s) with a segment duration of DUR ms\n"
                        "                       Note: the duration of a fragment (subsegment) is set\n"
-                       "                                               using the interleaver (-inter) switch.\n"
-                       "                       Note: You can specify -rap switch to split segments at RAP boundaries\n"
-                       "                       Note: when single-segment is used, this specifies the duration of a subsegment\n"
-                       " -subsegs-per-sidx N  sets the number of subsegments to be written in each SIDX box\n"
-                       "                       If 0, a single SIDX box is used per segment\n"
-                       "                       If -1, no SIDX box is used\n"
+                       "                                               using the -frag switch.\n"
+                       "                       Note: for onDemand profile, sets duration of a subsegment\n"
+                       " -frag time_in_ms     Specifies a fragment duration of time_in_ms.\n"
+                       "                       * Note: By default, this is the DASH duration\n"
+                       " -out filename        specifies output file name\n"
+                       "                       * Note: By default input (MP4,3GP) file is overwritten\n"
+                       " -tmp dirname         specifies directory for temporary file creation\n"
+                       "                       * Note: Default temp dir is OS-dependent\n"
+                       " -profile NAME   specifies the target DASH profile: \"onDemand\", \"live\", \"main\", \"simple\", \"full\"\n"
+                       "                       * This will set default option values to ensure conformance to the desired profile\n"
+                       "                       * Default profile is \"full\" in static mode, \"live\" in dynamic mode\n"
+                       "\n"
                        " -rap                 segments begin with random access points\n"
                        "                       Note: segment duration may not be exactly what asked by\n"
-                       "                       \"-dash\" since raw video data is not modified\n"
+                       "                       \"-dash\" since encoded video data is not modified\n"
+                       " -frag-rap            All fragments begin with random access points\n"
+                       "                       Note: fragment duration may not be exactly what is asked by\n"
+                       "                       \"-frag\" since encoded video data is not modified\n"
                        " -segment-name name   sets the segment name for generated segments\n"
                        "                       If not set (default), segments are concatenated in output file\n"
-                       " -segment-ext name    sets the segment extension. Default is m4s\n"
+                       "                        except in \"live\" profile where dash_%%s is used\n"
+                       " -segment-ext name    sets the segment extension. Default is m4s, \"null\" means no extension\n"
+                       " -base-url string     sets Base url at MPD level. Can be used several times.\n"
+                       " -mpd-title string    sets MPD title.\n"
+                       " -mpd-source string   sets MPD source.\n"
+                       " -mpd-info-url string sets MPD info url.\n"
+                       " -cprt string         adds copyright string to MPD\n"
+                       " -dash-live[=F] dur   generates a live DASH session using dur segment duration, optionnally writing live context to F\n" 
+                       "                       MP4Box will run the live session until \'q\' is pressed or a fatal error occurs.\n"
+                       " -dash-ctx FILE       stores/restore DASH timing from FILE.\n"
+                       " -dynamic             uses dynamic MPD type instead of static.\n"
+                       " -mpd-refresh TIME    specifies MPD update time in seconds.\n"
+                       " -time-shift  TIME    specifies MPD time shift buffer depth in seconds (default 0). Specify -1 to keep all files\n"
+                       " -subdur DUR          specifies maximum duration in ms of the input file to be dashed in LIVE or context mode.\n"
+                       "                       NOTE: This does not change the segment duration: dashing stops once segments produced exceeded the duration.\n"
+                       "\n"
+                       "Advanced Options, should not be needed when using -dash-profile:\n"
+                       " -subsegs-per-sidx N  sets the number of subsegments to be written in each SIDX box\n"
+                       "                       If 0, a single SIDX box is used per segment\n"
+                       "                       If -1, no SIDX box is used\n"
                        " -url-template        uses SegmentTemplate instead of explicit sources in segments.\n"
                        "                       Ignored if segments are stored in the output file.\n"
-                       " -daisy-chain         Uses daisy-chain SIDX instead of hierarchical. Ignored if frags/sidx is 0.\n"
-                       " -single-segment      Uses a single segment for the whole file (OnDemand profile). \n"
-                       " -dash-ctx FILE       Stores/restore DASH timing from FILE.\n"
+                       " -daisy-chain         uses daisy-chain SIDX instead of hierarchical. Ignored if frags/sidx is 0.\n"
+                       " -single-segment      uses a single segment for the whole file (OnDemand profile). \n"
+                       " -single-file         uses a single file for the whole file (default). \n"
+                       " -bs-switching MODE   sets bitstream switching to \"yes\" (default), \"no\" or \"single\" to test with single input.\n" 
                        " -dash-ts-prog N      program_number to be considered in case of an MPTS input file.\n"
                        "\n");
 }
 
 void PrintFormats()
 {
-       fprintf(stdout, "Suppported raw formats and file extensions:\n"
+       fprintf(stderr, "Suppported raw formats and file extensions:\n"
                        " NHNT                 .media .nhnt .info\n"
                        " NHML                 .nhml (opt: .media .info)\n"
                        " MPEG-1-2 Video       .m1v .m2v\n"
@@ -313,14 +354,14 @@ void PrintFormats()
                        " VRML                 .wrl .wrl.gz\n"
                        " X3D-XML              .x3d .x3d.gz\n"
                        " X3D-VRML             .x3dv .x3dv.gz\n"
-                       " MacroMedia Flash     .swf (very limitted import support only)\n"
+                       " MacroMedia Flash     .swf (very limited import support only)\n"
                        "\n"
                );
 }
 
 void PrintImportUsage()
 {
-       fprintf(stdout, "Importing Options\n"
+       fprintf(stderr, "Importing Options\n"
                        "\nFile importing syntax:\n"
                        " \"#video\" \"#audio\"  base import for most AV files\n"
                        " \"#trackID=ID\"        track import for IsoMedia and other files\n"
@@ -357,16 +398,27 @@ void PrintImportUsage()
                        " \":stype=4CC\"         forces the sample description type to a different value\n"
                        "                         !! THIS MAY BREAK THE FILE WRITING !!\n"
                        " \":chap\"              specifies the track is a chapter track\n"
+                       " \":chapter=NAME\"      adds a single chapter (old nero format) with given name lasting the entire file\n"
+                       "                         This command can be used in -cat as well\n"
+                       " \":chapfile=file\"     adds a chapter file (old nero format)\n"
+                       "                         This command can be used in -cat as well\n"
                        " \":layout=WxHxXxY\"    specifies the track layout\n"
                        "                         - if W (resp H) = 0, the max width (resp height) of\n"
                        "                         the tracks in the file are used.\n"
                        "                         - if Y=-1, the layout is moved to the bottom of the\n"
                        "                         track area\n"
                        "                         - X and Y can be omitted (:layout=WxH)\n"
+                       " \":rescale=TS\"        forces media timescale to TS !! changes the media duration\n"
+                       " \":timescale=TS\"      sets import timescale to TS\n"
                        "\n"
+                       " \":negctts\"           uses negative CTS-DTS offsets (ISO4 brand)\n"
                        " -add file              add file tracks to (new) output file\n"
                        " -cat file              concatenates file samples to (new) output file\n"
                        "                         * Note: creates tracks if needed\n"
+                       "                         * Note: aligns initial timestamp of the file to be concatenated."
+                       "                         * Note: new tracks can be imported before concatenation by specifying '+ADD_COMMAND'\n"
+                       "                        where ADD_COMMAND is a regular -add syntax\n"
+                       " -unalign-cat           does not attempt to align timestamps of samples inbetween tracks\n"
                        " -force-cat             skips media configuration check when concatenating file\n"
                        "                         !!! THIS MAY BREAK THE CONCATENATED TRACK(S) !!!\n"
                        " -keep-sys              keeps all MPEG-4 Systems info when using '-add' / 'cat'\n"
@@ -399,7 +451,7 @@ void PrintImportUsage()
 
 void PrintEncodeUsage()
 {
-       fprintf(stdout, "MPEG-4 Scene Encoding Options\n"
+       fprintf(stderr, "MPEG-4 Scene Encoding Options\n"
                        " -mp4                 specify input file is for encoding.\n"
                        " -def                 encode DEF names\n"
                        " -sync time_in_ms     forces BIFS sync sample generation every time_in_ms\n"
@@ -427,7 +479,7 @@ void PrintEncodeUsage()
 
 void PrintEncryptUsage()
 {
-       fprintf(stdout, "ISMA Encryption/Decryption Options\n"
+       fprintf(stderr, "ISMA Encryption/Decryption Options\n"
                        " -crypt drm_file      crypts a specific track using ISMA AES CTR 128\n"
                        " -decrypt [drm_file]  decrypts a specific track using ISMA AES CTR 128\n"
                        "                       * Note: drm_file can be omitted if keys are in file\n"
@@ -464,7 +516,7 @@ void PrintEncryptUsage()
 
 void PrintHintUsage()
 {
-       fprintf(stdout, "Hinting Options\n"
+       fprintf(stderr, "Hinting Options\n"
                        " -hint                hints the file for RTP/RTSP\n"
                        " -mtu size            specifies RTP MTU (max size) in bytes. Default size is 1450\n"
                        "                       * Note: this includes the RTP header (12 bytes)\n"
@@ -496,7 +548,7 @@ void PrintHintUsage()
 }
 void PrintExtractUsage()
 {
-       fprintf(stdout, "Extracting Options\n"
+       fprintf(stderr, "Extracting Options\n"
                        " -raw TrackID         extracts track in raw format when supported\n" 
                        " -raws TrackID        extract each track sample to a file\n" 
                        "                       * Note: \"TrackID:N\" extracts Nth sample\n"
@@ -516,8 +568,9 @@ void PrintExtractUsage()
 }
 void PrintDumpUsage()
 {
-       fprintf(stdout, "Dumping Options\n"
-                       " -std                 dumps to stdout instead of file\n"
+       fprintf(stderr, "Dumping Options\n"
+                       " -stdb                dumps/write to stdout and assumes stdout is opened in binary mode\n"
+                       " -std                 dumps/write to stdout and try to reopen stdout in binary mode.\n"
                        " -info [trackID]      prints movie info / track info if trackID specified\n"
                        "                       * Note: for non IsoMedia files, gets import options\n" 
                        " -bt                  scene to bt format - removes unknown MPEG4 nodes\n" 
@@ -529,6 +582,7 @@ void PrintDumpUsage()
                        " -diso                scene IsoMedia file boxes in XML output\n"
                        " -drtp                rtp hint samples structure to XML output\n"
                        " -dts                 prints sample timing to text output\n"
+                       " -dnal trackID        prints NAL sample info of given track\n"
                        " -sdp                 dumps SDP description of hinted file\n"
                        " -dcr                 ISMACryp samples structure to XML output\n"
                        " -dump-cover          Extracts cover art\n"
@@ -553,7 +607,7 @@ void PrintDumpUsage()
 
 void PrintMetaUsage()
 {
-       fprintf(stdout, "Meta handling Options\n"
+       fprintf(stderr, "Meta handling Options\n"
                        " -set-meta args       sets given meta type - syntax: \"ABCD[:tk=ID]\"\n"
                        "                       * ABCD: four char meta type (NULL or 0 to remove meta)\n"
                        "                       * [:tk=ID]: if not set use root (file) meta\n"
@@ -582,7 +636,7 @@ void PrintMetaUsage()
 
 void PrintSWFUsage()
 {
-       fprintf(stdout
+       fprintf(stderr
                        "SWF Importer Options\n"
                        "\n"
                        "MP4Box can import simple Macromedia Flash files (\".SWF\")\n"
@@ -606,9 +660,10 @@ void PrintSWFUsage()
 
 void PrintUsage()
 {
-       fprintf (stdout, "MP4Box [option] input [option]\n"
+       fprintf (stderr, "MP4Box [option] input [option]\n"
                        " -h general           general options help\n"
                        " -h hint              hinting options help\n"
+                       " -h dash              DASH segmenter help\n"
                        " -h import            import options help\n"
                        " -h encode            encode options help\n"
                        " -h meta              meta handling options help\n"
@@ -619,6 +674,7 @@ void PrintUsage()
                        " -h format            supported formats help\n"
                        " -h rtp               file streamer help\n"
                        " -h live              BIFS streamer help\n"
+                       " -h all               all options are printed\n"
                        "\n"
                        " -nodes               lists supported MPEG4 nodes\n"
                        " -node NodeName       gets MPEG4 node syntax and QP info\n"
@@ -633,6 +689,8 @@ void PrintUsage()
                        " -v                   verbose mode\n"
                        " -logs                set log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n"
                        " -version             gets build version\n"
+                       " -- INPUT             escape option if INPUT starts with - character\n"
+                       "\n"
                        );
 }
 
@@ -725,7 +783,7 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32
                /*skip emty tracks (mainly MPEG-4 interaction streams...*/
                if (!gf_isom_get_sample_count(file, i+1)) continue;
                if (!gf_isom_is_track_enabled(file, i+1)) {
-                       fprintf(stdout, "Track ID %d disabled - skipping hint\n", gf_isom_get_track_id(file, i+1) );
+                       fprintf(stderr, "Track ID %d disabled - skipping hint\n", gf_isom_get_track_id(file, i+1) );
                        continue;
                }
 
@@ -793,7 +851,7 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32
 
                if (!hinter) {
                        if (e) {
-                               fprintf(stdout, "Cannot create hinter (%s)\n", gf_error_to_string(e));
+                               fprintf(stderr, "Cannot create hinter (%s)\n", gf_error_to_string(e));
                                if (!nb_done) return e;
                        }
                        continue;
@@ -802,11 +860,11 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32
                tot_bw += bw;
                flags = gf_hinter_track_get_flags(hinter);
                gf_hinter_track_get_payload_name(hinter, szPayload);
-               fprintf(stdout, "Hinting track ID %d - Type \"%s:%s\" (%s) - BW %d kbps\n", gf_isom_get_track_id(file, i+1), gf_4cc_to_str(mtype), gf_4cc_to_str(mtype), szPayload, bw);
-               if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) fprintf(stdout, "\tMPEG-4 Systems stream carousel enabled\n");
+               fprintf(stderr, "Hinting track ID %d - Type \"%s:%s\" (%s) - BW %d kbps\n", gf_isom_get_track_id(file, i+1), gf_4cc_to_str(mtype), gf_4cc_to_str(mtype), szPayload, bw);
+               if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) fprintf(stderr, "\tMPEG-4 Systems stream carousel enabled\n");
 /*
-               if (flags & GP_RTP_PCK_FORCE_MPEG4) fprintf(stdout, "\tMPEG4 transport forced\n");
-               if (flags & GP_RTP_PCK_USE_MULTI) fprintf(stdout, "\tRTP aggregation enabled\n");
+               if (flags & GP_RTP_PCK_FORCE_MPEG4) fprintf(stderr, "\tMPEG4 transport forced\n");
+               if (flags & GP_RTP_PCK_USE_MULTI) fprintf(stderr, "\tRTP aggregation enabled\n");
 */
                e = gf_hinter_track_process(hinter);
 
@@ -814,7 +872,7 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32
                gf_hinter_track_del(hinter);
                
                if (e) {
-                       fprintf(stdout, "Error while hinting (%s)\n", gf_error_to_string(e));
+                       fprintf(stderr, "Error while hinting (%s)\n", gf_error_to_string(e));
                        if (!nb_done) return e;
                }
                init_payt++;
@@ -830,7 +888,7 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32
        gf_hinter_finalize(file, iod_mode, tot_bw);
 
        if (!single_ocr)
-               fprintf(stdout, "Warning: at least 2 timelines found in the file\nThis may not be supported by servers/players\n\n");
+               fprintf(stderr, "Warning: at least 2 timelines found in the file\nThis may not be supported by servers/players\n\n");
 
        return GF_OK;
 }
@@ -1144,7 +1202,7 @@ static Bool parse_tsel_args(TSELAction **__tsel_list, char *opts, u32 *nb_tsel_a
                        }
                }
                else if (!strnicmp(szSlot, "trackID=", 8) || !strchr(szSlot, '=') ) {
-                       __tsel_list = realloc(__tsel_list, sizeof(TSELAction) * (*nb_tsel_act + 1));
+                       __tsel_list = gf_realloc(__tsel_list, sizeof(TSELAction) * (*nb_tsel_act + 1));
                        tsel_list = *__tsel_list;
 
                        tsel_act = &tsel_list[*nb_tsel_act];
@@ -1168,7 +1226,7 @@ static Bool parse_tsel_args(TSELAction **__tsel_list, char *opts, u32 *nb_tsel_a
 }
 
 
-#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stdout, "Missing arg - please check usage\n"); MP4BOX_EXIT_WITH_CODE(1); }
+#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stderr, "Missing arg - please check usage\n"); MP4BOX_EXIT_WITH_CODE(1); }
 
 typedef struct
 {
@@ -1203,15 +1261,50 @@ enum
 };
 
 #define MP4BOX_EXIT_WITH_CODE(__ret_code)      \
-       if (sdp_lines) free(sdp_lines); \
-       if (metas) free(metas); \
-       if (tracks) free(tracks); \
-       if (tsel_acts) free(tsel_acts); \
-       if (brand_add) free(brand_add); \
-       if (brand_rem) free(brand_rem); \
-       if (dash_inputs) free(dash_inputs); \
+       if (mpd_base_urls) gf_free(mpd_base_urls);      \
+       if (sdp_lines) gf_free(sdp_lines); \
+       if (metas) gf_free(metas); \
+       if (tracks) gf_free(tracks); \
+       if (tsel_acts) gf_free(tsel_acts); \
+       if (brand_add) gf_free(brand_add); \
+       if (brand_rem) gf_free(brand_rem); \
+       if (dash_inputs) gf_free(dash_inputs); \
        return __ret_code; \
 
+
+GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char *name, u32 *nb_dash_inputs)
+{
+       GF_DashSegmenterInput *di;
+       char *sep = strchr(name, ':');
+       if (sep && (sep[1]=='\\')) sep = strchr(sep+1, ':');
+
+       dash_inputs = gf_realloc(dash_inputs, sizeof(GF_DashSegmenterInput) * (*nb_dash_inputs + 1) );
+       memset(&dash_inputs[*nb_dash_inputs], 0, sizeof(GF_DashSegmenterInput) );
+       di = &dash_inputs[*nb_dash_inputs];
+       (*nb_dash_inputs)++;
+
+       if (sep) {
+               char *opts = sep+1;
+               sep[0] = 0;
+               while (opts) {
+                       sep = strchr(opts, ':');
+                       if (sep) sep[0] = 0;
+                       if (!strnicmp(opts, "id=", 3)) strncpy(di->representationID, opts+3, 99);
+                       else if (!strnicmp(opts, "period=", 7)) strncpy(di->periodID, opts+7, 99);
+                       else if (!strnicmp(opts, "bandwidth=", 10)) di->bandwidth = atoi(opts+10);
+                       
+                       if (!sep) break;
+                       sep[0] = ':';
+                       opts = sep+1;
+               }
+       }
+       di->file_name = name;
+       if (!strlen(di->representationID)) sprintf(di->representationID, "%d", *nb_dash_inputs);
+
+       return dash_inputs;
+}
+
+
 int mp4boxMain(int argc, char **argv)
 {
        char outfile[5000];
@@ -1220,7 +1313,7 @@ int mp4boxMain(int argc, char **argv)
        GF_SMEncodeOptions opts;
 #endif
        SDPLine *sdp_lines = NULL;
-       Double InterleavingTime, split_duration, split_start, import_fps, dash_duration;
+       Double interleaving_time, split_duration, split_start, import_fps, dash_duration, dash_subduration;
        MetaAction *metas = NULL;
        TrackAction *tracks = NULL;
        TSELAction *tsel_acts = NULL;
@@ -1228,11 +1321,17 @@ int mp4boxMain(int argc, char **argv)
        s32 subsegs_per_sidx;
        u32 *brand_add = NULL;
        u32 *brand_rem = NULL;
-       u32 i, stat_level, hint_flags, info_track_id, import_flags, nb_add, nb_cat, ismaCrypt, agg_samples, nb_sdp_ex, max_ptime, raw_sample_num, split_size, nb_meta_act, nb_track_act, rtp_rate, major_brand, nb_alt_brand_add, nb_alt_brand_rem, old_interleave, car_dur, minor_version, conv_type, nb_tsel_acts, program_number;
+       u32 i, stat_level, hint_flags, info_track_id, import_flags, nb_add, nb_cat, ismaCrypt, agg_samples, nb_sdp_ex, max_ptime, raw_sample_num, split_size, nb_meta_act, nb_track_act, rtp_rate, major_brand, nb_alt_brand_add, nb_alt_brand_rem, old_interleave, car_dur, minor_version, conv_type, nb_tsel_acts, program_number, bitstream_switching_mode, dump_nal, time_shift_depth;
        Bool HintIt, needSave, FullInter, Frag, HintInter, dump_std, dump_rtp, dump_mode, regular_iod, trackID, remove_sys_tracks, remove_hint, force_new, remove_root_od, import_subtitle, dump_chap;
-       Bool print_sdp, print_info, open_edit, track_dump_type, dump_isom, dump_cr, force_ocr, encode, do_log, do_flat, dump_srt, dump_ttxt, dump_ts, do_saf, do_mpd, dump_m2ts, dump_cart, do_hash, verbose, force_cat, pack_wgt, single_group;
-       char *inName, *outName, *arg, *mediaSource, *tmpdir, *input_ctx, *output_ctx, *drm_file, *avi2raw, *cprt, *chap_file, *pes_dump, *itunes_tags, *pack_file, *raw_cat, *seg_name, *dash_ctx;
+       Bool print_sdp, print_info, open_edit, track_dump_type, dump_isom, dump_cr, force_ocr, encode, do_log, do_flat, dump_srt, dump_ttxt, dump_timestamps, do_saf, dump_m2ts, dump_cart, do_hash, verbose, force_cat, align_cat, pack_wgt, single_group, dash_dynamic, dash_live;
+       char *inName, *outName, *arg, *mediaSource, *tmpdir, *input_ctx, *output_ctx, *drm_file, *avi2raw, *cprt, *chap_file, *pes_dump, *itunes_tags, *pack_file, *raw_cat, *seg_name, *dash_ctx_file;
+
+       char **mpd_base_urls = NULL;
+       u32 nb_mpd_base_urls=0;
 
+#ifndef GPAC_DISABLE_MPD
+       Bool do_mpd = 0;
+#endif
 #ifndef GPAC_DISABLE_SCENE_ENCODER
        Bool chunk_mode=0;
 #endif
@@ -1241,19 +1340,26 @@ int mp4boxMain(int argc, char **argv)
        u32 MTUSize = 1450;
 #endif
        GF_ISOFile *file;
+       u32 mpd_update_time = 0;
        Bool stream_rtp=0;
        Bool live_scene=0;
        Bool enable_mem_tracker = 0;
        Bool dump_iod=0;
        Bool daisy_chain_sidx=0;
        Bool single_segment=0;
+       Bool single_file=0;
+       GF_DashProfile dash_profile = GF_DASH_PROFILE_UNKNOWN;
        Bool use_url_template=0;
-       Bool seg_at_rap =0;
+       Bool seg_at_rap=0;
+       Bool frag_at_rap=0;
        Bool adjust_split_end = 0;
-       char **dash_inputs = NULL;
+       GF_DashSegmenterInput *dash_inputs = NULL;
        u32 nb_dash_inputs = 0;
        char *gf_logs = NULL;
        char *seg_ext = NULL;
+       const char *dash_title = NULL;
+       const char *dash_source = NULL;
+       const char *dash_more_info = NULL;
 
        if (argc < 2) {
                PrintUsage();
@@ -1264,21 +1370,26 @@ int mp4boxMain(int argc, char **argv)
        e = GF_OK;
        split_duration = 0.0;
        split_start = -1.0;
-       InterleavingTime = 0.5;
-       dash_duration = 0.0;
+       interleaving_time = 0.0;
+       dash_duration = dash_subduration = 0.0;
        import_fps = 0;
        import_flags = 0;
        split_size = 0;
        movie_time = 0;
-       FullInter = HintInter = encode = do_log = old_interleave = do_saf = do_mpd = do_hash = verbose = 0;
+       dump_nal = 0;
+       FullInter = HintInter = encode = do_log = old_interleave = do_saf = do_hash = verbose = 0;
        dump_mode = Frag = force_ocr = remove_sys_tracks = agg_samples = remove_hint = keep_sys_tracks = remove_root_od = single_group = 0;
-       conv_type = HintIt = needSave = print_sdp = print_info = regular_iod = dump_std = open_edit = dump_isom = dump_rtp = dump_cr = dump_chap = dump_srt = dump_ttxt = force_new = dump_ts = dump_m2ts = dump_cart = import_subtitle = force_cat = pack_wgt = 0;
+       conv_type = HintIt = needSave = print_sdp = print_info = regular_iod = dump_std = open_edit = dump_isom = dump_rtp = dump_cr = dump_chap = dump_srt = dump_ttxt = force_new = dump_timestamps = dump_m2ts = dump_cart = import_subtitle = force_cat = pack_wgt = dash_dynamic = dash_live = 0;
+       bitstream_switching_mode = 1;
+       /*align cat is the new default behaviour for -cat*/
+       align_cat = 1;
        subsegs_per_sidx = 0;
        track_dump_type = 0;
        ismaCrypt = 0;
+       time_shift_depth = 0;
        file = NULL;
        itunes_tags = pes_dump = NULL;
-       seg_name = dash_ctx = NULL;
+       seg_name = dash_ctx_file = NULL;
 
 #ifndef GPAC_DISABLE_SCENE_ENCODER
        memset(&opts, 0, sizeof(opts));
@@ -1295,33 +1406,33 @@ int mp4boxMain(int argc, char **argv)
 #endif
        swf_flatten_angle = 0.0f;
        tmpdir = NULL;
-       
+
        /*parse our args*/
        for (i = 1; i < (u32) argc ; i++) {
                arg = argv[i];
-               /*main file*/
-//             if (isalnum(arg[0]) || (arg[0]=='/') || (arg[0]=='.') || (arg[0]=='\\') ) {
-               if (arg[0] != '-') {
+               /*input file(s)*/
+               if ((arg[0] != '-') || !stricmp(arg, "--")) {
+                       char *arg_val = arg;
+                       if (!stricmp(arg, "--")) {
+                               CHECK_NEXT_ARG
+                               arg_val = argv[i+1];
+                               i++;
+                       }
                        if (argc < 3) {
-                               fprintf(stdout, "Error - only one input file found as argument, please check usage\n"); 
+                               fprintf(stderr, "Error - only one input file found as argument, please check usage\n"); 
                                MP4BOX_EXIT_WITH_CODE(1); 
                        } else if (inName) { 
                                if (dash_duration) {
                                        if (!nb_dash_inputs) {
-                                               dash_inputs = realloc(dash_inputs, sizeof(char *) * (nb_dash_inputs+1) );
-                                               dash_inputs[nb_dash_inputs] = inName;
-                                               nb_dash_inputs++;
+                                               dash_inputs = set_dash_input(dash_inputs, inName, &nb_dash_inputs);
                                        }
-                                       dash_inputs = realloc(dash_inputs, sizeof(char *) * (nb_dash_inputs+1) );
-
-                                       dash_inputs[nb_dash_inputs] = arg;
-                                       nb_dash_inputs++;                                       
+                                       dash_inputs = set_dash_input(dash_inputs, arg_val, &nb_dash_inputs);
                                } else {
-                                       fprintf(stdout, "Error - 2 input names specified, please check usage\n");
+                                       fprintf(stderr, "Error - 2 input names specified, please check usage\n");
                                        MP4BOX_EXIT_WITH_CODE(1); 
                                }
                        } else {
-                               inName = arg;
+                               inName = arg_val;
                        }
                }
                else if (!stricmp(arg, "-?")) { PrintUsage(); MP4BOX_EXIT_WITH_CODE(0); }
@@ -1370,7 +1481,7 @@ int mp4boxMain(int argc, char **argv)
                                if (strlen(argv[i+1])==5) trackID = 2;
                                else trackID = 1 + atoi(argv[i+1] + 5);
                        }
-                       else { fprintf(stdout, "Usage: \"-aviraw video\" or \"-aviraw audio\"\n"); MP4BOX_EXIT_WITH_CODE(1); }
+                       else { fprintf(stderr, "Usage: \"-aviraw video\" or \"-aviraw audio\"\n"); MP4BOX_EXIT_WITH_CODE(1); }
                        track_dump_type = GF_EXPORT_AVI_NATIVE;
                        i++;
                }
@@ -1428,8 +1539,9 @@ int mp4boxMain(int argc, char **argv)
 #ifndef GPAC_DISABLE_SVG
                else if (!stricmp(arg, "-snode")) { CHECK_NEXT_ARG PrintNode(argv[i+1], 2); MP4BOX_EXIT_WITH_CODE(0); }
                else if (!stricmp(arg, "-snodes")) { PrintBuiltInNodes(2); MP4BOX_EXIT_WITH_CODE(0); } 
-               else if (!stricmp(arg, "-std")) dump_std = 1;
 #endif
+               else if (!stricmp(arg, "-std")) dump_std = 2;
+               else if (!stricmp(arg, "-stdb")) dump_std = 1;
 
 #if !defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_SCENE_DUMP)
                else if (!stricmp(arg, "-bt")) dump_mode = 1 + GF_SM_DUMP_BT;
@@ -1451,16 +1563,21 @@ int mp4boxMain(int argc, char **argv)
 
                else if (!stricmp(arg, "-dmp4")) {
                        dump_isom = 1;
-                       fprintf(stdout, "WARNING: \"-dmp4\" is deprecated - use \"-diso\" option\n");
+                       fprintf(stderr, "WARNING: \"-dmp4\" is deprecated - use \"-diso\" option\n");
                }
                else if (!stricmp(arg, "-drtp")) dump_rtp = 1;
                else if (!stricmp(arg, "-dts")) {
-                       dump_ts = 1;
+                       dump_timestamps = 1;
                        if ( ((i+1<(u32) argc) && inName) || (i+2<(u32) argc) ) {
                                if (argv[i+1][0] != '-') program_number = atoi(argv[i+1]);
                                i++;
                        }
-               } else if (!stricmp(arg, "-dcr")) dump_cr = 1;
+               } else if (!stricmp(arg, "-dnal")) {
+                       CHECK_NEXT_ARG
+                               dump_nal = atoi(argv[i+1]);
+                       i++;
+               }
+               else if (!stricmp(arg, "-dcr")) dump_cr = 1;
                else if (!stricmp(arg, "-ttxt") || !stricmp(arg, "-srt")) {
                        if ((i+1<(u32) argc) && (sscanf(argv[i+1], "%u", &trackID)==1)) {
                                char szTk[20];
@@ -1471,7 +1588,7 @@ int mp4boxMain(int argc, char **argv)
                                trackID = 0;
                        }
 #ifdef GPAC_DISABLE_ISOM_WRITE
-                       if (trackID) { fprintf(stdout, "Error: Read-Only version - subtitle conversion not available\n"); MP4BOX_EXIT_WITH_CODE(1); }
+                       if (trackID) { fprintf(stderr, "Error: Read-Only version - subtitle conversion not available\n"); MP4BOX_EXIT_WITH_CODE(1); }
 #endif
                        if (!stricmp(arg, "-ttxt")) dump_ttxt = 1;
                        else dump_srt = 1;
@@ -1514,33 +1631,41 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-tmp")) {
                        CHECK_NEXT_ARG tmpdir = argv[i+1]; i++; 
                }
-               else if (!stricmp(arg, "-cprt")) { CHECK_NEXT_ARG cprt = argv[i+1]; i++; open_edit = 1; }
+               else if (!stricmp(arg, "-write-buffer")) {
+                       CHECK_NEXT_ARG 
+                       gf_isom_set_output_buffering(NULL, atoi(argv[i+1]));
+                       i++; 
+               }
+               else if (!stricmp(arg, "-cprt")) { CHECK_NEXT_ARG cprt = argv[i+1]; i++; if (!dash_duration) open_edit = 1; }
                else if (!stricmp(arg, "-chap")) { CHECK_NEXT_ARG chap_file = argv[i+1]; i++; open_edit = 1; }
                else if (!strcmp(arg, "-mem-track")) {
 #ifdef GPAC_MEMORY_TRACKING
                        enable_mem_tracker = 1;
 #else
-                       fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
+                       fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
 #endif
                } else if (!strcmp(arg, "-strict-error")) {
                        gf_log_set_strict_error(1);
                } else if (!stricmp(arg, "-inter") || !stricmp(arg, "-old-inter")) {
                        CHECK_NEXT_ARG
-                       InterleavingTime = atof(argv[i+1]) / 1000;
+                       interleaving_time = atof(argv[i+1]) / 1000;
                        open_edit = 1;
                        needSave = 1;
                        if (!stricmp(arg, "-old-inter")) old_interleave = 1;
                        i++;
                } else if (!stricmp(arg, "-frag")) {
                        CHECK_NEXT_ARG
-                       InterleavingTime = atof(argv[i+1]) / 1000;
+                       interleaving_time = atof(argv[i+1]) / 1000;
                        needSave = 1;
                        i++;
                        Frag = 1;
                } else if (!stricmp(arg, "-dash")) {
                        CHECK_NEXT_ARG
                        dash_duration = atof(argv[i+1]) /        1000;
-                       needSave = 1;
+                       i++;
+               } else if (!stricmp(arg, "-subdur")) {
+                       CHECK_NEXT_ARG
+                       dash_subduration = atof(argv[i+1]) /     1000;
                        i++;
                } else if (!stricmp(arg, "-dash-ts-prog")) {
                        CHECK_NEXT_ARG
@@ -1558,14 +1683,59 @@ int mp4boxMain(int argc, char **argv)
                        CHECK_NEXT_ARG
                        seg_ext = argv[i+1];
                        i++;
-               } else if (!stricmp(arg, "-dash-ctx")) {
+               } else if (!stricmp(arg, "-bs-switching")) {
+                       CHECK_NEXT_ARG
+                       if (!stricmp(argv[i+1], "no") || !stricmp(argv[i+1], "off")) bitstream_switching_mode = 0;
+                       else if (!stricmp(argv[i+1], "single"))  bitstream_switching_mode = 2;
+                       else bitstream_switching_mode = 1;
+                       i++;
+               }
+               else if (!stricmp(arg, "-dynamic")) { dash_dynamic = 1; }
+               else if (!strnicmp(arg, "-dash-live", 10)) {
+                       dash_dynamic = 1;
+                       dash_live = 1;
+                       if (arg[10]=='=') {
+                               dash_ctx_file = arg+11;
+                       }
+                       CHECK_NEXT_ARG
+                       dash_duration = atof(argv[i+1]) / 1000;
+                       i++;
+               }
+               else if (!stricmp(arg, "-mpd-refresh")) { CHECK_NEXT_ARG mpd_update_time = atoi(argv[i+1]); i++;   }
+               else if (!stricmp(arg, "-time-shift")) { 
+                       CHECK_NEXT_ARG 
+                       time_shift_depth = (u32) atoi(argv[i+1]);
+                       i++;
+               }
+               else if (!stricmp(arg, "-mpd-title")) { CHECK_NEXT_ARG dash_title = argv[i+1]; i++; }
+               else if (!stricmp(arg, "-mpd-source")) { CHECK_NEXT_ARG dash_source = argv[i+1]; i++; }
+               else if (!stricmp(arg, "-mpd-info-url")) { CHECK_NEXT_ARG dash_more_info = argv[i+1]; i++; }
+               else if (!stricmp(arg, "-base-url")) { 
+                       CHECK_NEXT_ARG 
+                       dash_more_info = argv[i+1]; 
+                       mpd_base_urls = gf_realloc(mpd_base_urls, (nb_mpd_base_urls+1)*sizeof(char**));
+                       mpd_base_urls[nb_mpd_base_urls] = argv[i+1];
+                       nb_mpd_base_urls++;
+                       i++; 
+               }
+               
+               else if (!stricmp(arg, "-dash-ctx")) {
                        CHECK_NEXT_ARG
-                       dash_ctx = argv[i+1];
+                       dash_ctx_file = argv[i+1];
                        i++;
                } else if (!stricmp(arg, "-daisy-chain")) {
                        daisy_chain_sidx = 1;
                } else if (!stricmp(arg, "-single-segment")) {
                        single_segment = 1;
+               } else if (!stricmp(arg, "-single-file")) {
+                       single_file = 1;
+               } else if (!stricmp(arg, "-dash-profile") || !stricmp(arg, "-profile")) {
+                       CHECK_NEXT_ARG
+                       if (!stricmp(argv[i+1], "live") || !stricmp(argv[i+1], "simple")) dash_profile = GF_DASH_PROFILE_LIVE;
+                       else if (!stricmp(argv[i+1], "onDemand")) dash_profile = GF_DASH_PROFILE_ONDEMAND;
+                       else if (!stricmp(argv[i+1], "main")) dash_profile = GF_DASH_PROFILE_MAIN;
+                       else dash_profile = GF_DASH_PROFILE_FULL;
+                       i++;
                } else if (!strnicmp(arg, "-url-template", 13)) {
                        use_url_template = 1;
                        if ((arg[13]=='=') && arg[14]) {
@@ -1587,6 +1757,9 @@ int mp4boxMain(int argc, char **argv)
                        hint_flags |= GP_RTP_PCK_SIGNAL_RAP;
                        seg_at_rap=1;
                }
+               else if (!stricmp(arg, "-frag-rap")) {
+                       frag_at_rap=1;
+               }
                else if (!stricmp(arg, "-ts")) hint_flags |= GP_RTP_PCK_SIGNAL_TS;
                else if (!stricmp(arg, "-size")) hint_flags |= GP_RTP_PCK_SIGNAL_SIZE;
                else if (!stricmp(arg, "-idx")) hint_flags |= GP_RTP_PCK_SIGNAL_AU_IDX;
@@ -1617,7 +1790,7 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-add-sdp") || !stricmp(arg, "-sdp_ex")) {
                        char *id;
                        CHECK_NEXT_ARG
-                       sdp_lines = realloc(sdp_lines, sizeof(SDPLine) * (nb_sdp_ex+1) );
+                       sdp_lines = gf_realloc(sdp_lines, sizeof(SDPLine) * (nb_sdp_ex+1) );
 
                        id = strchr(argv[i+1], ':');
                        if (id) {
@@ -1654,8 +1827,8 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-new")) force_new = 1;
                else if (!stricmp(arg, "-add") || !stricmp(arg, "-import") || !stricmp(arg, "-convert")) {
                        CHECK_NEXT_ARG
-                       if (!stricmp(arg, "-import")) fprintf(stdout, "\tWARNING: \"-import\" is deprecated - use \"-add\"\n");
-                       else if (!stricmp(arg, "-convert")) fprintf(stdout, "\tWARNING: \"-convert\" is deprecated - use \"-add\"\n");
+                       if (!stricmp(arg, "-import")) fprintf(stderr, "\tWARNING: \"-import\" is deprecated - use \"-add\"\n");
+                       else if (!stricmp(arg, "-convert")) fprintf(stderr, "\tWARNING: \"-convert\" is deprecated - use \"-add\"\n");
                        nb_add++;
                        i++;
                }
@@ -1678,6 +1851,8 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-force-cat")) force_cat = 1;
+               else if (!stricmp(arg, "-align-cat")) align_cat = 1;
+               else if (!stricmp(arg, "-unalign-cat")) align_cat = 0;
                else if (!stricmp(arg, "-raw-cat")) {
                        CHECK_NEXT_ARG
                        raw_cat = argv[i+1];
@@ -1685,7 +1860,7 @@ int mp4boxMain(int argc, char **argv)
                }
                else if (!stricmp(arg, "-rem") || !stricmp(arg, "-disable") || !stricmp(arg, "-enable")) {
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        if (!stricmp(arg, "-enable")) tracks[nb_track_act].act_type = 6;
                        else if (!stricmp(arg, "-disable")) tracks[nb_track_act].act_type = 7;
@@ -1698,13 +1873,13 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-par")) {
                        char szTK[20], *ext;
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        tracks[nb_track_act].act_type = 4;
                        strcpy(szTK, argv[i+1]);
                        ext = strchr(szTK, '=');
                        if (!ext) {
-                               fprintf(stdout, "Bad format for track par - expecting ID=PAR_NUM:PAR_DEN got %s\n", argv[i+1]);
+                               fprintf(stderr, "Bad format for track par - expecting ID=PAR_NUM:PAR_DEN got %s\n", argv[i+1]);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                        if (!stricmp(ext+1, "none")) {
@@ -1721,7 +1896,7 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-lang")) {
                        char szTK[20], *ext;
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        tracks[nb_track_act].act_type = 1;
                        tracks[nb_track_act].lang[3] = 0;
@@ -1745,12 +1920,12 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-delay")) {
                        char szTK[20], *ext;
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        strcpy(szTK, argv[i+1]);
                        ext = strchr(szTK, '=');
                        if (!ext) {
-                               fprintf(stdout, "Bad format for track delay - expecting ID=DLAY got %s\n", argv[i+1]);
+                               fprintf(stderr, "Bad format for track delay - expecting ID=DLAY got %s\n", argv[i+1]);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                        tracks[nb_track_act].act_type = 2;
@@ -1764,19 +1939,19 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-ref")) {
                        char *szTK, *ext;
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        szTK = argv[i+1];
                        ext = strchr(szTK, ':');
                        if (!ext) {
-                               fprintf(stdout, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i+1]);
+                               fprintf(stderr, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i+1]);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                        tracks[nb_track_act].act_type = 8;
                        ext[0] = 0; tracks[nb_track_act].trackID = atoi(szTK); ext[0] = ':'; szTK = ext+1;
                        ext = strchr(szTK, ':');
                        if (!ext) {
-                               fprintf(stdout, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i+1]);
+                               fprintf(stderr, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i+1]);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                        ext[0] = 0;
@@ -1790,12 +1965,12 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-name")) {
                        char szTK[GF_MAX_PATH], *ext;
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        strcpy(szTK, argv[i+1]);
                        ext = strchr(szTK, '=');
                        if (!ext) {
-                               fprintf(stdout, "Bad format for track name - expecting ID=name got %s\n", argv[i+1]);
+                               fprintf(stderr, "Bad format for track name - expecting ID=name got %s\n", argv[i+1]);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                        tracks[nb_track_act].act_type = 5;
@@ -1836,12 +2011,14 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-mp4")) { encode = 1; open_edit = 1; }
                else if (!stricmp(arg, "-saf")) { do_saf = 1; }
                else if (!stricmp(arg, "-log")) { do_log = 1; }
+#ifndef GPAC_DISABLE_MPD
                else if (!stricmp(arg, "-mpd")) { 
                        do_mpd = 1; 
                        CHECK_NEXT_ARG 
                        outName = argv[i+1]; 
                        i++; 
                }
+#endif
                
 #ifndef GPAC_DISABLE_SCENE_ENCODER
                else if (!stricmp(arg, "-def")) opts.flags |= GF_SM_ENCODE_USE_NAMES;
@@ -1920,7 +2097,7 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-set-kms")) {
                        char szTK[20], *ext;
                        CHECK_NEXT_ARG
-                       tracks = realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
+                       tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
 
                        strncpy(szTK, argv[i+1], 19);
                        ext = strchr(szTK, '=');
@@ -1962,18 +2139,23 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-split-chunk") || !stricmp(arg, "-splitx") || !stricmp(arg, "-splitz")) { 
                        CHECK_NEXT_ARG 
                        if (!strstr(argv[i+1], ":")) {
-                               fprintf(stdout, "Chunk extraction usage: \"-splitx start:end\" expressed in seconds\n");
+                               fprintf(stderr, "Chunk extraction usage: \"-splitx start:end\" expressed in seconds\n");
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
-                       sscanf(argv[i+1], "%lf:%lf", &split_start, &split_duration);
-                       split_duration -= split_start; 
+                       if (strstr(argv[i+1], "end")) {
+                               sscanf(argv[i+1], "%lf:end", &split_start);
+                               split_duration = -2; 
+                       } else {
+                               sscanf(argv[i+1], "%lf:%lf", &split_start, &split_duration);
+                               split_duration -= split_start; 
+                       }
                        split_size = 0;
                        if (!stricmp(arg, "-splitz")) adjust_split_end = 1;
                        i++;
                }
                /*meta*/
                else if (!stricmp(arg, "-set-meta")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 0;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -1982,7 +2164,7 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-add-item")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 1;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -1991,7 +2173,7 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-rem-item")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 2;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -2000,7 +2182,7 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-set-primary")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 3;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -2009,7 +2191,7 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-set-xml")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 4;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -2018,7 +2200,7 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-rem-xml")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 6;
                        if (parse_meta_args(&metas[nb_meta_act], argv[i+1])) i++;
@@ -2026,7 +2208,7 @@ int mp4boxMain(int argc, char **argv)
                        open_edit = 1;
                }
                else if (!stricmp(arg, "-dump-xml")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 7;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -2034,7 +2216,7 @@ int mp4boxMain(int argc, char **argv)
                        i++;
                }
                else if (!stricmp(arg, "-dump-item")) { 
-                       metas = realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
+                       metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
 
                        metas[nb_meta_act].act_type = 8;
                        parse_meta_args(&metas[nb_meta_act], argv[i+1]);
@@ -2044,7 +2226,7 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-group-add") || !stricmp(arg, "-group-rem-track") || !stricmp(arg, "-group-rem")) { 
                        tsel_acts[nb_tsel_acts].act_type = !stricmp(arg, "-group-rem") ? 2 : ( !stricmp(arg, "-group-rem-track") ? 1 : 0 );
                        if (parse_tsel_args(&tsel_acts, argv[i+1], &nb_tsel_acts)==0) {
-                               fprintf(stdout, "Invalid group syntax - check usage\n");
+                               fprintf(stderr, "Invalid group syntax - check usage\n");
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                        open_edit=1;
@@ -2081,7 +2263,7 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-ab")) { 
                        char *b = argv[i+1];
                        CHECK_NEXT_ARG 
-                       brand_add = realloc(brand_add, sizeof(u32) * (nb_alt_brand_add+1));
+                       brand_add = gf_realloc(brand_add, sizeof(u32) * (nb_alt_brand_add+1));
 
                        brand_add[nb_alt_brand_add] = GF_4CC(b[0], b[1], b[2], b[3]);
                        nb_alt_brand_add++;
@@ -2091,7 +2273,7 @@ int mp4boxMain(int argc, char **argv)
                else if (!stricmp(arg, "-rb")) { 
                        char *b = argv[i+1];
                        CHECK_NEXT_ARG 
-                       brand_rem = realloc(brand_rem, sizeof(u32) * (nb_alt_brand_rem+1));
+                       brand_rem = gf_realloc(brand_rem, sizeof(u32) * (nb_alt_brand_rem+1));
 
                        brand_rem[nb_alt_brand_rem] = GF_4CC(b[0], b[1], b[2], b[3]);
                        nb_alt_brand_rem++;
@@ -2107,6 +2289,7 @@ int mp4boxMain(int argc, char **argv)
                        if (i+1== (u32) argc) PrintUsage();
                        else if (!strcmp(argv[i+1], "general")) PrintGeneralUsage();
                        else if (!strcmp(argv[i+1], "extract")) PrintExtractUsage();
+                       else if (!strcmp(argv[i+1], "dash")) PrintDASHUsage();
                        else if (!strcmp(argv[i+1], "dump")) PrintDumpUsage();
                        else if (!strcmp(argv[i+1], "import")) PrintImportUsage();
                        else if (!strcmp(argv[i+1], "format")) PrintFormats();
@@ -2122,6 +2305,7 @@ int mp4boxMain(int argc, char **argv)
                        else if (!strcmp(argv[i+1], "all")) {
                                PrintGeneralUsage();
                                PrintExtractUsage();
+                               PrintDASHUsage();
                                PrintDumpUsage();
                                PrintImportUsage();
                                PrintFormats();
@@ -2140,20 +2324,52 @@ int mp4boxMain(int argc, char **argv)
                }
                else if (!stricmp(arg, "-v")) verbose++;
                else if (!stricmp(arg, "-tag-list")) {
-                       fprintf(stdout, "Supported iTunes tag modifiers:\n");
+                       fprintf(stderr, "Supported iTunes tag modifiers:\n");
                        for (i=0; i<nb_itunes_tags; i++) {
-                               fprintf(stdout, "\t%s\t%s\n", itags[i].name, itags[i].comment);
+                               fprintf(stderr, "\t%s\t%s\n", itags[i].name, itags[i].comment);
                        }
                        MP4BOX_EXIT_WITH_CODE(0);
                } else if (!live_scene && !stream_rtp) {
-                       fprintf(stdout, "Option %s unknown. Please check usage\n", arg);
+                       fprintf(stderr, "Option %s unknown. Please check usage\n", arg);
                        MP4BOX_EXIT_WITH_CODE(1);
                }
        }
+
+       if (!inName && dump_std) 
+               inName = "std";
+
        if (!inName) {
                PrintUsage();
                MP4BOX_EXIT_WITH_CODE(1);
        }
+       if (!strcmp(inName, "std")) dump_std = 2;
+       if (!strcmp(inName, "stdb")) {
+               inName = "std";
+               dump_std = 1;
+       }
+
+       if (!interleaving_time) {
+               /*by default use single fragment per dash segment*/
+               if (dash_duration) 
+                       interleaving_time = dash_duration;
+               else
+                       interleaving_time = 0.5;
+       }
+
+       if (dump_std) 
+               outName = "std";
+
+       if (dump_std==2) {
+#ifdef WIN32
+               if ( _setmode(_fileno(stdout), _O_BINARY) == -1 ) 
+#else
+               if ( freopen(NULL, "wb", stdout) == NULL) 
+#endif
+               {
+                       fprintf(stderr, "Fatal error: cannot reopen stdout in binary mode.\n");
+                       MP4BOX_EXIT_WITH_CODE(1);
+               }
+       }
 
 #if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
        if (live_scene) {
@@ -2185,7 +2401,7 @@ int mp4boxMain(int argc, char **argv)
                        u32 nb_bytes = fread(chunk, 1, 4096, fin);
                        gf_fwrite(chunk, 1, nb_bytes, fout);
                        done += nb_bytes;
-                       fprintf(stdout, "Appending file %s - %02.2f done\r", raw_cat, 100.0*done/to_copy);
+                       fprintf(stderr, "Appending file %s - %02.2f done\r", raw_cat, 100.0*done/to_copy);
                        if (done >= to_copy) break;
                }
                fclose(fin);
@@ -2216,13 +2432,14 @@ int mp4boxMain(int argc, char **argv)
                }
        }
 
+#ifndef GPAC_DISABLE_MPD
        if (do_mpd) {
                Bool remote = 0;
                char *mpd_base_url = gf_strdup(inName);
                if (!strnicmp(inName, "http://", 7)) {
-                       e = gf_dm_wget(inName, "tmp_main.m3u8");
+                       e = gf_dm_wget(inName, "tmp_main.m3u8", 0, 0);
                        if (e != GF_OK) {
-                               fprintf(stdout, "Cannot retrieve M3U8 (%s): %s\n", inName, gf_error_to_string(e));
+                               fprintf(stderr, "Cannot retrieve M3U8 (%s): %s\n", inName, gf_error_to_string(e));
                                gf_free(mpd_base_url);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
@@ -2235,18 +2452,16 @@ int mp4boxMain(int argc, char **argv)
                        //gf_delete_file("tmp_main.m3u8");
                }
                if (e != GF_OK) {
-                       fprintf(stdout, "Error converting M3U8 (%s) to MPD (%s): %s\n", inName, outName, gf_error_to_string(e));
+                       fprintf(stderr, "Error converting M3U8 (%s) to MPD (%s): %s\n", inName, outName, gf_error_to_string(e));
                        MP4BOX_EXIT_WITH_CODE(1);
                } else {
-                       fprintf(stdout, "Done converting M3U8 (%s) to MPD (%s)\n", inName, outName);
+                       fprintf(stderr, "Done converting M3U8 (%s) to MPD (%s)\n", inName, outName);
                        MP4BOX_EXIT_WITH_CODE(0);
                }
        }
-
+#endif
        if (dash_duration && !nb_dash_inputs) {
-               dash_inputs = realloc(dash_inputs, sizeof(char *) * (nb_dash_inputs+1) );
-               dash_inputs[nb_dash_inputs] = inName;
-               nb_dash_inputs++;
+               dash_inputs = set_dash_input(dash_inputs, inName, &nb_dash_inputs);
        }
 
 
@@ -2274,7 +2489,7 @@ int mp4boxMain(int argc, char **argv)
                import.in_name = inName;
                e = gf_media_import(&import);
                if (e) {
-                       fprintf(stdout, "Error importing %s: %s\n", inName, gf_error_to_string(e));
+                       fprintf(stderr, "Error importing %s: %s\n", inName, gf_error_to_string(e));
                        gf_isom_delete(file);
                        gf_delete_file("ttxt_convert");
                        MP4BOX_EXIT_WITH_CODE(1);
@@ -2290,12 +2505,12 @@ int mp4boxMain(int argc, char **argv)
                gf_isom_delete(file);
                gf_delete_file("ttxt_convert");
                if (e) {
-                       fprintf(stdout, "Error converting %s: %s\n", inName, gf_error_to_string(e));
+                       fprintf(stderr, "Error converting %s: %s\n", inName, gf_error_to_string(e));
                        MP4BOX_EXIT_WITH_CODE(1);
                }
                MP4BOX_EXIT_WITH_CODE(0);
 #else
-               fprintf(stdout, "Feature not supported\n");
+               fprintf(stderr, "Feature not supported\n");
                MP4BOX_EXIT_WITH_CODE(1);
 #endif
        }
@@ -2322,14 +2537,14 @@ int mp4boxMain(int argc, char **argv)
                open_edit = 1;
                file = gf_isom_open(inName, open_mode, tmpdir);
                if (!file) {
-                       fprintf(stdout, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) );
+                       fprintf(stderr, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) );
                        MP4BOX_EXIT_WITH_CODE(1);
                }
                for (i=0; i<(u32) argc; i++) {
                        if (!strcmp(argv[i], "-add")) {
                                e = import_file(file, argv[i+1], import_flags, import_fps, agg_samples);
                                if (e) {
-                                       fprintf(stdout, "Error importing %s: %s\n", argv[i+1], gf_error_to_string(e));
+                                       fprintf(stderr, "Error importing %s: %s\n", argv[i+1], gf_error_to_string(e));
                                        gf_isom_delete(file);
                                        MP4BOX_EXIT_WITH_CODE(1);
                                }
@@ -2361,15 +2576,15 @@ int mp4boxMain(int argc, char **argv)
                        open_edit = 1;
                        file = gf_isom_open(inName, open_mode, tmpdir);
                        if (!file) {
-                               fprintf(stdout, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) );
+                               fprintf(stderr, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) );
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                }
                for (i=0; i<(u32)argc; i++) {
                        if (!strcmp(argv[i], "-cat")) {
-                               e = cat_isomedia_file(file, argv[i+1], import_flags, import_fps, agg_samples, tmpdir, force_cat);
+                               e = cat_isomedia_file(file, argv[i+1], import_flags, import_fps, agg_samples, tmpdir, force_cat, align_cat);
                                if (e) {
-                                       fprintf(stdout, "Error appending %s: %s\n", argv[i+1], gf_error_to_string(e));
+                                       fprintf(stderr, "Error appending %s: %s\n", argv[i+1], gf_error_to_string(e));
                                        gf_isom_delete(file);
                                        MP4BOX_EXIT_WITH_CODE(1);
                                }
@@ -2387,11 +2602,11 @@ int mp4boxMain(int argc, char **argv)
 #if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
        else if (chunk_mode) {
                if (!inName) {
-                       fprintf(stdout, "chunk encoding syntax: [-outctx outDump] -inctx inScene auFile\n");
+                       fprintf(stderr, "chunk encoding syntax: [-outctx outDump] -inctx inScene auFile\n");
                        MP4BOX_EXIT_WITH_CODE(1);
                }
                e = EncodeFileChunk(inName, outName ? outName : inName, input_ctx, output_ctx, tmpdir);
-               if (e) fprintf(stdout, "Error encoding chunk file %s\n", gf_error_to_string(e));
+               if (e) fprintf(stderr, "Error encoding chunk file %s\n", gf_error_to_string(e));
                MP4BOX_EXIT_WITH_CODE( e ? 1 : 0 );
        }
 #endif
@@ -2443,6 +2658,67 @@ int mp4boxMain(int argc, char **argv)
        } 
 #endif
 
+
+       if (dash_duration) {
+               char szMPD[GF_MAX_PATH], *sep;
+               GF_Config *dash_ctx = NULL;
+               gf_log_set_tool_level(GF_LOG_DASH, GF_LOG_INFO);
+               strcpy(outfile, outName ? outName : gf_url_get_resource_name(inName) );
+               sep = strrchr(outfile, '.');
+               if (sep) sep[0] = 0;
+               if (!outName) strcat(outfile, "_dash");
+               strcpy(szMPD, outfile);
+               strcat(szMPD, ".mpd");
+
+               if (!dash_ctx_file && dash_live) {
+                       dash_ctx = gf_cfg_new(NULL, NULL);
+               } else if (dash_ctx_file) {
+                       if (force_new) 
+                               gf_delete_file(dash_ctx_file);
+
+                       dash_ctx = gf_cfg_force_new(NULL, dash_ctx_file);
+               }
+
+               if (dash_profile==GF_DASH_PROFILE_UNKNOWN)
+                       dash_profile = dash_dynamic ? GF_DASH_PROFILE_LIVE : GF_DASH_PROFILE_FULL;
+
+               if (!dash_dynamic) {
+                       time_shift_depth = 0;
+                       mpd_update_time = 0;
+               } else if ((dash_profile>=GF_DASH_PROFILE_MAIN) && !use_url_template && !mpd_update_time) {
+                       /*use a default MPD update of dash_duration sec*/
+                       mpd_update_time = (u32)  (dash_subduration ? dash_subduration : dash_duration);
+                       fprintf(stderr, "Using default MPD refresh of %d seconds\n", mpd_update_time);
+               }
+
+               while (1) {
+                       e = gf_dasher_segment_files(szMPD, dash_inputs, nb_dash_inputs, dash_profile, dash_title, dash_source, cprt, dash_more_info,
+                                                                               (const char **) mpd_base_urls, nb_mpd_base_urls, 
+                                                                          use_url_template, single_segment, single_file, bitstream_switching_mode, 
+                                                                          seg_at_rap, dash_duration, seg_name, seg_ext,
+                                                                          interleaving_time, subsegs_per_sidx, daisy_chain_sidx, frag_at_rap, tmpdir,
+                                                                          dash_ctx, dash_dynamic, mpd_update_time, time_shift_depth, dash_subduration);
+                       if (e) break;
+
+                       if (dash_live) {
+                               u32 sleep_for = gf_dasher_next_update_time(dash_ctx, mpd_update_time);
+                               if (gf_prompt_has_input()) {
+                                       char c = (char) gf_prompt_get_char(); 
+                                       if (c=='q') break;
+                               }
+                               fprintf(stderr, "sleep for %d ms\n", sleep_for);
+                               gf_sleep(sleep_for);
+                       } else {
+                               break;
+                       }
+               }
+
+               if (dash_ctx) gf_cfg_del(dash_ctx);
+
+               gf_sys_close();
+               MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
+       }
+
        else if (!file
 #ifndef GPAC_DISABLE_MEDIA_EXPORT
                && !(track_dump_type & GF_EXPORT_AVI_NATIVE)
@@ -2456,11 +2732,11 @@ int mp4boxMain(int argc, char **argv)
                }
                switch (get_file_type_by_ext(inName)) {
                case 1:
-                       file = gf_isom_open(inName, (u8) (open_edit ? GF_ISOM_OPEN_EDIT : ( (dump_isom>0) ? GF_ISOM_OPEN_READ_DUMP : GF_ISOM_OPEN_READ) ), tmpdir);
+                       file = gf_isom_open(inName, (u8) (open_edit ? GF_ISOM_OPEN_EDIT : ( ((dump_isom>0) || print_info) ? GF_ISOM_OPEN_READ_DUMP : GF_ISOM_OPEN_READ) ), tmpdir);
                        if (!file && (gf_isom_last_error(NULL) == GF_ISOM_INCOMPLETE_FILE) && !open_edit) {
                                u64 missing_bytes;
                                e = gf_isom_open_progressive(inName, 0, 0, &file, &missing_bytes);
-                               fprintf(stdout, "Truncated file - missing "LLD" bytes\n", missing_bytes);
+                               fprintf(stderr, "Truncated file - missing "LLD" bytes\n", missing_bytes);
                        }
 
                        if (!file) {
@@ -2470,7 +2746,7 @@ int mp4boxMain(int argc, char **argv)
                                }
 
                                if (!file) {
-                                       fprintf(stdout, "Error opening file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)));
+                                       fprintf(stderr, "Error opening file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)));
                                        MP4BOX_EXIT_WITH_CODE(1);
                                }
                        }
@@ -2508,7 +2784,7 @@ int mp4boxMain(int argc, char **argv)
                                        import.flags = GF_IMPORT_MPE_DEMUX;
                                        e = gf_media_import(&import);
                                        if (e) {
-                                               fprintf(stdout, "Error importing %s: %s\n", inName, gf_error_to_string(e));
+                                               fprintf(stderr, "Error importing %s: %s\n", inName, gf_error_to_string(e));
                                                gf_isom_delete(file);
                                                gf_delete_file("ttxt_convert");
                                                MP4BOX_EXIT_WITH_CODE(1);
@@ -2516,21 +2792,13 @@ int mp4boxMain(int argc, char **argv)
                                }
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
-                               if (dash_duration) {
-                                       if (subsegs_per_sidx<0) subsegs_per_sidx = 0;
+                               if (dump_m2ts) {
 #ifndef GPAC_DISABLE_MPEG2TS
-                                       for (i=0; i<nb_dash_inputs; i++) {
-                                               dump_mpeg2_ts(dash_inputs[i], outName, program_number, dash_duration, seg_at_rap, subsegs_per_sidx,
-                                                       seg_name, seg_ext, use_url_template, single_segment, i, (i+1 == nb_dash_inputs) ? 1 : 0);
-                                       }
-#endif
-                               } else if (dump_m2ts) {
-#ifndef GPAC_DISABLE_MPEG2TS
-                                       dump_mpeg2_ts(inName, pes_dump, program_number, 0, 0, 0, NULL, NULL, 0, 0, 0, 0);
+                                       dump_mpeg2_ts(inName, pes_dump, program_number);
 #endif
-                               } else if (dump_ts) { /* dump_ts means dump time stamp information */
+                               } else if (dump_timestamps) {
 #ifndef GPAC_DISABLE_MPEG2TS
-                                       dump_mpeg2_ts(inName, pes_dump, program_number, 0, 0, 0, NULL, NULL, 0, 0, 0, 0);
+                                       dump_mpeg2_ts(inName, pes_dump, program_number);
 #endif
 #ifndef GPAC_DISABLE_MEDIA_IMPORT
                                } else {
@@ -2544,10 +2812,10 @@ int mp4boxMain(int argc, char **argv)
                                file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, tmpdir);
                                if (!outName && file) outName = inName;
                        } else if (!file_exists) {
-                               fprintf(stdout, "Error creating file %s: %s\n", inName, gf_error_to_string(GF_URL_ERROR));
+                               fprintf(stderr, "Error creating file %s: %s\n", inName, gf_error_to_string(GF_URL_ERROR));
                                MP4BOX_EXIT_WITH_CODE(1);
                        } else {
-                               fprintf(stdout, "Cannot open %s - extension not supported\n", inName);
+                               fprintf(stderr, "Cannot open %s - extension not supported\n", inName);
                                MP4BOX_EXIT_WITH_CODE(1);
                        }
                }
@@ -2577,12 +2845,18 @@ int mp4boxMain(int argc, char **argv)
                mdump.in_name = inName;
                mdump.flags = GF_EXPORT_AVI_NATIVE;
                mdump.trackID = trackID;
-               if (trackID>2) {
+               if (dump_std) {
+                       mdump.out_name = "std";
+               } else if (outName) {
+                       mdump.out_name = outName;
+               } else if (trackID>2) {
                        sprintf(szFile, "%s_audio%d", outfile, trackID-1);
+                       mdump.out_name = szFile;
                } else {
                        sprintf(szFile, "%s_%s", outfile, (trackID==1) ? "video" : "audio");
+                       mdump.out_name = szFile;
                }
-               mdump.out_name = szFile;
+
                e = gf_media_export(&mdump);
                if (e) goto err_exit;
                MP4BOX_EXIT_WITH_CODE(0);
@@ -2616,8 +2890,12 @@ int mp4boxMain(int argc, char **argv)
        if (!HintIt && print_sdp) DumpSDP(file, dump_std ? NULL : outfile);
 #endif
        if (print_info) {
-               if (info_track_id) DumpTrackInfo(file, info_track_id, 1);
-               else DumpMovieInfo(file);
+               if (!file) {
+                       fprintf(stderr, "Cannot print info on a non ISOM file (%s)\n", inName);
+               } else {
+                       if (info_track_id) DumpTrackInfo(file, info_track_id, 1);
+                       else DumpMovieInfo(file);
+               }
        }
 #ifndef GPAC_DISABLE_ISOM_DUMP
        if (dump_isom) dump_isom_xml(file, dump_std ? NULL : outfile);
@@ -2628,14 +2906,16 @@ int mp4boxMain(int argc, char **argv)
 #endif
 #endif
 
-       if (dump_ts) dump_file_ts(file, dump_std ? NULL : outfile);
+       if (dump_timestamps) dump_file_timestamps(file, dump_std ? NULL : outfile);
+       if (dump_nal) dump_file_nal(file, dump_nal, dump_std ? NULL : outfile);
+       
        if (do_hash) {
                u8 hash[20];
                e = gf_media_get_file_hash(inName, hash);
                if (e) goto err_exit;
-               fprintf(stdout, "File %s hash (SHA-1): ", inName);
-               for (i=0; i<20; i++) fprintf(stdout, "%02X", hash[i]);
-               fprintf(stdout, "\n");
+               fprintf(stderr, "File %s hash (SHA-1): ", inName);
+               for (i=0; i<20; i++) fprintf(stderr, "%02X", hash[i]);
+               fprintf(stderr, "\n");
        }
        if (dump_cart) dump_cover_art(file, outfile);
        if (dump_chap) dump_chapters(file, outfile);
@@ -2643,7 +2923,7 @@ int mp4boxMain(int argc, char **argv)
        if (dump_iod) {
                GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *)gf_isom_get_root_od(file);
                if (!iod) {
-                       fprintf(stdout, "File %s has no IOD", inName);
+                       fprintf(stderr, "File %s has no IOD", inName);
                } else {
                        char szName[GF_MAX_PATH];
                        FILE *iodf;
@@ -2652,7 +2932,7 @@ int mp4boxMain(int argc, char **argv)
                        sprintf(szName, "%s.iod", outfile);
                        iodf = gf_f64_open(szName, "wb");
                        if (!iodf) {
-                               fprintf(stdout, "Cannot open destination %s\n", szName);
+                               fprintf(stderr, "Cannot open destination %s\n", szName);
                        } else {
                                char *desc;
                                u32 size;
@@ -2661,7 +2941,7 @@ int mp4boxMain(int argc, char **argv)
                                        gf_fwrite(desc, 1, size, iodf);
                                        gf_free(desc);
                                } else {
-                                       fprintf(stdout, "Error writing IOD %s\n", szName);
+                                       fprintf(stderr, "Error writing IOD %s\n", szName);
                                }
                                fclose(iodf);
                        }
@@ -2671,7 +2951,7 @@ int mp4boxMain(int argc, char **argv)
 
 #if !(definedGPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
        if (split_duration || split_size) {
-               split_isomedia_file(file, split_duration, split_size, inName, InterleavingTime, split_start, adjust_split_end, outName, tmpdir);
+               split_isomedia_file(file, split_duration, split_size, inName, interleaving_time, split_start, adjust_split_end, outName, tmpdir);
                /*never save file when splitting is desired*/
                open_edit = 0;
                needSave = 0;
@@ -2745,14 +3025,14 @@ int mp4boxMain(int argc, char **argv)
                                e = gf_isom_remove_meta_xml(file, meta->root_meta, tk);
                                needSave = 1;
                        } else {
-                               fprintf(stdout, "No meta box in input file\n");
+                               fprintf(stderr, "No meta box in input file\n");
                        }
                        break;
                case 8:
                        if (gf_isom_get_meta_item_count(file, meta->root_meta, tk)) {
                                e = gf_isom_extract_meta_item(file, meta->root_meta, tk, meta->item_id, strlen(meta->szPath) ? meta->szPath : NULL);
                        } else {
-                               fprintf(stdout, "No meta box in input file\n");
+                               fprintf(stderr, "No meta box in input file\n");
                        }
                        break;
 #endif
@@ -2760,7 +3040,7 @@ int mp4boxMain(int argc, char **argv)
                        if (gf_isom_has_meta_xml(file, meta->root_meta, tk)) {
                                e = gf_isom_extract_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL);
                        } else {
-                               fprintf(stdout, "No meta box in input file\n");
+                               fprintf(stderr, "No meta box in input file\n");
                        }
                        break;
                }
@@ -2818,7 +3098,7 @@ int mp4boxMain(int argc, char **argv)
        if (remove_hint) {
                for (i=0; i<gf_isom_get_track_count(file); i++) {
                        if (gf_isom_get_media_type(file, i+1) == GF_ISOM_MEDIA_HINT) {
-                               fprintf(stdout, "Removing hint track ID %d\n", gf_isom_get_track_id(file, i+1));
+                               fprintf(stderr, "Removing hint track ID %d\n", gf_isom_get_track_id(file, i+1));
                                gf_isom_remove_track(file, i+1);
                                i--;
                        }
@@ -2831,7 +3111,7 @@ int mp4boxMain(int argc, char **argv)
 
        if (!encode) {
                if (!file) {
-                       fprintf(stdout, "Nothing to do - exiting\n");
+                       fprintf(stderr, "Nothing to do - exiting\n");
                        gf_sys_close();
                        MP4BOX_EXIT_WITH_CODE(0);
                }
@@ -2858,20 +3138,20 @@ int mp4boxMain(int argc, char **argv)
                }
 #ifndef GPAC_DISABLE_MEDIA_IMPORT
                if ((conv_type == GF_ISOM_CONV_TYPE_ISMA) || (conv_type == GF_ISOM_CONV_TYPE_ISMA_EX)) {
-                       fprintf(stdout, "Converting to ISMA Audio-Video MP4 file...\n");
+                       fprintf(stderr, "Converting to ISMA Audio-Video MP4 file...\n");
                        /*keep ESIDs when doing ISMACryp*/
                        e = gf_media_make_isma(file, ismaCrypt ? 1 : 0, 0, (conv_type==GF_ISOM_CONV_TYPE_ISMA_EX) ? 1 : 0);
                        if (e) goto err_exit;
                        needSave = 1;
                }
                if (conv_type == GF_ISOM_CONV_TYPE_3GPP) {
-                       fprintf(stdout, "Converting to 3GP file...\n");
+                       fprintf(stderr, "Converting to 3GP file...\n");
                        e = gf_media_make_3gpp(file);
                        if (e) goto err_exit;
                        needSave = 1;
                }
                if (conv_type == GF_ISOM_CONV_TYPE_PSP) {
-                       fprintf(stdout, "Converting to PSP file...\n");
+                       fprintf(stderr, "Converting to PSP file...\n");
                        e = gf_media_make_psp(file);
                        if (e) goto err_exit;
                        needSave = 1;
@@ -2880,7 +3160,7 @@ int mp4boxMain(int argc, char **argv)
                if (conv_type == GF_ISOM_CONV_TYPE_IPOD) {
                        u32 major_brand = 0;
 
-                       fprintf(stdout, "Setting up iTunes/iPod file...\n");
+                       fprintf(stderr, "Setting up iTunes/iPod file...\n");
 
                        for (i=0; i<gf_isom_get_track_count(file); i++) {
                                u32 mType = gf_isom_get_media_type(file, i+1);
@@ -2892,7 +3172,7 @@ int mp4boxMain(int argc, char **argv)
                                        switch (gf_isom_get_media_subtype(file, i+1, 1)) {
                                        case GF_ISOM_SUBTYPE_AVC_H264:
                                        case GF_ISOM_SUBTYPE_AVC2_H264:
-                                               fprintf(stdout, "Forcing AVC/H264 SAR to 1:1...\n");
+                                               fprintf(stderr, "Forcing AVC/H264 SAR to 1:1...\n");
                                                gf_media_change_par(file, i+1, 1, 1);
                                                break;
                                        }
@@ -2938,7 +3218,7 @@ int mp4boxMain(int argc, char **argv)
                if (ismaCrypt) {
                        if (ismaCrypt == 1) {
                                if (!drm_file) {
-                                       fprintf(stdout, "Missing DRM file location - usage '-%s drm_file input_file\n", (ismaCrypt==1) ? "crypt" : "decrypt");
+                                       fprintf(stderr, "Missing DRM file location - usage '-%s drm_file input_file\n", (ismaCrypt==1) ? "crypt" : "decrypt");
                                        e = GF_BAD_PARAM;
                                        goto err_exit;
                                }
@@ -2963,9 +3243,9 @@ int mp4boxMain(int argc, char **argv)
                case 0:
                        e = gf_isom_remove_track(file, track);
                        if (e) {
-                               fprintf(stdout, "Error Removing track ID %d: %s\n", tka->trackID, gf_error_to_string(e));
+                               fprintf(stderr, "Error Removing track ID %d: %s\n", tka->trackID, gf_error_to_string(e));
                        } else {
-                               fprintf(stdout, "Removing track ID %d\n", tka->trackID);
+                               fprintf(stderr, "Removing track ID %d\n", tka->trackID);
                        }
                        needSave = 1;
                        break;
@@ -2997,7 +3277,7 @@ int mp4boxMain(int argc, char **argv)
                                                gf_isom_append_edit_segment(file, track, tk_dur-to_skip, media_time, GF_ISOM_EDIT_NORMAL);
                                                needSave = 1;
                                        } else {
-                                               fprintf(stdout, "Warning: request negative delay longer than track duration - ignoring\n");
+                                               fprintf(stderr, "Warning: request negative delay longer than track duration - ignoring\n");
                                        }
                                }
                        } else if (gf_isom_get_edit_segment_count(file, track)) {
@@ -3068,7 +3348,7 @@ int mp4boxMain(int argc, char **argv)
                                }
                        }
                        if (itag==nb_itunes_tags) {
-                               fprintf(stdout, "Invalid iTune tag format \"%s\" - ignoring\n", tags);
+                               fprintf(stderr, "Invalid iTune tag format \"%s\" - ignoring\n", tags);
                                tags = NULL;
                                continue;
                        }
@@ -3076,7 +3356,7 @@ int mp4boxMain(int argc, char **argv)
 
                        val = strchr(tags, '=');
                        if (!val) {
-                               fprintf(stdout, "Invalid iTune tag format \"%s\" (expecting '=') - ignoring\n", tags);
+                               fprintf(stderr, "Invalid iTune tag format \"%s\" (expecting '=') - ignoring\n", tags);
                                tags = NULL;
                                continue;
                        }
@@ -3163,205 +3443,27 @@ int mp4boxMain(int argc, char **argv)
                needSave = 1;
        }
 
-       /*split file*/
-       if (dash_duration) {
-               char szMPD[GF_MAX_PATH];
-               char szInit[GF_MAX_PATH];
-               GF_ISOFile *init_seg;
-               Bool sps_merge_failed = 0;
-               Double period_duration = 0;
-
-               if (single_segment) {
-                       fprintf(stdout, "DASH-ing file%s with single segment\nSubsegment duration %.3f - Fragment duration: %.3f secs\n", (nb_dash_inputs>1) ? "s" : "", dash_duration, InterleavingTime);
-                       subsegs_per_sidx = 0;
-                       seg_name = seg_ext = NULL;
-               } else {
-                       if (!seg_ext) seg_ext = "m4s";
-                       fprintf(stdout, "DASH-ing file with %.3f secs segments - fragments: %.3f secs\n", dash_duration, InterleavingTime);
-                       if (subsegs_per_sidx<0) fprintf(stdout, "No sidx used");
-                       else if (subsegs_per_sidx) fprintf(stdout, "%d subsegments per sidx", subsegs_per_sidx);
-                       else fprintf(stdout, "Single sidx used");
-               }
-               fprintf(stdout, "\n");
-               if (seg_at_rap) fprintf(stdout, "Spliting segments at GOP boundaries\n");
-
-               strcpy(outfile, outName ? outName : inName);
-               while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0;
-               outfile[strlen(outfile)-1] = 0;
-               if (!outName) strcat(outfile, "_dash");
-
-               strcpy(szInit, outfile);
-               strcat(szInit, "_init.mp4");
-               strcpy(szMPD, outfile);
-               strcat(szMPD, ".mpd");
-
-               init_seg = gf_isom_open(szInit, GF_ISOM_OPEN_WRITE, tmpdir);
-               for (i=0; i<nb_dash_inputs; i++) {
-                       u32 j;
-                       Double dur;
-                       GF_ISOFile *in = file;
-                       if (i) {
-                               in = gf_isom_open(dash_inputs[i], GF_ISOM_OPEN_READ, NULL);
-                               if (!in) {
-                                       fprintf(stdout, "Error while opening %s: %s\n", dash_inputs[i], gf_error_to_string( gf_isom_last_error(NULL) ));
-                                       gf_isom_delete(file);
-                                       gf_sys_close();
-                                       MP4BOX_EXIT_WITH_CODE(0);
-                               }
-                       }
-                       for (j=0; j<gf_isom_get_track_count(in); j++) {
-                               u32 track = gf_isom_get_track_by_id(init_seg, gf_isom_get_track_id(in, j+1));
-                               if (track) {                                    
-                                       u32 outDescIndex;
-                                       assert( gf_isom_get_sample_description_count(in, j+1) == 1);
-
-                                       /*if not the same sample desc we might need to clone it*/
-                                       if (! gf_isom_is_same_sample_description(in, j+1, 1, init_seg, track, 1)) {
-                                               Bool do_merge = 1;
-                                               u32 stype1, stype2;
-                                               stype1 = gf_isom_get_media_subtype(in, j+1, 1);
-                                               stype2 = gf_isom_get_media_subtype(init_seg, track, 1);
-                                               if (stype1 != stype2) do_merge = 0;
-                                               switch (stype1) {
-                                               case GF_4CC( 'a', 'v', 'c', '1'):
-                                               case GF_4CC( 'a', 'v', 'c', '2'):
-                                               case GF_4CC( 's', 'v', 'c', '1'):
-                                                       break;
-                                               default:
-                                                       do_merge = 0;
-                                                       break;
-                                               }
-                                               if (do_merge) {
-                                                       u32 k, l, sps_id1, sps_id2;
-                                                       GF_AVCConfig *avccfg1 = gf_isom_avc_config_get(in, j+1, 1);
-                                                       GF_AVCConfig *avccfg2 = gf_isom_avc_config_get(init_seg, track, 1);
-#ifndef GPAC_DISABLE_AV_PARSERS
-                                                       for (k=0; k<gf_list_count(avccfg2->sequenceParameterSets); k++) {
-                                                               GF_AVCConfigSlot *slc = gf_list_get(avccfg2->sequenceParameterSets, k);
-                                                               gf_avc_get_sps_info(slc->data, slc->size, &sps_id1, NULL, NULL, NULL, NULL);
-                                                               for (l=0; l<gf_list_count(avccfg1->sequenceParameterSets); l++) {
-                                                                       GF_AVCConfigSlot *slc_orig = gf_list_get(avccfg1->sequenceParameterSets, l);
-                                                                       gf_avc_get_sps_info(slc_orig->data, slc_orig->size, &sps_id2, NULL, NULL, NULL, NULL);
-                                                                       if (sps_id2==sps_id1) {
-                                                                               do_merge = 0;
-                                                                               break;
-                                                                       }
-                                                               }
-                                                       }
-#endif
-                                                       /*no conflicts in SPS ids, merge all SPS in a single sample desc*/
-                                                       if (do_merge) {
-                                                               while (gf_list_count(avccfg1->sequenceParameterSets)) {
-                                                                       GF_AVCConfigSlot *slc = gf_list_get(avccfg1->sequenceParameterSets, 0);
-                                                                       gf_list_rem(avccfg1->sequenceParameterSets, 0);
-                                                                       gf_list_add(avccfg2->sequenceParameterSets, slc);
-                                                               }
-                                                               while (gf_list_count(avccfg1->pictureParameterSets)) {
-                                                                       GF_AVCConfigSlot *slc = gf_list_get(avccfg1->pictureParameterSets, 0);
-                                                                       gf_list_rem(avccfg1->pictureParameterSets, 0);
-                                                                       gf_list_add(avccfg2->pictureParameterSets, slc);
-                                                               }
-                                                               gf_isom_avc_config_update(init_seg, track, 1, avccfg2);
-                                                       } else {
-                                                               sps_merge_failed = 1;
-                                                       }
-                                                       gf_odf_avc_cfg_del(avccfg1);
-                                                       gf_odf_avc_cfg_del(avccfg2);
-                                               }
-
-                                               /*cannot merge, clone*/
-                                               if (!do_merge)
-                                                       gf_isom_clone_sample_description(init_seg, track, in, j+1, 1, NULL, NULL, &outDescIndex);
-                                       }
-                               } else {
-                                       gf_isom_clone_track(in, j+1, init_seg, 0, &track);
-                               }
-                               dur = (Double) gf_isom_get_track_duration(in, j+1);
-                               dur /= gf_isom_get_timescale(in);
-                               if (dur>period_duration) period_duration = dur;
-                       }
-
-                       if (i) gf_isom_close(in);
-               }
-               if (sps_merge_failed) {
-                       fprintf(stdout, "Couldnt merge AVC|H264 SPS from different files (same SPS ID used) - different sample descriptions will be used\n");
-               }
-               if (!seg_name) use_url_template = 0;
-
-               gf_media_mpd_start(szMPD, (char *)gf_isom_get_filename(file), use_url_template, single_segment, dash_ctx, init_seg, period_duration);
-
-               for (i=0; i<nb_dash_inputs; i++) {
-                       char szSegName[GF_MAX_PATH], *segment_name;
-                       GF_ISOFile *in = file;
-                       if (i) in = gf_isom_open(dash_inputs[i], GF_ISOM_OPEN_READ, NULL);
-
-                       segment_name = seg_name;
-
-                       if (nb_dash_inputs>1) {
-                               char *sep = strrchr(dash_inputs[i], '/');
-                               if (!sep) sep = strrchr(dash_inputs[i], '\\');
-                               if (sep) strcpy(outfile, sep+1);
-                               else strcpy(outfile, dash_inputs[i]);
-                               sep = strrchr(outfile, '.');
-                               if (sep) sep[0] = 0;
-       
-                               if (seg_name) {
-                                       if (strstr(seg_name, "%s")) sprintf(szSegName, seg_name, outfile);
-                                       else strcpy(szSegName, seg_name);
-                                       segment_name = szSegName;
-                               }
-                               strcat(outfile, "_dash");
-                       }
-                       if (nb_dash_inputs>1) {
-                               fprintf(stdout, "DASHing file %s\n", dash_inputs[i]);
-                       }
-#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-                       e = gf_media_fragment_file(in, outfile, szMPD, InterleavingTime, seg_at_rap ? 2 : 1, dash_duration, segment_name, seg_ext, subsegs_per_sidx, daisy_chain_sidx, use_url_template, single_segment, dash_ctx, init_seg, i+1);
-#else
-                       fprintf(stderr, "GPAC was compiled without fragment support\n");
-                       e = GF_NOT_SUPPORTED;
-#endif
-                       if (e) {
-                               fprintf(stdout, "Error while DASH-ing file: %s\n", gf_error_to_string(e));
-                               break;
-                       }
-                       if (i) gf_isom_close(in);
-               }
-               /*close MPD*/
-               gf_media_mpd_end(szMPD);
-               
-               /*if init segment shared, write to file*/
-               if (nb_dash_inputs>1) {
-                       gf_isom_close(init_seg);
-               } else {
-                       gf_isom_delete(init_seg);
-                       gf_delete_file(szInit);
-               }
-
-               gf_isom_delete(file);
-               gf_sys_close();
-               MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
 #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-       } else if (Frag) {
-               if (!InterleavingTime) InterleavingTime = 0.5;
-               if (HintIt) fprintf(stdout, "Warning: cannot hint and fragment - ignoring hint\n");
-               fprintf(stdout, "Fragmenting file (%.3f seconds fragments)\n", InterleavingTime);
-               e = gf_media_fragment_file(file, outfile, NULL, InterleavingTime, 0, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0);
-               if (e) fprintf(stdout, "Error while fragmenting file: %s\n", gf_error_to_string(e));
+       if (Frag) {
+               if (!interleaving_time) interleaving_time = 0.5;
+               if (HintIt) fprintf(stderr, "Warning: cannot hint and fragment - ignoring hint\n");
+               fprintf(stderr, "Fragmenting file (%.3f seconds fragments)\n", interleaving_time);
+               e = gf_media_fragment_file(file, outfile, interleaving_time);
+               if (e) fprintf(stderr, "Error while fragmenting file: %s\n", gf_error_to_string(e));
                gf_isom_delete(file);
                if (!e && !outName && !force_new) {
-                       if (remove(inName)) fprintf(stdout, "Error removing file %s\n", inName);
-                       else if (rename(outfile, inName)) fprintf(stdout, "Error renaming file %s to %s\n", outfile, inName);
+                       if (gf_delete_file(inName)) fprintf(stderr, "Error removing file %s\n", inName);
+                       else if (gf_move_file(outfile, inName)) fprintf(stderr, "Error renaming file %s to %s\n", outfile, inName);
                }
                gf_sys_close();
                MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
-#endif
        }
-       
+#endif
+
 #ifndef GPAC_DISABLE_ISOM_HINTING
        if (HintIt) {
                if (force_ocr) SetupClockReferences(file);
-               fprintf(stdout, "Hinting file with Path-MTU %d Bytes\n", MTUSize);
+               fprintf(stderr, "Hinting file with Path-MTU %d Bytes\n", MTUSize);
                MTUSize -= 12;          
                e = HintFile(file, MTUSize, max_ptime, rtp_rate, hint_flags, HintCopy, HintInter, regular_iod, single_group);
                if (e) goto err_exit;
@@ -3373,14 +3475,14 @@ int mp4boxMain(int argc, char **argv)
        /*full interleave (sample-based) if just hinted*/
        if (FullInter) {
                e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_TIGHT);
-       } else if (!InterleavingTime) {
+       } else if (!interleaving_time) {
                e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_STREAMABLE);
                needSave = 1;
        } else if (do_flat) {
                e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_FLAT);
                needSave = 1;
        } else {
-               e = gf_isom_make_interleave(file, InterleavingTime);
+               e = gf_isom_make_interleave(file, interleaving_time);
                if (!e && !old_interleave) e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_DRIFT_INTERLEAVED);
        }
        if (e) goto err_exit;
@@ -3426,7 +3528,7 @@ int mp4boxMain(int argc, char **argv)
                e = gf_media_import_chapters(file, chap_file, import_fps);
                needSave = 1;
 #else
-               fprintf(stdout, "Warning: GPAC compiled without Media Import, chapters can't be imported\n");
+               fprintf(stderr, "Warning: GPAC compiled without Media Import, chapters can't be imported\n");
                e = GF_NOT_SUPPORTED;
 #endif
                if (e) goto err_exit;
@@ -3448,23 +3550,23 @@ int mp4boxMain(int argc, char **argv)
        if (!encode && !force_new) gf_isom_set_final_name(file, outfile);
        if (needSave) {
                if (outName) {
-                       fprintf(stdout, "Saving to %s: ", outfile);
+                       fprintf(stderr, "Saving to %s: ", outfile);
                        gf_isom_set_final_name(file, outfile);
                } else if (encode || pack_file) {
-                       fprintf(stdout, "Saving to %s: ", gf_isom_get_filename(file) );
+                       fprintf(stderr, "Saving to %s: ", gf_isom_get_filename(file) );
                } else {
-                       fprintf(stdout, "Saving %s: ", inName);
+                       fprintf(stderr, "Saving %s: ", inName);
                }
-               if (HintIt && FullInter) fprintf(stdout, "Hinted file - Full Interleaving\n");
-               else if (FullInter) fprintf(stdout, "Full Interleaving\n");
-               else if (do_flat || !InterleavingTime) fprintf(stdout, "Flat storage\n");
-               else fprintf(stdout, "%.3f secs Interleaving%s\n", InterleavingTime, old_interleave ? " - no drift control" : "");
+               if (HintIt && FullInter) fprintf(stderr, "Hinted file - Full Interleaving\n");
+               else if (FullInter) fprintf(stderr, "Full Interleaving\n");
+               else if (do_flat || !interleaving_time) fprintf(stderr, "Flat storage\n");
+               else fprintf(stderr, "%.3f secs Interleaving%s\n", interleaving_time, old_interleave ? " - no drift control" : "");
 
                e = gf_isom_close(file);
 
                if (!e && !outName && !encode && !force_new && !pack_file) {
-                       if (remove(inName)) fprintf(stdout, "Error removing file %s\n", inName);
-                       else if (rename(outfile, inName)) fprintf(stdout, "Error renaming file %s to %s\n", outfile, inName);
+                       if (gf_delete_file(inName)) fprintf(stderr, "Error removing file %s\n", inName);
+                       else if (gf_move_file(outfile, inName)) fprintf(stderr, "Error renaming file %s to %s\n", outfile, inName);
                }
        } else {
                gf_isom_delete(file);
@@ -3472,20 +3574,20 @@ int mp4boxMain(int argc, char **argv)
        /*close libgpac*/
        gf_sys_close();
 
-       if (e) fprintf(stdout, "Error: %s\n", gf_error_to_string(e));
+       if (e) fprintf(stderr, "Error: %s\n", gf_error_to_string(e));
        MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
 #else
        /*close libgpac*/
        gf_sys_close();
        gf_isom_delete(file);
-       fprintf(stdout, "Error: Read-only version of MP4Box.\n");
+       fprintf(stderr, "Error: Read-only version of MP4Box.\n");
        MP4BOX_EXIT_WITH_CODE(1);
 #endif
 err_exit:
        /*close libgpac*/
        gf_sys_close();
        if (file) gf_isom_delete(file);         
-       fprintf(stdout, "\n\tError: %s\n", gf_error_to_string(e));
+       fprintf(stderr, "\n\tError: %s\n", gf_error_to_string(e));
        MP4BOX_EXIT_WITH_CODE(1);
 }
 
index 0cdc8d97b31cd2611db8ed341fe5f793ab8ebb33..00d37e424a64b1bea0de7e3f16533b4efb3134f8 100644 (file)
@@ -38,9 +38,6 @@ all: $(PROG)
 MP4Client$(EXE): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(LINKLIBS)
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(PROG)
 
index 9ff100944f11bcd5342202fa16f61cb7798cf37a..9556a9d55024a8960f5132ce6336ffc054cbe01d 100644 (file)
@@ -1,13 +1,13 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
- *                     Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / command-line client
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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.
@@ -65,7 +65,7 @@ typedef struct tagBITMAPINFOHEADER{
 
 extern Bool is_connected;
 extern GF_Terminal *term;
-extern u32 Duration;
+extern u64 Duration;
 extern GF_Err last_error;
 
 static GFINLINE u8 colmask(s32 a, s32 n)
@@ -215,6 +215,7 @@ void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num)
 
 void write_png(GF_VideoSurface *fb, char *rad_name, u32 img_num)
 {
+#ifndef GPAC_DISABLE_AV_PARSERS
        char str[GF_MAX_PATH];
        FILE *fout;
        u32 dst_size;
@@ -246,6 +247,7 @@ void write_png(GF_VideoSurface *fb, char *rad_name, u32 img_num)
        }
 
        gf_free(dst);
+#endif //GPAC_DISABLE_AV_PARSERS
 }
 
 
@@ -340,8 +342,8 @@ void dump_depth (GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum,
 
        /*lock it*/
        e = gf_sc_get_screen_buffer(term->compositor, &fb, 1);
-       if (e) fprintf(stdout, "Error grabbing depth buffer: %s\n", gf_error_to_string(e));
-       else  fprintf(stdout, "OK\n");
+       if (e) fprintf(stderr, "Error grabbing depth buffer: %s\n", gf_error_to_string(e));
+       else  fprintf(stderr, "OK\n");
        /*export frame*/
        switch (dump_type) {
        case 1:
@@ -409,7 +411,7 @@ void dump_depth (GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum,
                }
 #ifndef GPAC_DISABLE_AVILIB
                if (AVI_write_frame(avi_out, conv_buf, fb.height*fb.width*3, 1) <0)
-                       printf("Error writing frame\n");
+                       fprintf(stderr, "Error writing frame\n");
 #endif
                break;
        case 2:
@@ -444,7 +446,7 @@ void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum,
        if (dump_type==5 || dump_type==6) e = gf_sc_get_screen_buffer(term->compositor, &fb, 2);
        else if (dump_type== 9 || dump_type==10) e = gf_sc_get_screen_buffer(term->compositor, &fb, 3);
        else e = gf_sc_get_screen_buffer(term->compositor, &fb, 0);
-       if (e) fprintf(stdout, "Error grabbing frame buffer: %s\n", gf_error_to_string(e));
+       if (e) fprintf(stderr, "Error grabbing frame buffer: %s\n", gf_error_to_string(e));
 
        /*export frame*/
        switch (dump_type) {
@@ -549,10 +551,10 @@ void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum,
 #ifndef GPAC_DISABLE_AVILIB
                if (dump_type!=5 && dump_type!= 10) { 
                        if (AVI_write_frame(avi_out, conv_buf, out_size, 1) <0)
-                       printf("Error writing frame\n");
+                       fprintf(stderr, "Error writing frame\n");
                } else {
                        if (AVI_write_frame(avi_out, conv_buf, out_size, 1) <0)
-                       printf("Error writing frame\n");                                
+                       fprintf(stderr, "Error writing frame\n");                               
                }
 #endif
                break;
@@ -594,7 +596,7 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
        prev = strrchr(szPath, '.');
        if (prev) prev[0] = 0;
 
-       fprintf(stdout, "Opening URL %s\n", url);
+       fprintf(stderr, "Opening URL %s\n", url);
        /*connect in pause mode*/
        gf_term_connect_from_time(term, url, 0, 1);
 
@@ -612,14 +614,14 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
                gf_term_process_flush(term);
        } 
 #ifndef GPAC_USE_TINYGL
-        printf("not tinygl\n");
+        fprintf(stderr, "not tinygl\n");
        e = gf_sc_get_screen_buffer(term->compositor, &fb, 0);
 #else
-        printf("tinygl\n");
+        fprintf(stderr, "tinygl\n");
        e = gf_sc_get_screen_buffer(term->compositor, &fb, 1);
 #endif
        if (e != GF_OK) {
-               fprintf(stdout, "Error grabbing screen buffer: %s\n", gf_error_to_string(e));
+               fprintf(stderr, "Error grabbing screen buffer: %s\n", gf_error_to_string(e));
                return 0;
        }
        width = fb.width;
@@ -635,7 +637,7 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
 
        /*we work in RGB24, and we must make sure the pitch is %4*/
        if ((width*3)%4) {
-               fprintf(stdout, "Adjusting width (%d) to have a stride multiple of 4\n", width);
+               fprintf(stderr, "Adjusting width (%d) to have a stride multiple of 4\n", width);
                while ((width*3)%4) width--;
 
                gf_term_set_size(term, width, height);
@@ -649,10 +651,11 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
 
        if (dump_mode==1 || dump_mode==5 || dump_mode==8 || dump_mode==10) {
 #ifdef GPAC_DISABLE_AVILIB
-               fprintf(stdout, "AVILib is disabled in this build of GPAC\n");
+               fprintf(stderr, "AVILib is disabled in this build of GPAC\n");
                return 0;
 #else
-               u32 time, prev_time, nb_frames, dump_dur;
+               u32 time, prev_time, nb_frames;
+               u64 dump_dur;
                char *conv_buf;
                avi_t *avi_out = NULL; 
                avi_t *depth_avi_out = NULL; 
@@ -662,14 +665,14 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
                strcat(szPath, ".avi");
                avi_out = AVI_open_output_file(szPath);
                if (!avi_out) {
-                       fprintf(stdout, "Error creating AVI file %s\n", szPath);
+                       fprintf(stderr, "Error creating AVI file %s\n", szPath);
                        return 1;
                }
                if (dump_mode==8) {
                        strcat(szPath_depth, "_depth.avi");
                        depth_avi_out = AVI_open_output_file(szPath_depth);
                        if (!depth_avi_out) {
-                               fprintf(stdout, "Error creating AVI file %s\n", szPath);
+                               fprintf(stderr, "Error creating AVI file %s\n", szPath);
                                return 1;
                        }       
                }
@@ -685,7 +688,7 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
                        dump_dur = times[0] ? times[0] : Duration;
                }
                if (!dump_dur) {
-                       fprintf(stdout, "Warning: file has no duration, defaulting to 1 sec\n");
+                       fprintf(stderr, "Warning: file has no duration, defaulting to 1 sec\n");
                        dump_dur = 1000;
                }
 
@@ -701,7 +704,7 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
                        while ((gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_STEP_PAUSE)) {
                                gf_term_process_flush(term);
                        }
-                       fprintf(stdout, "Dumping %02d/100 %% - time %.02f sec\r", (u32) ((100.0*prev_time)/dump_dur), prev_time/1000.0 );
+                       fprintf(stderr, "Dumping %02d/100 %% - time %.02f sec\r", (u32) ((100.0*prev_time)/dump_dur), prev_time/1000.0 );
 
                        if (dump_mode==8) {
                                /*we'll dump both buffers at once*/
@@ -719,14 +722,14 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa
                        prev_time = time;
 
                        if (gf_prompt_has_input() && (gf_prompt_get_char()=='q')) {
-                               fprintf(stdout, "Aborting dump\n");
+                               fprintf(stderr, "Aborting dump\n");
                                break;
                        }
                }
                AVI_close(avi_out);
                if (dump_mode==8) AVI_close(depth_avi_out);
                gf_free(conv_buf);
-               fprintf(stdout, "AVI Extraction 100/100\n");
+               fprintf(stderr, "AVI Extraction 100/100\n");
 #endif /*GPAC_DISABLE_AVILIB*/
        } else {
                if (times[0]) gf_term_step_clocks(term, times[0]);
index a2d0ec08c7a9320ac985c6ec398d3742a23c1c20..caa330b4ab1b0889515d35aaf071d94c108185df 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / command-line client
@@ -34,6 +35,9 @@
 /*ISO 639 languages*/
 #include <gpac/iso639.h>
 
+#include <gpac/internal/terminal_dev.h>
+
+
 #ifndef WIN32
 #include <dlfcn.h>
 #include <pwd.h>
@@ -123,7 +127,7 @@ void hide_shell(u32 cmd_type)
 
 void PrintUsage()
 {
-       fprintf(stdout, "Usage MP4Client [options] [filename]\n"
+       fprintf(stderr, "Usage MP4Client [options] [filename]\n"
                "\t-c fileName:    user-defined configuration file. Also works with -cfg\n"
 #ifdef GPAC_MEMORY_TRACKING
                "\t-mem-track:  enables memory tracker\n"
@@ -163,6 +167,9 @@ void PrintUsage()
                "\t        \"audio\"      : Audio renderer and mixers\n"
 #ifdef GPAC_MEMORY_TRACKING
                "\t        \"mem\"        : GPAC memory tracker\n"
+#endif
+#ifndef GPAC_DISABLE_DASH_CLIENT
+               "\t        \"dash\"       : HTTP streaming logs\n"
 #endif
                "\t        \"module\"     : GPAC modules debugging\n"
                "\t        \"mutex\"      : mutex\n"
@@ -224,7 +231,7 @@ void PrintUsage()
 
 void PrintHelp()
 {
-       fprintf(stdout, "MP4Client command keys:\n"
+       fprintf(stderr, "MP4Client command keys:\n"
                "\tq: quit\n"
                "\tX: kill\n"
                "\to: connect to the specified URL\n"
@@ -270,7 +277,7 @@ void PrintHelp()
                "\tE: forces reload of GPAC configuration\n"
                "\n"
                "\tR: toggles run-time info display in window title bar on/off\n"
-               "\tF: toggle displaying of FPS in stdout on/off\n"
+               "\tF: toggle displaying of FPS in stderr on/off\n"
                "\tg: print GPAC allocated memory\n"
                "\th: print this message\n"
                "\n"
@@ -297,7 +304,7 @@ static void PrintTime(u64 time)
        m = (u32) (time / 1000 / 60 - h*60);
        s = (u32) (time / 1000 - h*3600 - m*60);
        ms = (u32) (time - (h*3600 + m*60 + s) * 1000);
-       fprintf(stdout, "%02d:%02d:%02d.%03d", h, m, s, ms);
+       fprintf(stderr, "%02d:%02d:%02d.%03d", h, m, s, ms);
 }
 
 
@@ -325,7 +332,7 @@ static void UpdateRTInfo(const char *legend)
                }
                
                if (display_rti==2) {
-                       fprintf(stdout, "%s\r", szMsg); 
+                       fprintf(stderr, "%s\r", szMsg); 
                } else {
                        GF_Event evt;
                        evt.type = GF_EVENT_SET_CAPTION;
@@ -436,7 +443,7 @@ int getch(){
 static const char * read_line_input(char * line, int maxSize, Bool showContent){
     char read;
     int i = 0;
-    if (fflush( stdout ))
+    if (fflush( stderr ))
       perror("Failed to flush buffer %s");
     do {
       line[i] = '\0';
@@ -445,14 +452,14 @@ static const char * read_line_input(char * line, int maxSize, Bool showContent){
       read = getch();
       if (read == 8 || read == 127){
        if (i > 0){
-         fprintf(stdout, "\b \b");
+         fprintf(stderr, "\b \b");
          i--;
        }
       } else if (read > 32){
-       fputc(showContent ? read : '*', stdout);
+       fputc(showContent ? read : '*', stderr);
        line[i++] = read;
       }
-      fflush(stdout);
+      fflush(stderr);
     } while (read != '\n');
     if (!read)
       return 0;
@@ -564,10 +571,10 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt)
                        gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN));
                        break;
                case GF_KEY_F:
-                       if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stdout, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0));
+                       if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0));
                        break;
                case GF_KEY_T:
-                       if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stdout, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0);
+                       if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0);
                        break;
                case GF_KEY_D:
                        if (evt->key.flags & GF_KEY_MOD_CTRL) gf_term_set_option(term, GF_OPT_DRAW_MODE, (gf_term_get_option(term, GF_OPT_DRAW_MODE)==GF_DRAW_MODE_DEFER) ? GF_DRAW_MODE_IMMEDIATE : GF_DRAW_MODE_DEFER );
@@ -591,16 +598,16 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt)
                case GF_KEY_P:
                        if (evt->key.flags & GF_KEY_MOD_CTRL && is_connected) {
                                Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE);
-                               fprintf(stdout, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
+                               fprintf(stderr, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
                                gf_term_set_option(term, GF_OPT_PLAY_STATE, (gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) ? GF_STATE_PLAYING : GF_STATE_PAUSED);
                        }
                        break;
                case GF_KEY_S:
                        if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) {
                                gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE);
-                               fprintf(stdout, "Step time: ");
+                               fprintf(stderr, "Step time: ");
                                PrintTime(gf_term_get_time_in_ms(term));
-                               fprintf(stdout, "\n");
+                               fprintf(stderr, "\n");
                        }
                        break;
                case GF_KEY_B:
@@ -629,9 +636,9 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt)
        case GF_EVENT_CONNECT:
                if (evt->connect.is_connected) {
                        is_connected = 1;
-                       fprintf(stdout, "Service Connected\n");
+                       fprintf(stderr, "Service Connected\n");
                } else if (is_connected) {
-                       fprintf(stdout, "Service %s\n", is_connected ? "Disconnected" : "Connection Failed");
+                       fprintf(stderr, "Service %s\n", is_connected ? "Disconnected" : "Connection Failed");
                        is_connected = 0;
                        Duration = 0;
                }
@@ -704,16 +711,16 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt)
        }
                break;
        case GF_EVENT_NAVIGATE_INFO:
-               if (evt->navigate.to_url) fprintf(stdout, "Go to URL: \"%s\"\r", evt->navigate.to_url);
+               if (evt->navigate.to_url) fprintf(stderr, "Go to URL: \"%s\"\r", evt->navigate.to_url);
                break;
        case GF_EVENT_NAVIGATE:
                if (gf_term_is_supported_url(term, evt->navigate.to_url, 1, no_mime_check)) {
                        strcpy(the_url, evt->navigate.to_url);
-                       fprintf(stdout, "Navigating to URL %s\n", the_url);
+                       fprintf(stderr, "Navigating to URL %s\n", the_url);
                        gf_term_navigate_to(term, evt->navigate.to_url);
                        return 1;
                } else {
-                       fprintf(stdout, "Navigation destination not supported\nGo to URL: %s\n", evt->navigate.to_url);
+                       fprintf(stderr, "Navigation destination not supported\nGo to URL: %s\n", evt->navigate.to_url);
                }
                break;
        case GF_EVENT_SET_CAPTION:
@@ -727,15 +734,15 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt)
                assert( evt->auth.password);
                assert( evt->auth.site_url);
                while ((!strlen(evt->auth.user) || !strlen(evt->auth.password)) && (maxTries--) >= 0){
-                       fprintf(stdout, "**** Authorization required for site %s ****\n", evt->auth.site_url);
-                       fprintf(stdout, "login   : ");
+                       fprintf(stderr, "**** Authorization required for site %s ****\n", evt->auth.site_url);
+                       fprintf(stderr, "login   : ");
                        read_line_input(evt->auth.user, 50, 1);
-                       fprintf(stdout, "\npassword: ");
+                       fprintf(stderr, "\npassword: ");
                        read_line_input(evt->auth.password, 50, 0);
-                       printf("*********\n");
+                       fprintf(stderr, "*********\n");
                }
                if (maxTries < 0){
-                 printf("**** No User or password has been filled, aborting ***\n");
+                 fprintf(stderr, "**** No User or password has been filled, aborting ***\n");
                  return 0;
                }
                return 1;
@@ -749,12 +756,12 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt)
 void list_modules(GF_ModuleManager *modules)
 {
        u32 i;
-       fprintf(stdout, "\rAvailable modules:\n");
+       fprintf(stderr, "\rAvailable modules:\n");
        for (i=0; i<gf_modules_get_count(modules); i++) {
                char *str = (char *) gf_modules_get_file_name(modules, i);
-               if (str) fprintf(stdout, "\t%s\n", str);
+               if (str) fprintf(stderr, "\t%s\n", str);
        }
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
 }
 
 void set_navigation()
@@ -766,16 +773,16 @@ void set_navigation()
        fflush(stdin);
 
        if (!type) {
-               fprintf(stdout, "Content/compositor doesn't allow user-selectable navigation\n");
+               fprintf(stderr, "Content/compositor doesn't allow user-selectable navigation\n");
        } else if (type==1) {
-               fprintf(stdout, "Select Navigation (\'N\'one, \'E\'xamine, \'S\'lide): ");
+               fprintf(stderr, "Select Navigation (\'N\'one, \'E\'xamine, \'S\'lide): ");
                nav = getch();
                if (nav=='N') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
                else if (nav=='E') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE);
                else if (nav=='S') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE);
-               else fprintf(stdout, "Unknown selector \'%c\' - only \'N\',\'E\',\'S\' allowed\n", nav);
+               else fprintf(stderr, "Unknown selector \'%c\' - only \'N\',\'E\',\'S\' allowed\n", nav);
        } else if (type==2) {
-               fprintf(stdout, "Select Navigation (\'N\'one, \'W\'alk, \'F\'ly, \'E\'xamine, \'P\'an, \'S\'lide, \'G\'ame, \'V\'R, \'O\'rbit): ");
+               fprintf(stderr, "Select Navigation (\'N\'one, \'W\'alk, \'F\'ly, \'E\'xamine, \'P\'an, \'S\'lide, \'G\'ame, \'V\'R, \'O\'rbit): ");
                nav = getch();
                if (nav=='N') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
                else if (nav=='W') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK);
@@ -786,9 +793,9 @@ void set_navigation()
                else if (nav=='G') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_GAME);
                else if (nav=='O') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_ORBIT);
                else if (nav=='V') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_VR);
-               else fprintf(stdout, "Unknown selector %c - only \'N\',\'W\',\'F\',\'E\',\'P\',\'S\',\'G\', \'V\', \'O\' allowed\n", nav);
+               else fprintf(stderr, "Unknown selector %c - only \'N\',\'W\',\'F\',\'E\',\'P\',\'S\',\'G\', \'V\', \'O\' allowed\n", nav);
        }
-       if (e) fprintf(stdout, "Error setting mode: %s\n", gf_error_to_string(e));
+       if (e) fprintf(stderr, "Error setting mode: %s\n", gf_error_to_string(e));
 }
 
 
@@ -870,6 +877,30 @@ static void init_rti_logs(char *rti_file, char *url, Bool use_rtix)
        }
 }
 
+void set_cfg_option(char *opt_string)
+{
+       char *sep, *sep2, szSec[1024], szKey[1024], szVal[1024];
+       sep = strchr(opt_string, ':');
+       if (!sep) {
+               fprintf(stderr, "Badly formatted option %s - expected Section:Name=Value\n", opt_string);
+               return;
+       }
+       sep[0] = 0;
+       strcpy(szSec, opt_string);
+       sep[0] = ':'; sep ++;
+       sep2 = strchr(sep, '=');
+       if (!sep2) {
+               fprintf(stderr, "Badly formatted option %s - expected Section:Name=Value\n", opt_string);
+               return;
+       }
+       sep2[0] = 0;
+       strcpy(szKey, sep);
+       strcpy(szVal, sep2+1);
+       sep2[0] = '='; 
+       if (!stricmp(szVal, "null")) szVal[0]=0;
+       gf_cfg_set_key(cfg_file, szSec, szKey, szVal[0] ? szVal : NULL);
+}
+
 #ifdef WIN32
 #include <wincon.h>
 #endif
@@ -922,7 +953,7 @@ int main (int argc, char **argv)
 #ifdef GPAC_MEMORY_TRACKING
                        enable_mem_tracker = 1;
 #else
-                       fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
+                       fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
 #endif
                }
                else if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) {
@@ -939,7 +970,7 @@ int main (int argc, char **argv)
 
        cfg_file = gf_cfg_init(the_cfg, NULL);
        if (!cfg_file) {
-               fprintf(stdout, "Error: Configuration File not found\n");
+               fprintf(stderr, "Error: Configuration File not found\n");
                return 1;
        }
        /*if logs are specified, use them*/
@@ -1056,27 +1087,12 @@ int main (int argc, char **argv)
 #ifdef GPAC_MEMORY_TRACKING
                        enable_mem_tracker = 1;
 #else
-                       fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
+                       fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); 
 #endif
                }
                else if (!strcmp(arg, "-loop")) loop_at_end = 1;
                else if (!strcmp(arg, "-opt")) {
-                       char *sep, *sep2, szSec[1024], szKey[1024], szVal[1024];
-                       sep = strchr(argv[i+1], ':');
-                       if (sep) {
-                               sep[0] = 0;
-                               strcpy(szSec, argv[i+1]);
-                               sep[0] = ':'; sep ++;
-                               sep2 = strchr(sep, '=');
-                               if (sep2) {
-                                       sep2[0] = 0;
-                                       strcpy(szKey, sep);
-                                       strcpy(szVal, sep2+1);
-                                       sep2[0] = '='; 
-                                       if (!stricmp(szVal, "null")) szVal[0]=0;
-                                       gf_cfg_set_key(cfg_file, szSec, szKey, szVal[0] ? szVal : NULL);
-                               }
-                       }
+                       set_cfg_option(argv[i+1]);
                        i++;
                }
                else if (!stricmp(arg, "-views")) {
@@ -1093,11 +1109,11 @@ int main (int argc, char **argv)
                        PrintUsage();
                        return 1;
                } else { 
-                       fprintf(stdout, "Unrecognized option %s - skipping\n", arg);
+                       fprintf(stderr, "Unrecognized option %s - skipping\n", arg);
                }
        }
        if (dump_mode && !url_arg ) {
-               fprintf(stdout, "Missing argument for dump\n");
+               fprintf(stderr, "Missing argument for dump\n");
                PrintUsage();
                if (logfile) fclose(logfile);
                return 1;
@@ -1137,21 +1153,21 @@ int main (int argc, char **argv)
                init_h = forced_height;
        }
 
-       fprintf(stdout, "Loading modules\n");
+       fprintf(stderr, "Loading modules\n");
        str = gf_cfg_get_key(cfg_file, "General", "ModulesDirectory");
        assert( str );
 
        user.modules = gf_modules_new((const unsigned char *) str, cfg_file);
        if (user.modules) i = gf_modules_get_count(user.modules);
        if (!i || !user.modules) {
-               fprintf(stdout, "Error: no modules found in %s - exiting\n", str);
+               fprintf(stderr, "Error: no modules found in %s - exiting\n", str);
                if (user.modules) gf_modules_del(user.modules);
                gf_cfg_del(cfg_file);
                gf_sys_close();
                if (logfile) fclose(logfile);
                return 1;
        }
-       fprintf(stdout, "Modules Found (%d in dir %s)\n", i, str);
+       fprintf(stderr, "Modules Found (%d in dir %s)\n", i, str);
 
        user.config = cfg_file;
        user.EventProc = GPAC_EventProc;
@@ -1163,11 +1179,11 @@ int main (int argc, char **argv)
 
        if (threading_flags & (GF_TERM_NO_DECODER_THREAD|GF_TERM_NO_COMPOSITOR_THREAD) ) term_step = 1;
 
-       fprintf(stdout, "Loading GPAC Terminal\n");     
+       fprintf(stderr, "Loading GPAC Terminal\n");     
        i = gf_sys_clock();
        term = gf_term_new(&user);
        if (!term) {
-               fprintf(stdout, "\nInit error - check you have at least one video out and one rasterizer...\nFound modules:\n");
+               fprintf(stderr, "\nInit error - check you have at least one video out and one rasterizer...\nFound modules:\n");
                list_modules(user.modules);
                gf_modules_del(user.modules);
                gf_cfg_del(cfg_file);
@@ -1175,7 +1191,7 @@ int main (int argc, char **argv)
                if (logfile) fclose(logfile);
                return 1;
        }
-       fprintf(stdout, "Terminal Loaded in %d ms\n", gf_sys_clock()-i);
+       fprintf(stderr, "Terminal Loaded in %d ms\n", gf_sys_clock()-i);
 
        if (dump_mode) {
 //             gf_term_set_option(term, GF_OPT_VISIBLE, 0);
@@ -1183,10 +1199,10 @@ int main (int argc, char **argv)
        } else {
                /*check video output*/
                str = gf_cfg_get_key(cfg_file, "Video", "DriverName");
-               if (!strcmp(str, "Raw Video Output")) fprintf(stdout, "WARNING: using raw output video (memory only) - no display used\n");
+               if (!strcmp(str, "Raw Video Output")) fprintf(stderr, "WARNING: using raw output video (memory only) - no display used\n");
                /*check audio output*/
                str = gf_cfg_get_key(cfg_file, "Audio", "DriverName");
-               if (!str || !strcmp(str, "No Audio Output Available")) fprintf(stdout, "WARNING: no audio output available - make sure no other program is locking the sound card\n");
+               if (!str || !strcmp(str, "No Audio Output Available")) fprintf(stderr, "WARNING: no audio output available - make sure no other program is locking the sound card\n");
 
                str = gf_cfg_get_key(cfg_file, "General", "NoMIMETypeFetch");
                no_mime_check = (str && !stricmp(str, "yes")) ? 1 : 0;
@@ -1195,7 +1211,7 @@ int main (int argc, char **argv)
        str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Enabled");
        if (str && !strcmp(str, "yes")) {
                str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Name");
-               if (str) fprintf(stdout, "HTTP Proxy %s enabled\n", str);
+               if (str) fprintf(stderr, "HTTP Proxy %s enabled\n", str);
        }
 
        if (rti_file) {
@@ -1226,28 +1242,42 @@ int main (int argc, char **argv)
 
                strcpy(the_url, url_arg);
                ext = strrchr(the_url, '.');
-               if (ext && strncmp("http:", the_url, 5) && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) {
-                       fprintf(stdout, "Opening Playlist %s\n", the_url);
-                       playlist = gf_f64_open(the_url, "rt");
+               if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) {
+                       GF_Err e = GF_OK;
+                       fprintf(stderr, "Opening Playlist %s\n", the_url);
+       
+                       strcpy(pl_path, the_url);
+                       /*this is not clean, we need to have a plugin handle playlist for ourselves*/
+                       if (!strncmp("http:", the_url, 5)) {
+                               GF_DownloadSession *sess = gf_dm_sess_new(term->downloader, the_url, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e);
+                               if (sess) {
+                                       e = gf_dm_sess_process(sess);
+                                       if (!e) strcpy(the_url, gf_dm_sess_get_cache_name(sess));
+                                       gf_dm_sess_del(sess);
+                               }
+                       }
+                       
+                       playlist = e ? NULL : gf_f64_open(the_url, "rt");
                        readonly_playlist = 1;
                        if (playlist) {
-                               strcpy(pl_path, the_url);
                                if (1 > fscanf(playlist, "%s", the_url))
                                  fprintf(stderr, "Cannot read any URL from playlist\n");
                                else {
-                                 fprintf(stdout, "Opening URL %s\n", the_url);
+                                 fprintf(stderr, "Opening URL %s\n", the_url);
                                  gf_term_connect_with_path(term, the_url, pl_path);
                                }
                        } else {
-                               fprintf(stdout, "Hit 'h' for help\n\n");
+                               if (e) 
+                                       fprintf(stderr, "Failed to open playlist %s: %s\n", the_url, gf_error_to_string(e) );
+                               fprintf(stderr, "Hit 'h' for help\n\n");
                        }
                } else {
-                       fprintf(stdout, "Opening URL %s\n", the_url);
-                       if (pause_at_first) fprintf(stdout, "[Status: Paused]\n");
+                       fprintf(stderr, "Opening URL %s\n", the_url);
+                       if (pause_at_first) fprintf(stderr, "[Status: Paused]\n");
                        gf_term_connect_from_time(term, the_url, 0, pause_at_first);
                }
        } else {
-               fprintf(stdout, "Hit 'h' for help\n\n");
+               fprintf(stderr, "Hit 'h' for help\n\n");
                str = gf_cfg_get_key(cfg_file, "General", "StartupFile");
                if (str) {
                        strcpy(the_url, "MP4Client "GPAC_FULL_VERSION);
@@ -1317,7 +1347,7 @@ force_input:
                case 'o':
                        startup_file = 0;
                        gf_term_disconnect(term);
-                       fprintf(stdout, "Enter the absolute URL\n");
+                       fprintf(stderr, "Enter the absolute URL\n");
                        if (1 > scanf("%s", the_url)){
                            fprintf(stderr, "Cannot read absolute URL, aborting\n");
                            break;
@@ -1327,7 +1357,7 @@ force_input:
                        break;
                case 'O':
                        gf_term_disconnect(term);
-                       fprintf(stdout, "Enter the absolute URL to the playlist\n");
+                       fprintf(stderr, "Enter the absolute URL to the playlist\n");
                        if (1 > scanf("%s", the_url)){
                            fprintf(stderr, "Cannot read the absolute URL, aborting.\n");
                            break;
@@ -1339,7 +1369,7 @@ force_input:
                                    fclose( playlist);
                                    break;
                                }
-                               fprintf(stdout, "Opening URL %s\n", the_url);
+                               fprintf(stderr, "Opening URL %s\n", the_url);
                                gf_term_connect(term, the_url);
                        }
                        break;
@@ -1355,10 +1385,10 @@ force_input:
                                        res = fscanf(playlist, "%s", the_url);
                                }
                                if (res == EOF) {
-                                       fprintf(stdout, "No more items - exiting\n");
+                                       fprintf(stderr, "No more items - exiting\n");
                                        Run = 0;
                                } else {
-                                       fprintf(stdout, "Opening URL %s\n", the_url);
+                                       fprintf(stderr, "Opening URL %s\n", the_url);
                                        gf_term_connect_with_path(term, the_url, pl_path);
                                }
                        }
@@ -1378,7 +1408,7 @@ force_input:
                                        }
                                        count--;
                                }
-                               fprintf(stdout, "Opening URL %s\n", the_url);
+                               fprintf(stderr, "Opening URL %s\n", the_url);
                                gf_term_connect(term, the_url);
                        }
                        break;
@@ -1394,32 +1424,32 @@ force_input:
                case 'p':
                        if (is_connected) {
                                Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE);
-                               fprintf(stdout, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
+                               fprintf(stderr, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
                                gf_term_set_option(term, GF_OPT_PLAY_STATE, is_pause ? GF_STATE_PLAYING : GF_STATE_PAUSED);
                        }
                        break;
                case 's':
                        if (is_connected) {
                                gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE);
-                               fprintf(stdout, "Step time: ");
+                               fprintf(stderr, "Step time: ");
                                PrintTime(gf_term_get_time_in_ms(term));
-                               fprintf(stdout, "\n");
+                               fprintf(stderr, "\n");
                        }
                        break;
 
                case 'z':
                case 'T':
                        if (!CanSeek || (Duration<=2000)) {
-                               fprintf(stdout, "scene not seekable\n");
+                               fprintf(stderr, "scene not seekable\n");
                        } else {
                                Double res;
                                s32 seekTo;
-                               fprintf(stdout, "Duration: ");
+                               fprintf(stderr, "Duration: ");
                                PrintTime(Duration);
                                res = gf_term_get_time_in_ms(term);
                                if (c=='z') {
                                        res *= 100; res /= (s64)Duration;
-                                       fprintf(stdout, " (current %.2f %%)\nEnter Seek percentage:\n", res);
+                                       fprintf(stderr, " (current %.2f %%)\nEnter Seek percentage:\n", res);
                                        if (scanf("%d", &seekTo) == 1) { 
                                                if (seekTo > 100) seekTo = 100;
                                                res = (Double)(s64)Duration; res /= 100; res *= seekTo;
@@ -1427,9 +1457,9 @@ force_input:
                                        }
                                } else {
                                        u32 r, h, m, s;
-                                       fprintf(stdout, " - Current Time: ");
+                                       fprintf(stderr, " - Current Time: ");
                                        PrintTime((u64) res);
-                                       fprintf(stdout, "\nEnter seek time (Format: s, m:s or h:m:s):\n");
+                                       fprintf(stderr, "\nEnter seek time (Format: s, m:s or h:m:s):\n");
                                        h = m = s = 0;
                                        r =scanf("%d:%d:%d", &h, &m, &s);
                                        if (r==2) { s = m; m = h; h = 0; }
@@ -1446,11 +1476,11 @@ force_input:
                case 't':
                {
                        if (is_connected) {
-                               fprintf(stdout, "Current Time: ");
+                               fprintf(stderr, "Current Time: ");
                                PrintTime(gf_term_get_time_in_ms(term));
-                               fprintf(stdout, " - Duration: ");
+                               fprintf(stderr, " - Duration: ");
                                PrintTime(Duration);
-                               fprintf(stdout, "\n");
+                               fprintf(stderr, "\n");
                        }
                }
                        break;
@@ -1464,8 +1494,8 @@ force_input:
                        if (is_connected) {
                                u32 ID;
                                do {
-                                 fprintf(stdout, "Enter OD ID (0 for main OD): ");
-                                 fflush(stdout);
+                                 fprintf(stderr, "Enter OD ID (0 for main OD): ");
+                                 fflush(stderr);
                                } while( 1 > scanf("%ud", &ID));
                                ViewOD(term, ID, (u32)-1);
                        }
@@ -1474,8 +1504,8 @@ force_input:
                        if (is_connected) {
                                u32 num;
                                do {
-                                 fprintf(stdout, "Enter OD number (0 for main OD): ");
-                                 fflush(stdout);
+                                 fprintf(stderr, "Enter OD number (0 for main OD): ");
+                                 fflush(stderr);
                                } while( 1 > scanf("%ud", &num));
                                ViewOD(term, (u32)-1, num);
                        }
@@ -1508,8 +1538,8 @@ force_input:
                                Bool xml_dump, std_out;
                                radname[0] = 0;
                                do {
-                                 fprintf(stdout, "Enter Inline OD ID if any or 0 : ");
-                                 fflush(stdout);
+                                 fprintf(stderr, "Enter Inline OD ID if any or 0 : ");
+                                 fflush(stderr);
                                } while( 1 >  scanf("%ud", &odid));
                                if (odid) {
                                        GF_ObjectManager *root_odm = gf_term_get_root_object(term);
@@ -1525,8 +1555,8 @@ force_input:
                                        }
                                }
                                do{
-                                 fprintf(stdout, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stdout: ");
-                                 fflush(stdout);
+                                 fprintf(stderr, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stderr: ");
+                                 fflush(stderr);
                                } while( 1 > scanf("%s", radname));
                                sExt = strrchr(radname, '.');
                                xml_dump = 0;
@@ -1536,7 +1566,7 @@ force_input:
                                }
                                std_out = strnicmp(radname, "std", 3) ? 0 : 1;
                                e = gf_term_dump_scene(term, std_out ? NULL : radname, NULL, xml_dump, 0, odm);
-                               fprintf(stdout, "Dump done (%s)\n", gf_error_to_string(e));
+                               fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e));
                        }
                        break;
 
@@ -1547,7 +1577,7 @@ force_input:
                {
                        Bool use_3d = !gf_term_get_option(term, GF_OPT_USE_OPENGL);
                        if (gf_term_set_option(term, GF_OPT_USE_OPENGL, use_3d)==GF_OK) {
-                               fprintf(stdout, "Using %s for 2D drawing\n", use_3d ? "OpenGL" : "2D rasterizer");
+                               fprintf(stderr, "Using %s for 2D drawing\n", use_3d ? "OpenGL" : "2D rasterizer");
                        }
                }
                        break;
@@ -1555,7 +1585,7 @@ force_input:
                {
                        Bool opt = gf_term_get_option(term, GF_OPT_STRESS_MODE);
                        opt = !opt;
-                       fprintf(stdout, "Turning stress mode %s\n", opt ? "on" : "off");
+                       fprintf(stderr, "Turning stress mode %s\n", opt ? "on" : "off");
                        gf_term_set_option(term, GF_OPT_STRESS_MODE, opt);
                }
                        break;
@@ -1568,21 +1598,21 @@ force_input:
                        switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) {
                        case GF_MEDIA_CACHE_DISABLED: gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); break;
                        case GF_MEDIA_CACHE_ENABLED: gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); break;
-                       case GF_MEDIA_CACHE_RUNNING: fprintf(stdout, "Streaming Cache is running - please stop it first\n"); continue;
+                       case GF_MEDIA_CACHE_RUNNING: fprintf(stderr, "Streaming Cache is running - please stop it first\n"); continue;
                        }
                        switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) {
-                       case GF_MEDIA_CACHE_ENABLED: fprintf(stdout, "Streaming Cache Enabled\n"); break;
-                       case GF_MEDIA_CACHE_DISABLED: fprintf(stdout, "Streaming Cache Disabled\n"); break;
-                       case GF_MEDIA_CACHE_RUNNING: fprintf(stdout, "Streaming Cache Running\n"); break;
+                       case GF_MEDIA_CACHE_ENABLED: fprintf(stderr, "Streaming Cache Enabled\n"); break;
+                       case GF_MEDIA_CACHE_DISABLED: fprintf(stderr, "Streaming Cache Disabled\n"); break;
+                       case GF_MEDIA_CACHE_RUNNING: fprintf(stderr, "Streaming Cache Running\n"); break;
                        }
                        break;
                case 'S':
                case 'A':
                        if (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)==GF_MEDIA_CACHE_RUNNING) {
                                gf_term_set_option(term, GF_OPT_MEDIA_CACHE, (c=='S') ? GF_MEDIA_CACHE_DISABLED : GF_MEDIA_CACHE_DISCARD);
-                               fprintf(stdout, "Streaming Cache stopped\n");
+                               fprintf(stderr, "Streaming Cache stopped\n");
                        } else {
-                               fprintf(stdout, "Streaming Cache not running\n");
+                               fprintf(stderr, "Streaming Cache not running\n");
                        }
                        break;
                case 'R':
@@ -1599,7 +1629,7 @@ force_input:
                {
                        GF_Err e;
                        char szCom[8192];
-                       fprintf(stdout, "Enter command to send:\n");
+                       fprintf(stderr, "Enter command to send:\n");
                        fflush(stdin);
                        szCom[0] = 0;
                        if (1 > scanf("%[^\t\n]", szCom)){
@@ -1607,7 +1637,7 @@ force_input:
                            break;
                        }
                        e = gf_term_scene_update(term, NULL, szCom);
-                       if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e));
+                       if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
                }
                        break;
 
@@ -1615,7 +1645,7 @@ force_input:
                {
                        char szLog[1024], *cur_logs;
                        cur_logs = gf_log_get_tools_levels();
-                       fprintf(stdout, "Enter new log level (current tools %s):\n", cur_logs);
+                       fprintf(stderr, "Enter new log level (current tools %s):\n", cur_logs);
                        gf_free(cur_logs);
                        if (scanf("%s", szLog) < 1) {
                            fprintf(stderr, "Cannot read new log level, aborting.\n");
@@ -1629,14 +1659,14 @@ force_input:
                {
                        GF_SystemRTInfo rti;
                        gf_sys_get_rti(rti_update_time_ms, &rti, 0);
-                       fprintf(stdout, "GPAC allocated memory "LLD"\n", rti.gpac_memory);
+                       fprintf(stderr, "GPAC allocated memory "LLD"\n", rti.gpac_memory);
                }
                        break;
                case 'M':
                {
                        u32 size;
                        do {
-                               fprintf(stdout, "Enter new video cache memory in kBytes (current %ud):\n", gf_term_get_option(term, GF_OPT_VIDEO_CACHE_SIZE));
+                               fprintf(stderr, "Enter new video cache memory in kBytes (current %ud):\n", gf_term_get_option(term, GF_OPT_VIDEO_CACHE_SIZE));
                        } while (1 > scanf("%ud", &size));
                        gf_term_set_option(term, GF_OPT_VIDEO_CACHE_SIZE, size);
                }
@@ -1650,6 +1680,20 @@ force_input:
                        switch_bench();
                        break;
 
+               case 'Y':
+               {
+                       char szOpt[8192];
+                       fprintf(stderr, "Enter option to set (Section:Name=Value):\n");
+                       fflush(stdin);
+                       szOpt[0] = 0;
+                       if (1 > scanf("%[^\t\n]", szOpt)){
+                           fprintf(stderr, "Cannot read option\n");
+                           break;
+                       }
+                       set_cfg_option(szOpt);
+               }
+                       break;
+
                /*extract to PNG*/
                case 'Z':
                {
@@ -1660,7 +1704,7 @@ force_input:
                        nb_pass = 1;
                        nb_views = gf_term_get_option(term, GF_OPT_NUM_STEREO_VIEWS);
                        if (nb_views>1) {
-                               fprintf(stdout, "Auto-stereo mode detected - type number of view to dump (0 is main output, 1 to %d offscreen view, %d for all offscreen, %d for all offscreen and main)\n", nb_views, nb_views+1, nb_views+2);
+                               fprintf(stderr, "Auto-stereo mode detected - type number of view to dump (0 is main output, 1 to %d offscreen view, %d for all offscreen, %d for all offscreen and main)\n", nb_views, nb_views+1, nb_views+2);
                                if (scanf("%d", &offscreen_view) != 1) {
                                        offscreen_view = 0;
                                }
@@ -1684,32 +1728,34 @@ force_input:
                                }
                                offscreen_view++;
                                if (e) {
-                                       fprintf(stdout, "Error dumping screen buffer %s\n", gf_error_to_string(e) );
+                                       fprintf(stderr, "Error dumping screen buffer %s\n", gf_error_to_string(e) );
                                        nb_pass = 0;
                                } else {
+#ifndef GPAC_DISABLE_AV_PARSERS
                                        u32 dst_size = fb.width*fb.height*4;
                                        char *dst = (char*)gf_malloc(sizeof(char)*dst_size);
 
                                        e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size);
                                        if (e) {
-                                               fprintf(stdout, "Error encoding PNG %s\n", gf_error_to_string(e) );
+                                               fprintf(stderr, "Error encoding PNG %s\n", gf_error_to_string(e) );
                                                nb_pass = 0;
                                        } else {
                                                FILE *png = gf_f64_open(szFileName, "wb");
                                                if (!png) {
-                                                       fprintf(stdout, "Error writing file %s\n", szFileName);
+                                                       fprintf(stderr, "Error writing file %s\n", szFileName);
                                                        nb_pass = 0;
                                                } else {
                                                        gf_fwrite(dst, dst_size, 1, png);
                                                        fclose(png);
-                                                       fprintf(stdout, "Dump to %s\n", szFileName);
+                                                       fprintf(stderr, "Dump to %s\n", szFileName);
                                                }
                                        }
                                        if (dst) gf_free(dst);
                                        gf_term_release_screen_buffer(term, &fb);
+#endif //GPAC_DISABLE_AV_PARSERS
                                }
                        }
-                       fprintf(stdout, "Done: %s\n", szFileName);
+                       fprintf(stderr, "Done: %s\n", szFileName);
                }
                        break;
 
@@ -1725,12 +1771,12 @@ force_input:
        gf_term_disconnect(term);
        if (rti_file) UpdateRTInfo("Disconnected\n");
 
-       fprintf(stdout, "Deleting terminal... ");
+       fprintf(stderr, "Deleting terminal... ");
        if (playlist) fclose(playlist);
        gf_term_del(term);
-       fprintf(stdout, "done (in %d ms)\n", gf_sys_clock() - i);
+       fprintf(stderr, "done (in %d ms)\n", gf_sys_clock() - i);
 
-       fprintf(stdout, "GPAC cleanup ...\n");
+       fprintf(stderr, "GPAC cleanup ...\n");
        gf_modules_del(user.modules);
        gf_cfg_del(cfg_file);
 
@@ -1753,12 +1799,12 @@ void PrintWorldInfo(GF_Terminal *term)
        descs = gf_list_new();
        title = gf_term_get_world_info(term, NULL, descs);
        if (!title && !gf_list_count(descs)) {
-               fprintf(stdout, "No World Info available\n");
+               fprintf(stderr, "No World Info available\n");
        } else {
-               fprintf(stdout, "\t%s\n", title ? title : "No title available");
+               fprintf(stderr, "\t%s\n", title ? title : "No title available");
                for (i=0; i<gf_list_count(descs); i++) {
                        char *str = gf_list_get(descs, i);
-                       fprintf(stdout, "%s\n", str);
+                       fprintf(stderr, "%s\n", str);
                }
        }
        gf_list_del(descs);
@@ -1772,31 +1818,31 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind
        GF_ObjectManager *odm;
 
        if (!root_odm) {
-               fprintf(stdout, "Currently loaded objects:\n");
+               fprintf(stderr, "Currently loaded objects:\n");
                root_odm = gf_term_get_root_object(term);
        }
        if (!root_odm) return;
 
        count = gf_term_get_current_service_id(term);
        if (count) 
-               fprintf(stdout, "Current service ID %d\n", count);
+               fprintf(stderr, "Current service ID %d\n", count);
 
        if (gf_term_get_object_info(term, root_odm, &odi) != GF_OK) return;
        if (!odi.od) {
-               fprintf(stdout, "Service not attached\n");
+               fprintf(stderr, "Service not attached\n");
                return;
        }
 
        for (i=0;i<indent;i++) szIndent[i]=' ';
        szIndent[indent]=0;
        
-       fprintf(stdout, "%s", szIndent);
-       fprintf(stdout, "#%d %s - ", num, root_name);
-       if (odi.od->ServiceID) fprintf(stdout, "Service ID %d ", odi.od->ServiceID);
+       fprintf(stderr, "%s", szIndent);
+       fprintf(stderr, "#%d %s - ", num, root_name);
+       if (odi.od->ServiceID) fprintf(stderr, "Service ID %d ", odi.od->ServiceID);
        if (odi.media_url) {
-               fprintf(stdout, "%s\n", odi.media_url);
+               fprintf(stderr, "%s\n", odi.media_url);
        } else {
-               fprintf(stdout, "OD ID %d\n", odi.od->objectDescriptorID);
+               fprintf(stderr, "OD ID %d\n", odi.od->objectDescriptorID);
        }
 
        szIndent[indent]=' ';
@@ -1820,16 +1866,16 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind
                                PrintODList(term, odm, num, indent, "EXTERNPROTO Library");
                                break;
                        default:
-                               fprintf(stdout, "%s", szIndent);
-                               fprintf(stdout, "#%d - ", num);
+                               fprintf(stderr, "%s", szIndent);
+                               fprintf(stderr, "#%d - ", num);
                                if (odi.media_url) {
-                                       fprintf(stdout, "%s", odi.media_url);
+                                       fprintf(stderr, "%s", odi.media_url);
                                } else {
-                                       fprintf(stdout, "ID %d", odi.od->objectDescriptorID);
+                                       fprintf(stderr, "ID %d", odi.od->objectDescriptorID);
                                }
-                               fprintf(stdout, " - %s", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems");
-                               if (odi.od && odi.od->ServiceID) fprintf(stdout, " - Service ID %d", odi.od->ServiceID);
-                               fprintf(stdout, "\n");
+                               fprintf(stderr, " - %s", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems");
+                               if (odi.od && odi.od->ServiceID) fprintf(stderr, " - Service ID %d", odi.od->ServiceID);
+                               fprintf(stderr, "\n");
                                break;
                        }
                }
@@ -1863,70 +1909,70 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number)
                }
        }
        if (!odm) {
-               if (number == (u32)-1) fprintf(stdout, "cannot find OD with ID %d\n", OD_ID);
-               else fprintf(stdout, "cannot find OD with number %d\n", number);
+               if (number == (u32)-1) fprintf(stderr, "cannot find OD with ID %d\n", OD_ID);
+               else fprintf(stderr, "cannot find OD with number %d\n", number);
                return;
        }
        if (!odi.od) {
-               if (number == (u32)-1) fprintf(stdout, "Object %d not attached yet\n", OD_ID);
-               else fprintf(stdout, "Object #%d not attached yet\n", number);          
+               if (number == (u32)-1) fprintf(stderr, "Object %d not attached yet\n", OD_ID);
+               else fprintf(stderr, "Object #%d not attached yet\n", number);          
                return;
        }
 
        if (!odi.od) {
-               fprintf(stdout, "Service not attached\n");
+               fprintf(stderr, "Service not attached\n");
                return;
        }
 
        if (odi.od->tag==GF_ODF_IOD_TAG) {
-               fprintf(stdout, "InitialObjectDescriptor %d\n", odi.od->objectDescriptorID);
-               fprintf(stdout, "Profiles and Levels: Scene %x - Graphics %x - Visual %x - Audio %x - OD %x\n", 
+               fprintf(stderr, "InitialObjectDescriptor %d\n", odi.od->objectDescriptorID);
+               fprintf(stderr, "Profiles and Levels: Scene %x - Graphics %x - Visual %x - Audio %x - OD %x\n", 
                        odi.scene_pl, odi.graphics_pl, odi.visual_pl, odi.audio_pl, odi.OD_pl);
-               fprintf(stdout, "Inline Profile Flag %d\n", odi.inline_pl);
+               fprintf(stderr, "Inline Profile Flag %d\n", odi.inline_pl);
        } else {
-               fprintf(stdout, "ObjectDescriptor %d\n", odi.od->objectDescriptorID);
+               fprintf(stderr, "ObjectDescriptor %d\n", odi.od->objectDescriptorID);
        }
 
-       fprintf(stdout, "Object Duration: ");
+       fprintf(stderr, "Object Duration: ");
        if (odi.duration) {
          PrintTime((u32) (odi.duration*1000));
        } else {
-         fprintf(stdout, "unknown");
+         fprintf(stderr, "unknown");
        }
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
 
        if (odi.owns_service) {
-               fprintf(stdout, "Service Handler: %s\n", odi.service_handler);
-               fprintf(stdout, "Service URL: %s\n", odi.service_url);
+               fprintf(stderr, "Service Handler: %s\n", odi.service_handler);
+               fprintf(stderr, "Service URL: %s\n", odi.service_url);
        }               
        if (odi.codec_name) {
                Float avg_dec_time;
                switch (odi.od_type) {
                case GF_STREAM_VISUAL:
-                       fprintf(stdout, "Video Object: Width %d - Height %d\r\n", odi.width, odi.height);
-                       fprintf(stdout, "Media Codec: %s\n", odi.codec_name);
-                       if (odi.par) fprintf(stdout, "Pixel Aspect Ratio: %d:%d\n", (odi.par>>16)&0xFF, (odi.par)&0xFF);
+                       fprintf(stderr, "Video Object: Width %d - Height %d\r\n", odi.width, odi.height);
+                       fprintf(stderr, "Media Codec: %s\n", odi.codec_name);
+                       if (odi.par) fprintf(stderr, "Pixel Aspect Ratio: %d:%d\n", (odi.par>>16)&0xFF, (odi.par)&0xFF);
                        break;
                case GF_STREAM_AUDIO:
-                       fprintf(stdout, "Audio Object: Sample Rate %d - %d channels\r\n", odi.sample_rate, odi.num_channels);
-                       fprintf(stdout, "Media Codec: %s\n", odi.codec_name);
+                       fprintf(stderr, "Audio Object: Sample Rate %d - %d channels\r\n", odi.sample_rate, odi.num_channels);
+                       fprintf(stderr, "Media Codec: %s\n", odi.codec_name);
                        break;
                case GF_STREAM_SCENE:
                case GF_STREAM_PRIVATE_SCENE:
                        if (odi.width && odi.height) {
-                               fprintf(stdout, "Scene Description - Width %d - Height %d\n", odi.width, odi.height);
+                               fprintf(stderr, "Scene Description - Width %d - Height %d\n", odi.width, odi.height);
                        } else {
-                               fprintf(stdout, "Scene Description - no size specified\n");
+                               fprintf(stderr, "Scene Description - no size specified\n");
                        }
-                       fprintf(stdout, "Scene Codec: %s\n", odi.codec_name);
+                       fprintf(stderr, "Scene Codec: %s\n", odi.codec_name);
                        break;
                case GF_STREAM_TEXT:
                        if (odi.width && odi.height) {
-                               fprintf(stdout, "Text Object: Width %d - Height %d\n", odi.width, odi.height);
+                               fprintf(stderr, "Text Object: Width %d - Height %d\n", odi.width, odi.height);
                        } else {
-                               fprintf(stdout, "Text Object: No size specified\n");
+                               fprintf(stderr, "Text Object: No size specified\n");
                        }
-                       fprintf(stdout, "Text Codec %s\n", odi.codec_name);
+                       fprintf(stderr, "Text Codec %s\n", odi.codec_name);
                        break;
                }
        
@@ -1935,65 +1981,65 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number)
                        avg_dec_time = (Float) odi.total_dec_time; 
                        avg_dec_time /= odi.nb_dec_frames; 
                }
-               fprintf(stdout, "\tBitrate over last second: %d kbps\n\tMax bitrate over one second: %d kbps\n\tAverage Decoding Time %.2f ms (%d max)\n\tTotal decoded frames %d\n", 
+               fprintf(stderr, "\tBitrate over last second: %d kbps\n\tMax bitrate over one second: %d kbps\n\tAverage Decoding Time %.2f ms (%d max)\n\tTotal decoded frames %d\n", 
                        (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time, odi.nb_dec_frames);
        }
-       if (odi.protection) fprintf(stdout, "Encrypted Media%s\n", (odi.protection==2) ? " NOT UNLOCKED" : "");
+       if (odi.protection) fprintf(stderr, "Encrypted Media%s\n", (odi.protection==2) ? " NOT UNLOCKED" : "");
 
        count = gf_list_count(odi.od->ESDescriptors);
-       fprintf(stdout, "%d streams in OD\n", count);
+       fprintf(stderr, "%d streams in OD\n", count);
        for (i=0; i<count; i++) {
                GF_ESD *esd = (GF_ESD *) gf_list_get(odi.od->ESDescriptors, i);
 
-               fprintf(stdout, "\nStream ID %d - Clock ID %d\n", esd->ESID, esd->OCRESID);
-               if (esd->dependsOnESID) fprintf(stdout, "\tDepends on Stream ID %d for decoding\n", esd->dependsOnESID);
+               fprintf(stderr, "\nStream ID %d - Clock ID %d\n", esd->ESID, esd->OCRESID);
+               if (esd->dependsOnESID) fprintf(stderr, "\tDepends on Stream ID %d for decoding\n", esd->dependsOnESID);
 
                switch (esd->decoderConfig->streamType) {
                case GF_STREAM_OD:
-                       fprintf(stdout, "\tOD Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tOD Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_OCR:
-                       fprintf(stdout, "\tOCR Stream\n");
+                       fprintf(stderr, "\tOCR Stream\n");
                        break;
                case GF_STREAM_SCENE:
-                       fprintf(stdout, "\tScene Description Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tScene Description Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_VISUAL:
-                       fprintf(stdout, "\tVisual Stream - media type: %s", gf_esd_get_textual_description(esd));
+                       fprintf(stderr, "\tVisual Stream - media type: %s", gf_esd_get_textual_description(esd));
                        break;
                case GF_STREAM_AUDIO:
-                       fprintf(stdout, "\tAudio Stream - media type: %s", gf_esd_get_textual_description(esd));
+                       fprintf(stderr, "\tAudio Stream - media type: %s", gf_esd_get_textual_description(esd));
                        break;
                case GF_STREAM_MPEG7:
-                       fprintf(stdout, "\tMPEG-7 Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tMPEG-7 Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_IPMP:
-                       fprintf(stdout, "\tIPMP Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tIPMP Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_OCI:
-                       fprintf(stdout, "\tOCI Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tOCI Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_MPEGJ:
-                       fprintf(stdout, "\tMPEGJ Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tMPEGJ Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_INTERACT:
-                       fprintf(stdout, "\tUser Interaction Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tUser Interaction Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                case GF_STREAM_TEXT:
-                       fprintf(stdout, "\tStreaming Text Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
+                       fprintf(stderr, "\tStreaming Text Stream - version %d\n", esd->decoderConfig->objectTypeIndication);
                        break;
                default:
-                       fprintf(stdout, "\tUnknown Stream\n");
+                       fprintf(stderr, "\tUnknown Stream\n");
                        break;
                }
 
-               fprintf(stdout, "\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate);
+               fprintf(stderr, "\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate);
                if (esd->slConfig->predefined==SLPredef_SkipSL) {
-                       fprintf(stdout, "\tNot using MPEG-4 Synchronization Layer\n");
+                       fprintf(stderr, "\tNot using MPEG-4 Synchronization Layer\n");
                } else {
-                       fprintf(stdout, "\tStream Clock Resolution %d\n", esd->slConfig->timestampResolution);
+                       fprintf(stderr, "\tStream Clock Resolution %d\n", esd->slConfig->timestampResolution);
                }
-               if (esd->URLString) fprintf(stdout, "\tStream Location: %s\n", esd->URLString);
+               if (esd->URLString) fprintf(stderr, "\tStream Location: %s\n", esd->URLString);
 
                /*check language*/
                if (esd->langDesc) {
@@ -2015,31 +2061,31 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number)
                                        i+=3;
                                }
                        }
-                       fprintf(stdout, "\tStream Language: %s\n", szLang);
+                       fprintf(stderr, "\tStream Language: %s\n", szLang);
                }
        }
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
        /*check OCI (not everything interests us) - FIXME: support for unicode*/
        count = gf_list_count(odi.od->OCIDescriptors);
        if (count) {
-               fprintf(stdout, "%d Object Content Information descriptors in OD\n", count);
+               fprintf(stderr, "%d Object Content Information descriptors in OD\n", count);
                for (i=0; i<count; i++) {
                        GF_Descriptor *desc = (GF_Descriptor *) gf_list_get(odi.od->OCIDescriptors, i);
                        switch (desc->tag) {
                        case GF_ODF_SEGMENT_TAG:
                        {
                                GF_Segment *sd = (GF_Segment *) desc;
-                               fprintf(stdout, "Segment Descriptor: Name: %s - start time %g sec - duration %g sec\n", sd->SegmentName, sd->startTime, sd->Duration);
+                               fprintf(stderr, "Segment Descriptor: Name: %s - start time %g sec - duration %g sec\n", sd->SegmentName, sd->startTime, sd->Duration);
                        }
                                break;
                        case GF_ODF_CC_NAME_TAG:
                        {
                                GF_CC_Name *ccn = (GF_CC_Name *)desc;
-                               fprintf(stdout, "Content Creators:\n");
+                               fprintf(stderr, "Content Creators:\n");
                                for (j=0; j<gf_list_count(ccn->ContentCreators); j++) {
                                        GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j);
                                        if (!ci->isUTF8) continue;
-                                       fprintf(stdout, "\t%s\n", ci->contentCreatorName);
+                                       fprintf(stderr, "\t%s\n", ci->contentCreatorName);
                                }
                        }
                                break;
@@ -2047,69 +2093,69 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number)
                        case GF_ODF_SHORT_TEXT_TAG:
                                {
                                        GF_ShortTextual *std = (GF_ShortTextual *)desc;
-                                       fprintf(stdout, "Description:\n\tEvent: %s\n\t%s\n", std->eventName, std->eventText);
+                                       fprintf(stderr, "Description:\n\tEvent: %s\n\t%s\n", std->eventName, std->eventText);
                                }
                                break;
                        default:
                                break;
                        }
                }
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
        }
 
        switch (odi.status) {
-       case 0: fprintf(stdout, "Stopped - "); break;
-       case 1: fprintf(stdout, "Playing - "); break;
-       case 2: fprintf(stdout, "Paused - "); break;
-       case 3: fprintf(stdout, "Not setup yet\n"); return;
-       default: fprintf(stdout, "Setup Failed\n"); return;
-       }
-       if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer);
-       else fprintf(stdout, "Not buffering - ");
-       fprintf(stdout, "Clock drift: %d ms\n", odi.clock_drift);
-       if (odi.db_unit_count) fprintf(stdout, "%d AU in DB\n", odi.db_unit_count);
-       if (odi.cb_max_count) fprintf(stdout, "Composition Buffer: %d CU (%d max)\n", odi.cb_unit_count, odi.cb_max_count);
-       fprintf(stdout, "\n");
+       case 0: fprintf(stderr, "Stopped - "); break;
+       case 1: fprintf(stderr, "Playing - "); break;
+       case 2: fprintf(stderr, "Paused - "); break;
+       case 3: fprintf(stderr, "Not setup yet\n"); return;
+       default: fprintf(stderr, "Setup Failed\n"); return;
+       }
+       if (odi.buffer>=0) fprintf(stderr, "Buffer: %d ms - ", odi.buffer);
+       else fprintf(stderr, "Not buffering - ");
+       fprintf(stderr, "Clock drift: %d ms\n", odi.clock_drift);
+       if (odi.db_unit_count) fprintf(stderr, "%d AU in DB\n", odi.db_unit_count);
+       if (odi.cb_max_count) fprintf(stderr, "Composition Buffer: %d CU (%d max)\n", odi.cb_unit_count, odi.cb_max_count);
+       fprintf(stderr, "\n");
 
        if (odi.owns_service) {
                const char *url;
                u32 done, total, bps;
                d_enum = 0;
                while (gf_term_get_download_info(term, odm, &d_enum, &url, NULL, &done, &total, &bps)) {
-                       if (d_enum==1) fprintf(stdout, "Current Downloads in service:\n");
+                       if (d_enum==1) fprintf(stderr, "Current Downloads in service:\n");
                        if (done && total) {
-                               fprintf(stdout, "%s: %d / %d bytes (%.2f %%) - %.2f kBps\n", url, done, total, (100.0f*done)/total, ((Float)bps)/1024.0f);
+                               fprintf(stderr, "%s: %d / %d bytes (%.2f %%) - %.2f kBps\n", url, done, total, (100.0f*done)/total, ((Float)bps)/1024.0f);
                        } else {
-                               fprintf(stdout, "%s: %.2f kbps\n", url, ((Float)8*bps)/1024.0f);
+                               fprintf(stderr, "%s: %.2f kbps\n", url, ((Float)8*bps)/1024.0f);
                        }
                }
-               if (!d_enum) fprintf(stdout, "No Downloads in service\n");
-               fprintf(stdout, "\n");
+               if (!d_enum) fprintf(stderr, "No Downloads in service\n");
+               fprintf(stderr, "\n");
        }
        d_enum = 0;
        while (gf_term_get_channel_net_info(term, odm, &d_enum, &id, &com, &e)) {
                if (e) continue;
                if (!com.bw_down && !com.bw_up) continue;
 
-               fprintf(stdout, "Stream ID %d statistics:\n", id);
+               fprintf(stderr, "Stream ID %d statistics:\n", id);
                if (com.multiplex_port) {
-                       fprintf(stdout, "\tMultiplex Port %d - multiplex ID %d\n", com.multiplex_port, com.port);
+                       fprintf(stderr, "\tMultiplex Port %d - multiplex ID %d\n", com.multiplex_port, com.port);
                } else {
-                       fprintf(stdout, "\tPort %d\n", com.port);
+                       fprintf(stderr, "\tPort %d\n", com.port);
                }
-               fprintf(stdout, "\tPacket Loss Percentage: %.4f\n", com.pck_loss_percentage);
-               fprintf(stdout, "\tDown Bandwidth: %d bps\n", com.bw_down);
-               if (com.bw_up) fprintf(stdout, "\tUp Bandwidth: %d bps\n", com.bw_up);
+               fprintf(stderr, "\tPacket Loss Percentage: %.4f\n", com.pck_loss_percentage);
+               fprintf(stderr, "\tDown Bandwidth: %d bps\n", com.bw_down);
+               if (com.bw_up) fprintf(stderr, "\tUp Bandwidth: %d bps\n", com.bw_up);
                if (com.ctrl_port) {
                        if (com.multiplex_port) {
-                               fprintf(stdout, "\tControl Multiplex Port: %d - Control Multiplex ID %d\n", com.multiplex_port, com.ctrl_port);
+                               fprintf(stderr, "\tControl Multiplex Port: %d - Control Multiplex ID %d\n", com.multiplex_port, com.ctrl_port);
                        } else {
-                               fprintf(stdout, "\tControl Port: %d\n", com.ctrl_port);
+                               fprintf(stderr, "\tControl Port: %d\n", com.ctrl_port);
                        }
-                       fprintf(stdout, "\tDown Bandwidth: %d bps\n", com.ctrl_bw_down);
-                       fprintf(stdout, "\tUp Bandwidth: %d bps\n", com.ctrl_bw_up);
+                       fprintf(stderr, "\tDown Bandwidth: %d bps\n", com.ctrl_bw_down);
+                       fprintf(stderr, "\tUp Bandwidth: %d bps\n", com.ctrl_bw_up);
                }
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
        }
 }
 
@@ -2120,22 +2166,22 @@ void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm)
 
        if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return;
        if (!odi.od) {
-               fprintf(stdout, "Service not attached\n");
+               fprintf(stderr, "Service not attached\n");
                return;
        }
 
-       fprintf(stdout, "OD %d: ", odi.od->objectDescriptorID);
+       fprintf(stderr, "OD %d: ", odi.od->objectDescriptorID);
        switch (odi.status) {
-       case 1: fprintf(stdout, "Playing - "); break;
-       case 2: fprintf(stdout, "Paused - "); break;
-       default: fprintf(stdout, "Stopped - "); break;
-       }
-       if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer);
-       else fprintf(stdout, "Not buffering - ");
-       fprintf(stdout, "Clock drift: %d ms", odi.clock_drift);
-       fprintf(stdout, " - time: ");
+       case 1: fprintf(stderr, "Playing - "); break;
+       case 2: fprintf(stderr, "Paused - "); break;
+       default: fprintf(stderr, "Stopped - "); break;
+       }
+       if (odi.buffer>=0) fprintf(stderr, "Buffer: %d ms - ", odi.buffer);
+       else fprintf(stderr, "Not buffering - ");
+       fprintf(stderr, "Clock drift: %d ms", odi.clock_drift);
+       fprintf(stderr, " - time: ");
        PrintTime((u32) (odi.current_time*1000));
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
 }
 
 void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm)
@@ -2146,24 +2192,24 @@ void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm)
 
        if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return;
        if (!odi.od) {
-               fprintf(stdout, "Service not attached\n");
+               fprintf(stderr, "Service not attached\n");
                return;
        }
 
-       fprintf(stdout, "OD %d: ", odi.od->objectDescriptorID);
+       fprintf(stderr, "OD %d: ", odi.od->objectDescriptorID);
        switch (odi.status) {
-       case 1: fprintf(stdout, "Playing"); break;
-       case 2: fprintf(stdout, "Paused"); break;
-       default: fprintf(stdout, "Stopped"); break;
+       case 1: fprintf(stderr, "Playing"); break;
+       case 2: fprintf(stderr, "Paused"); break;
+       default: fprintf(stderr, "Stopped"); break;
        }
-       if (odi.buffer>=0) fprintf(stdout, " - Buffer: %d ms", odi.buffer);
-       if (odi.db_unit_count) fprintf(stdout, " - DB: %d AU", odi.db_unit_count);
-       if (odi.cb_max_count) fprintf(stdout, " - CB: %d/%d CUs", odi.cb_unit_count, odi.cb_max_count);
+       if (odi.buffer>=0) fprintf(stderr, " - Buffer: %d ms", odi.buffer);
+       if (odi.db_unit_count) fprintf(stderr, " - DB: %d AU", odi.db_unit_count);
+       if (odi.cb_max_count) fprintf(stderr, " - CB: %d/%d CUs", odi.cb_unit_count, odi.cb_max_count);
        
-       fprintf(stdout, "\n * %d decoded frames - %d dropped frames\n", odi.nb_dec_frames, odi.nb_droped);
+       fprintf(stderr, "\n * %d decoded frames - %d dropped frames\n", odi.nb_dec_frames, odi.nb_droped);
        avg_dec_time = 0;
        if (odi.nb_dec_frames) { avg_dec_time = (Float) odi.total_dec_time; avg_dec_time /= odi.nb_dec_frames; }
-       fprintf(stdout, " * Avg Bitrate %d kbps (%d max) - Avg Decoding Time %.2f ms (%d max)\n",
+       fprintf(stderr, " * Avg Bitrate %d kbps (%d max) - Avg Decoding Time %.2f ms (%d max)\n",
                                                                (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time);
 }
 
@@ -2187,7 +2233,7 @@ void ViewODs(GF_Terminal *term, Bool show_timing)
                        PrintODBuffer(term, odm);
                }
        }
-       fprintf(stdout, "\n");
+       fprintf(stderr, "\n");
 }
 
 
@@ -2197,14 +2243,14 @@ void PrintGPACConfig()
        char szName[200];
        char *secName = NULL;
 
-       fprintf(stdout, "Enter section name (\"*\" for complete dump):\n");
+       fprintf(stderr, "Enter section name (\"*\" for complete dump):\n");
        if (1 > scanf("%s", szName)){
            fprintf(stderr, "No section name, aborting.\n");
            return;
        }
        if (strcmp(szName, "*")) secName = szName;
 
-       fprintf(stdout, "\n\n*** GPAC Configuration ***\n\n");
+       fprintf(stderr, "\n\n*** GPAC Configuration ***\n\n");
 
        cfg_count = gf_cfg_get_section_count(cfg_file);
        for (i=0; i<cfg_count; i++) {
@@ -2216,14 +2262,14 @@ void PrintGPACConfig()
                        if (!stricmp(sec, "MimeTypes")) continue;
                        if (!stricmp(sec, "RecentFiles")) continue;
                }
-               fprintf(stdout, "[%s]\n", sec);
+               fprintf(stderr, "[%s]\n", sec);
                key_count = gf_cfg_get_key_count(cfg_file, sec);
                for (j=0; j<key_count; j++) {
                        const char *key = gf_cfg_get_key_name(cfg_file, sec, j);
                        const char *val = gf_cfg_get_key(cfg_file, sec, key);
-                       fprintf(stdout, "%s=%s\n", key, val);
+                       fprintf(stderr, "%s=%s\n", key, val);
                }
-               fprintf(stdout, "\n");
+               fprintf(stderr, "\n");
        }
 }
 
index 2bc1e0ee8e0887838eb77838101f866900f22523..eaf7bd45a7c6dae0fa4c4a5a6844f12ed5e0de02 100644 (file)
@@ -28,10 +28,6 @@ all: broadcaster
 broadcaster: $(OBJS) *.h
        $(CC) $(LDFLAGS) -o $(APPNAME) $(OBJS) $(LINKFLAG)
 
-.c.o:
-       $(CC) -Wall -g -c $(CFLAGS) $*.c
-
-
 clean:
        -rm -f $(OBJS) $(APPNAME) *~
 
index 7650492bc712b80f0140b5382c753a0490d149f0..7a95d5fad1d3e3ecc48c4cef3563e12a30e0ef45 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DMB application
index a71b3756f12b05292ab0d65828077b18e733cd64..8241c095b57732ac72e33130a4ee61b146e3e8de 100644 (file)
@@ -40,11 +40,6 @@ all: $(PROG)
 $(PROG): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../../bin/gcc/$@ $(OBJS) $(LINKFLAGS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../../bin/gcc/$(PROG)
 
index 896cf981b13ec8ba27b1ab2004f84dc58b3fa58d..f57f2dc8128684885c8f1dce3043f0375aacb33f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2000-2006
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / load&compare application
index 464f26d9aae2cc7ad4d82cbd07af12e043567f4d..315079eb449301d79fa27c813bf5cee1116ca61e 100644 (file)
@@ -50,11 +50,6 @@ LIBGPAC:
 $(PROG): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../../bin/gcc/$@ $(OBJS) $(LINKFLAGS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../../bin/gcc/$(PROG)
 
index c6bc6923f7502d9314c77792e1793fa9306143ea..f8ac67c2f7a5759c4144cd643e0b42a373bfa81e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2007-200X
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mpedemux application
index ef3a048e2d4ef8332bf5660eb81e9748de84d312..e8243686ce51256cef128f610f850427b48eb9d3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2000-200X
+ *                     Authors: Cyril COncolato
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / svg2bifs application
diff --git a/applications/ts2hds/Makefile b/applications/ts2hds/Makefile
new file mode 100644 (file)
index 0000000..675572d
--- /dev/null
@@ -0,0 +1,56 @@
+include ../../config.mak\r
+\r
+vpath %.c $(SRC_PATH)/applications/ts2hds\r
+\r
+CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include"\r
+\r
+ifeq ($(DEBUGBUILD), yes)\r
+CFLAGS+=-g\r
+LDFLAGS+=-g\r
+endif\r
+\r
+ifeq ($(GPROFBUILD), yes)\r
+CFLAGS+=-pg\r
+LDFLAGS+=-pg\r
+endif\r
+\r
+#common obj\r
+OBJS= main.o f4v.o f4m.o\r
+\r
+LINKFLAGS=-L../../bin/gcc\r
+ifeq ($(CONFIG_WIN32),yes)\r
+EXE=.exe\r
+PROG=ts2hds$(EXE)\r
+else\r
+EXT=\r
+PROG=ts2hds\r
+endif\r
+LINKFLAGS+=-lgpac\r
+\r
+\r
+SRCS := $(OBJS:.o=.c) \r
+\r
+all: $(PROG)\r
+\r
+$(PROG): $(OBJS)\r
+       $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS)\r
+\r
+clean: \r
+       rm -f $(OBJS) ../../bin/gcc/$(PROG)\r
+\r
+dep: depend\r
+\r
+depend:\r
+       rm -f .depend   \r
+       $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend\r
+\r
+distclean: clean\r
+       rm -f Makefile.bak .depend\r
+\r
+\r
+\r
+# include dependency files if they exist\r
+#\r
+ifneq ($(wildcard .depend),)\r
+include .depend\r
+endif\r
diff --git a/applications/ts2hds/f4m.c b/applications/ts2hds/f4m.c
new file mode 100644 (file)
index 0000000..b09aa49
--- /dev/null
@@ -0,0 +1,141 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Author: Romain Bouqueau\r
+ *                     Copyright (c) Romain Bouqueau 2012-\r
+ *                             All rights reserved\r
+ *\r
+ *          Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com)\r
+ *\r
+ *  This file is part of GPAC / TS to HDS (ts2hds) application\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#include "ts2hds.h"\r
+\r
+#include <gpac/base_coding.h>\r
+\r
+#define ADOBE_INLINED_BOOTSTRAP\r
+\r
+struct __tag_adobe_stream\r
+{\r
+       FILE *f;\r
+       const char *id;\r
+       const char *base_url;\r
+       u32 bitrate;\r
+};\r
+\r
+struct __tag_adobe_multirate\r
+{\r
+       FILE *f;\r
+       const char *id;\r
+       const char *base_url;\r
+       GF_List *streams;\r
+};\r
+\r
+AdobeMultirate *adobe_alloc_multirate_manifest(char *id)\r
+{\r
+       AdobeMultirate *am = gf_calloc(1, sizeof(AdobeMultirate));\r
+       char filename[GF_MAX_PATH];\r
+\r
+       //default init\r
+       am->base_url = "http://localhost/hds/tmp";\r
+       am->id = id;\r
+       sprintf(filename, "%s.f4m", am->id);\r
+       am->f = fopen(filename, "wt");\r
+       if (!am->f) {\r
+               fprintf(stderr, "Couldn't create Adobe multirate manifest file: %s\n", filename);\r
+               assert(0);\r
+               gf_free(am);\r
+               return NULL;\r
+       }\r
+       am->streams = gf_list_new();\r
+\r
+       //create a fake stream\r
+       {\r
+               AdobeStream *as = gf_calloc(1, sizeof(AdobeStream));\r
+               as->id = "HD";\r
+               as->bitrate = 100;\r
+               gf_list_add(am->streams, as);\r
+       }\r
+\r
+       return am;\r
+}\r
+\r
+void adobe_free_multirate_manifest(AdobeMultirate *am)\r
+{\r
+       u32 i;\r
+\r
+       if (am->f)\r
+               fclose(am->f);\r
+\r
+       for (i=0; i<gf_list_count(am->streams); i++) {\r
+               AdobeStream *as = gf_list_get(am->streams, i);\r
+               assert(as);\r
+               //TODO: base_url and id may be stored as gf_strdup in the future\r
+               gf_list_rem(am->streams, i);\r
+               gf_free(as);\r
+       }\r
+       gf_list_del(am->streams);\r
+\r
+       gf_free(am);\r
+}\r
+\r
+GF_Err adobe_gen_multirate_manifest(AdobeMultirate* am, char *bootstrap, size_t bootstrap_size)\r
+{\r
+       u32 i;\r
+#ifdef ADOBE_INLINED_BOOTSTRAP\r
+       char bootstrap64[GF_MAX_PATH];\r
+       u32 bootstrap64_len;\r
+#endif\r
+\r
+       fprintf(am->f, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");\r
+       fprintf(am->f, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");\r
+       fprintf(am->f, "<id>%s</id>\n", am->id);\r
+       fprintf(am->f, "<baseURL>%s</baseURL>\n", am->base_url);\r
+    fprintf(am->f, "<streamType>live</streamType>\n");\r
+\r
+       assert(am->streams);\r
+       for (i=0; i<gf_list_count(am->streams); i++) {\r
+               AdobeStream *as = gf_list_get(am->streams, i);\r
+               assert(as);\r
+#ifdef ADOBE_INLINED_BOOTSTRAP\r
+               fprintf(am->f, "<bootstrapInfo profile=\"named\" id=\"boot_%s_%d\">\n", as->id, as->bitrate);\r
+               bootstrap64_len = gf_base64_encode(bootstrap, bootstrap_size, bootstrap64, GF_MAX_PATH);\r
+               fwrite(bootstrap64, bootstrap64_len, 1, am->f);\r
+               if (bootstrap64_len >= GF_MAX_PATH) {\r
+                       fprintf(stderr, "Bootstrap may have been truncated for stream %s_%d.\n", as->id, as->bitrate);\r
+                       assert(0);\r
+               }\r
+               fprintf(am->f, "\n</bootstrapInfo>\n");\r
+#else\r
+               fprintf(am->f, "<bootstrapInfo profile=\"named\" id=\"boot_%s_%d\" url=\"%s_%d.bootstrap\"/>\n", as->id, as->bitrate, as->id, as->bitrate);\r
+               {\r
+                       char filename[GF_MAX_PATH];\r
+                       FILE *bstfile;\r
+                       sprintf(filename, "%s_%d.bootstrap", as->id, as->bitrate);\r
+                       bstfile = fopen(filename, "wb");\r
+                       gf_fwrite(bootstrap, bootstrap_size, 1, bstfile);\r
+                       fclose(bstfile);\r
+               }\r
+#endif\r
+               fprintf(am->f, "<media url=\"%s_%s_%d_\" bitrate=\"%d\" bootstrapInfoId=\"boot_%s_%d\"/>\n", am->id, as->id, as->bitrate, as->bitrate, as->id, as->bitrate);\r
+       }\r
+       fprintf(am->f, "</manifest>\n");\r
+\r
+       return GF_OK;\r
+}\r
diff --git a/applications/ts2hds/f4v.c b/applications/ts2hds/f4v.c
new file mode 100644 (file)
index 0000000..f49284b
--- /dev/null
@@ -0,0 +1,185 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Author: Romain Bouqueau\r
+ *                     Copyright (c) Romain Bouqueau 2012-\r
+ *                             All rights reserved\r
+ *\r
+ *          Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com)\r
+ *\r
+ *  This file is part of GPAC / TS to HDS (ts2hds) application\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#include "ts2hds.h"\r
+\r
+//we need to write Adobe custom boxes\r
+#include <gpac/internal/isomedia_dev.h>\r
+\r
+GF_Err adobize_segment(GF_ISOFile *isom_file, AdobeHDSCtx *ctx)\r
+{\r
+       GF_Err e;\r
+       GF_BitStream *bs;\r
+\r
+       GF_AdobeFragRandomAccessBox *afra = (GF_AdobeFragRandomAccessBox*)      afra_New();\r
+       GF_AfraEntry *ae                  = (GF_AfraEntry*)                                     gf_calloc(1, sizeof(GF_AfraEntry));\r
+       GF_AdobeBootstrapInfoBox *abst    = (GF_AdobeBootstrapInfoBox*)         abst_New();\r
+       GF_AdobeSegmentRunTableBox *asrt  = (GF_AdobeSegmentRunTableBox*)       asrt_New();\r
+       GF_AdobeSegmentRunEntry *asre     = (GF_AdobeSegmentRunEntry*)          gf_calloc(1, sizeof(GF_AdobeSegmentRunEntry));\r
+       GF_AdobeFragmentRunTableBox *afrt = (GF_AdobeFragmentRunTableBox*)      afrt_New();\r
+       GF_AdobeFragmentRunEntry *afre    = (GF_AdobeFragmentRunEntry*)         gf_calloc(1, sizeof(GF_AdobeFragmentRunEntry));\r
+\r
+       u64 init_seg_time = ctx->curr_time;\r
+       u32 seg_duration = (u32)gf_isom_get_duration(isom_file);\r
+\r
+       //update context\r
+       ctx->curr_time += seg_duration;\r
+\r
+       //Adobe specific boxes\r
+       //Random Access\r
+       afra->type = GF_4CC('a', 'f', 'r', 'a');\r
+       afra->version = 0;\r
+       afra->flags = 0;\r
+       afra->long_ids = 1;\r
+       afra->long_offsets = 1;\r
+       afra->global_entries = 0;\r
+       afra->time_scale = gf_isom_get_timescale(isom_file);\r
+\r
+       afra->entry_count = 1;\r
+       ae->time = init_seg_time;\r
+       ae->offset = 31663;\r
+       gf_list_add(afra->local_access_entries, ae);\r
+\r
+       afra->global_entries = 0;\r
+       afra->global_entry_count = 0;\r
+\r
+       e = gf_list_add(isom_file->TopBoxes, afra);\r
+       if (e) {\r
+               fprintf(stderr, "Impossible to write AFRA box: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               return e;\r
+       }\r
+\r
+       //Bootstrap Info\r
+       abst->type = GF_4CC('a', 'b', 's', 't');\r
+       abst->version = 0;\r
+       abst->flags = 0;\r
+       abst->bootstrapinfo_version = 1;\r
+       abst->profile = 0;\r
+       abst->live = 1;\r
+       abst->update = 0;\r
+       abst->time_scale = gf_isom_get_timescale(isom_file);\r
+       abst->current_media_time = init_seg_time+seg_duration;\r
+       abst->smpte_time_code_offset = 0;\r
+\r
+       abst->movie_identifier = NULL;\r
+       abst->drm_data = NULL;\r
+       abst->meta_data = NULL;\r
+\r
+       abst->server_entry_count = 0;\r
+       abst->quality_entry_count = 0;\r
+\r
+       abst->segment_run_table_count = 1;\r
+       {\r
+               //Segment Run\r
+               asrt->type = GF_4CC('a', 's', 'r', 't');\r
+               asrt->version = 0;\r
+               asrt->flags = 0;\r
+               asrt->segment_run_entry_count = 1;\r
+               {\r
+                       asre->first_segment = 1;\r
+                       asre->fragment_per_segment = 1;\r
+               }\r
+               e = gf_list_add(asrt->segment_run_entry_table, asre);\r
+               if (e) {\r
+                       fprintf(stderr, "Impossible to write ASR Entry: %s\n", gf_error_to_string(e));\r
+                       assert(0);\r
+                       return e;\r
+               }\r
+       }\r
+       e = gf_list_add(abst->segment_run_table_entries, asrt);\r
+       if (e) {\r
+               fprintf(stderr, "Impossible to write ASRT box: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               return e;\r
+       }\r
+\r
+       abst->fragment_run_table_count = 1;\r
+       {\r
+               //Fragment Run\r
+               afrt->type = GF_4CC('a', 'f', 'r', 't');\r
+               afrt->version = 0;\r
+               afrt->flags = 0;\r
+               afrt->timescale = 1000;\r
+               afrt->fragment_run_entry_count = 1;\r
+               {\r
+                       afre->first_fragment = 1;\r
+                       afre->first_fragment_timestamp = 0;\r
+                       afre->fragment_duration = seg_duration;\r
+               }\r
+               e = gf_list_add(afrt->fragment_run_entry_table, afre);\r
+               if (e) {\r
+                       fprintf(stderr, "Impossible to write AFR Entry: %s\n", gf_error_to_string(e));\r
+                       assert(0);\r
+                       return e;\r
+               }\r
+       }\r
+       e = gf_list_add(abst->fragment_run_table_entries, afrt);\r
+       if (e) {\r
+               fprintf(stderr, "Impossible to write AFRT box: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               return e;\r
+       }\r
+\r
+       e = gf_list_add(isom_file->TopBoxes, abst);\r
+       if (e) {\r
+               fprintf(stderr, "Impossible to write ABST box: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               return e;\r
+       }\r
+\r
+       e = abst_Size((GF_Box*)abst);\r
+       if (e) {\r
+               fprintf(stderr, "Impossible to compute ABST box size: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               return e;\r
+       }\r
+       ctx->bootstrap_size = (size_t)abst->size;\r
+       ctx->bootstrap = gf_malloc(ctx->bootstrap_size);\r
+       bs = gf_bs_new(ctx->bootstrap, ctx->bootstrap_size, GF_BITSTREAM_WRITE);\r
+       e = abst_Write((GF_Box*)abst, bs);\r
+       if (e) {\r
+               fprintf(stderr, "Impossible to code the ABST box: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               gf_bs_del(bs);\r
+               return e;\r
+       }\r
+       gf_bs_del(bs);\r
+\r
+       //set brands as reversed engineered from f4v files\r
+       /*e = gf_isom_reset_alt_brands(isom_file);\r
+       if (e) {\r
+               fprintf(stderr, "Warning: couldn't reset ISOM brands: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+       }*/\r
+       gf_isom_set_brand_info(isom_file, GF_4CC('f','4','v',' '), 1);\r
+       gf_isom_modify_alternate_brand(isom_file, GF_4CC('i','s','o','m'), 1);\r
+       gf_isom_modify_alternate_brand(isom_file, GF_4CC('m','p','4','2'), 1);\r
+       gf_isom_modify_alternate_brand(isom_file, GF_4CC('m','4','v',' '), 1);\r
+\r
+       return GF_OK;\r
+}
\ No newline at end of file
diff --git a/applications/ts2hds/main.c b/applications/ts2hds/main.c
new file mode 100644 (file)
index 0000000..0e98a52
--- /dev/null
@@ -0,0 +1,304 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Author: Romain Bouqueau\r
+ *                     Copyright (c) Romain Bouqueau 2012-\r
+ *                             All rights reserved\r
+ *\r
+ *          Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com)\r
+ *\r
+ *  This file is part of GPAC / TS to HDS (ts2hds) application\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#include "ts2hds.h"\r
+\r
+//FIXME: test only\r
+//#include <gpac/internal/isomedia_dev.h>\r
+//#include <gpac/base_coding.h>\r
+\r
+#ifdef WIN32\r
+#define strnicmp _strnicmp\r
+#endif\r
+\r
+#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stderr, "Missing arg - please check usage\n"); exit(1); }\r
+\r
+#ifdef GPAC_DISABLE_ISOM\r
+\r
+#error "Cannot compile TS2HDS if GPAC is not built with ISO File Format support"\r
+\r
+#endif\r
+\r
+\r
+static GFINLINE void usage(const char * progname) \r
+{\r
+       fprintf(stderr, "USAGE: %s -i input -o output\n"\r
+                                       "\n"\r
+#ifdef GPAC_MEMORY_TRACKING\r
+                                       "\t-mem-track:  enables memory tracker\n"\r
+#endif\r
+               );\r
+}\r
+\r
+\r
+/*parse TS2HDS arguments*/\r
+static GFINLINE GF_Err parse_args(int argc, char **argv, char **input, char **output, u64 *curr_time, u32 *segnum)\r
+{\r
+       Bool input_found=0, output_found=0;\r
+       char *arg = NULL, *error_msg = "no argument found";\r
+       s32 i;\r
+\r
+       for (i=1; i<argc; i++) {\r
+               arg = argv[i];\r
+               if (!strnicmp(arg, "-h", 2) || strstr(arg, "-help")) {\r
+                       usage(argv[0]);\r
+                       return GF_EOS;\r
+               } else if (!strnicmp(arg, "-input", 6)) {\r
+                       CHECK_NEXT_ARG\r
+                       *input = argv[++i];\r
+                       input_found = 1;\r
+               } else if (!strnicmp(arg, "-output", 6)) {\r
+                       CHECK_NEXT_ARG\r
+                       *output = argv[++i];\r
+                       output_found = 1;\r
+               } else if (!strnicmp(arg, "-segnum", 6)) {\r
+                       CHECK_NEXT_ARG\r
+                       *segnum = atoi(argv[++i]);\r
+               } else if (!strnicmp(arg, "-mem-track", 10)) {\r
+#ifdef GPAC_MEMORY_TRACKING\r
+                       gf_sys_close();\r
+                       gf_sys_init(1);\r
+                       gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);\r
+#else\r
+                       fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); \r
+#endif\r
+               } else {\r
+                       error_msg = "unknown option \"%s\"";\r
+                       goto error;\r
+               }\r
+       }\r
+\r
+       /*syntax is correct; now testing the presence of mandatory arguments*/\r
+       if (input_found && output_found) {\r
+               return GF_OK;\r
+       } else {\r
+               if (!input_found)\r
+                       fprintf(stderr, "Error: input argument not found\n\n");\r
+               if (!output_found)\r
+                       fprintf(stderr, "Error: output argument not found\n\n");\r
+               return GF_BAD_PARAM;\r
+       }\r
+\r
+error: \r
+       if (!arg) {\r
+               fprintf(stderr, "Error: %s\n\n", error_msg);\r
+       } else {\r
+               fprintf(stderr, "Error: %s \"%s\"\n\n", error_msg, arg);\r
+       }\r
+       return GF_BAD_PARAM;\r
+}\r
+\r
+int main(int argc, char **argv)\r
+{\r
+       /********************/\r
+       /*   declarations   */\r
+       /********************/\r
+       char *input, *output, tmpstr[GF_MAX_PATH];\r
+       GF_ISOFile *isom_file_in, *isom_file_out;\r
+       GF_MediaImporter import;\r
+       AdobeHDSCtx ctx;\r
+       GF_Err e;\r
+       u32 i;\r
+       \r
+       /*****************/\r
+       /*   gpac init   */\r
+       /*****************/\r
+       gf_sys_init(0);\r
+       gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);\r
+       \r
+       /***********************/\r
+       /*   initialisations   */\r
+       /***********************/\r
+       input = NULL;\r
+       output = NULL;\r
+       isom_file_in = NULL;\r
+       isom_file_out = NULL;\r
+       memset(&import, 0, sizeof(GF_MediaImporter));\r
+       e = GF_OK;\r
+       memset(&ctx, 0, sizeof(ctx));\r
+       \r
+       ctx.multirate_manifest = adobe_alloc_multirate_manifest(output);\r
+       ctx.curr_time = 6000;\r
+       ctx.segnum = 1;\r
+\r
+       /*********************************************/\r
+       /*   parse arguments and build HDS context   */\r
+       /*********************************************/\r
+       if (GF_OK != parse_args(argc, argv, &input, &output, &ctx.curr_time, &ctx.segnum)) {\r
+               usage(argv[0]);\r
+               goto exit;\r
+       }\r
+\r
+#if 0 /*'moov' conversion tests*/\r
+       {\r
+               char metamoov64[GF_MAX_PATH];\r
+               u32 metamoov64_len;\r
+               unsigned char metamoov[GF_MAX_PATH];\r
+               u32 metamoov_len=GF_MAX_PATH;\r
+               FILE *f = fopen("metamoov64"/*input*/, "rt");\r
+               gf_f64_seek(f, 0, SEEK_END);\r
+               metamoov64_len = (u32)gf_f64_tell(f);\r
+               gf_f64_seek(f, 0, SEEK_SET);\r
+               fread(metamoov64, metamoov64_len, 1, f);\r
+               metamoov_len = gf_base64_decode(metamoov64, metamoov64_len, metamoov, metamoov_len);\r
+               fclose(f);\r
+               f = fopen("metamoov", "wb");\r
+               fwrite(metamoov, metamoov_len, 1, f);\r
+               fclose(f);\r
+               return 0;\r
+       }\r
+#endif\r
+\r
+#if 0 /*'abst'conversion tests*/\r
+       {\r
+               char bootstrap64[GF_MAX_PATH];\r
+               u32 bootstrap64_len;\r
+               unsigned char bootstrap[GF_MAX_PATH];\r
+               u32 bootstrap_len=GF_MAX_PATH;\r
+               GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox *)abst_New();\r
+               GF_BitStream *bs;\r
+#if 1 //64\r
+               FILE *f = fopen("bootstrap64"/*input*/, "rt");\r
+               gf_f64_seek(f, 0, SEEK_END);\r
+               bootstrap64_len = (u32)gf_f64_tell(f);\r
+               gf_f64_seek(f, 0, SEEK_SET);\r
+               fread(bootstrap64, bootstrap64_len, 1, f);\r
+               bootstrap_len = gf_base64_decode(bootstrap64, bootstrap64_len, bootstrap, bootstrap_len);\r
+#else //binary bootstrap\r
+               FILE *f = fopen("bootstrap.bin"/*input*/, "rb");\r
+               gf_f64_seek(f, 0, SEEK_END);\r
+               bootstrap_len = (u32)gf_f64_tell(f);\r
+               gf_f64_seek(f, 0, SEEK_SET);\r
+               fread(bootstrap, bootstrap_len, 1, f);\r
+#endif\r
+               bs = gf_bs_new(bootstrap+8, bootstrap_len-8, GF_BITSTREAM_READ);\r
+               abst->size = bootstrap[2]*256+bootstrap[3];\r
+               assert(abst->size<GF_MAX_PATH);\r
+               abst_Read((GF_Box*)abst, bs);\r
+               gf_bs_del(bs);\r
+               //then rewrite with just one 'afrt'\r
+               memset(bootstrap, 0, bootstrap_len);\r
+               bs = gf_bs_new(bootstrap, bootstrap_len, GF_BITSTREAM_WRITE);\r
+               abst_Write((GF_Box*)abst, bs);\r
+               bootstrap_len = (u32)gf_bs_get_position(bs);\r
+               gf_bs_del(bs);\r
+               fclose(f);\r
+               f = fopen("bootstrap", "wt");\r
+               bootstrap64_len = gf_base64_encode(bootstrap, bootstrap_len, bootstrap64, GF_MAX_PATH);\r
+               fwrite(bootstrap64, bootstrap64_len, 1, f);\r
+               fprintf(f, "\n\n");\r
+               abst_dump((GF_Box*)abst, f);\r
+               fclose(f);\r
+               abst_del((GF_Box*)abst);\r
+               return 0;\r
+       }\r
+#endif\r
+\r
+       /*****************/\r
+       /*   main loop   */\r
+       /*****************/\r
+       import.trackID = 0;\r
+       import.in_name = input;\r
+       import.flags = GF_IMPORT_PROBE_ONLY;\r
+\r
+       //create output or open when recovering from a saved state\r
+       sprintf(tmpstr, "%s_import.mp4", input);\r
+       isom_file_in = gf_isom_open(tmpstr, GF_ISOM_WRITE_EDIT, NULL);\r
+       if (!isom_file_in) {\r
+               fprintf(stderr, "Error opening output file %s: %s\n", tmpstr, gf_error_to_string(e));\r
+               assert(0);\r
+               goto exit;\r
+       }\r
+       import.dest = isom_file_in;\r
+\r
+       //probe input\r
+       e = gf_media_import(&import);\r
+       if (e) {\r
+               fprintf(stderr, "Error while importing input file %s: %s\n", input, gf_error_to_string(e));\r
+               assert(0);\r
+               goto exit;\r
+       }\r
+\r
+       //import input data\r
+       import.flags = 0;\r
+       for (i=0; i<import.nb_tracks; i++) {\r
+               import.trackID = import.tk_info[i].track_num;\r
+               e = gf_media_import(&import);\r
+               if (e) {\r
+                       fprintf(stderr, "Error while importing track number %u, input file %s: %s\n", import.trackID, input, gf_error_to_string(e));\r
+                       assert(0);\r
+                       goto exit;\r
+               }\r
+       }\r
+\r
+       //Adobe specific stuff\r
+       e = adobize_segment(isom_file_in, &ctx);\r
+       if (e) {\r
+               fprintf(stderr, "Couldn't turn the ISOM fragmented file into an Adobe f4v segment: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               goto exit;\r
+       }\r
+\r
+       //interleave data and remove imported file\r
+       //FIXME: set multiple fragments: \r
+       sprintf(tmpstr, "%s_HD_100_Seg%u-Frag1", output, ctx.segnum); //FIXME: "HD", "100" and fragnum: pass as arg\r
+       //e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0);\r
+       e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0+gf_isom_get_duration(isom_file_in)/gf_isom_get_timescale(isom_file_in));\r
+       if (e) {\r
+               fprintf(stderr, "Error while fragmenting file to output %s: %s\n", output, gf_error_to_string(e));\r
+               assert(0);\r
+               goto exit;\r
+       }\r
+       gf_isom_delete(isom_file_in);\r
+       isom_file_in = NULL;\r
+\r
+       e = adobe_gen_multirate_manifest(ctx.multirate_manifest, ctx.bootstrap, ctx.bootstrap_size);\r
+       if (e) {\r
+               fprintf(stderr, "Couldn't generate Adobe f4m manifest: %s\n", gf_error_to_string(e));\r
+               assert(0);\r
+               goto exit;\r
+       }\r
+\r
+exit:\r
+       //delete intermediate mp4 file\r
+       if (isom_file_in)\r
+               gf_isom_delete(isom_file_in);\r
+\r
+       if (ctx.multirate_manifest)\r
+               adobe_free_multirate_manifest(ctx.multirate_manifest);\r
+\r
+       if (ctx.bootstrap) {\r
+               gf_free(ctx.bootstrap);\r
+               //ctx.bootstrap = NULL;\r
+               //ctx.bootstrap_size = 0;\r
+       }\r
+\r
+       gf_sys_close();\r
+       \r
+       return !e ? 0 : 1;\r
+}\r
+\r
diff --git a/applications/ts2hds/ts2hds.h b/applications/ts2hds/ts2hds.h
new file mode 100644 (file)
index 0000000..5016ca6
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Author: Romain Bouqueau\r
+ *                     Copyright (c) Romain Bouqueau 2012-\r
+ *                             All rights reserved\r
+ *\r
+ *          Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com)\r
+ *\r
+ *  This file is part of GPAC / TS to HDS (ts2hds) application\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#include <gpac/media_tools.h>\r
+\r
+//f4m\r
+typedef struct __tag_adobe_stream AdobeStream;\r
+typedef struct __tag_adobe_multirate AdobeMultirate;\r
+AdobeMultirate *adobe_alloc_multirate_manifest(char *id);\r
+void adobe_free_multirate_manifest(AdobeMultirate *am);\r
+GF_Err adobe_gen_multirate_manifest(AdobeMultirate* am, char *bootstrap, size_t bootstrap_size);\r
+\r
+//context\r
+typedef struct\r
+{\r
+       u64 curr_time;\r
+       u32 segnum;\r
+       char *bootstrap;\r
+       size_t bootstrap_size;\r
+       AdobeMultirate *multirate_manifest;\r
+} AdobeHDSCtx;\r
+\r
+//f4v\r
+GF_Err adobize_segment(GF_ISOFile *isom_file, AdobeHDSCtx *ctx);\r
index f7f7bf2e5310c5ac6abbea7d7e8cce0136b8f3e6..cfcadb11f929d6fa34714832e82d080c8b65a8fe 100644 (file)
@@ -55,11 +55,6 @@ all: $(PROG)
 $(PROG): $(OBJS)
        $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(PROG)
 
index b372b65e3f7194160006053eacf8e59867cc8ed2..9825bffa2382da765814e6f936644b010154a977 100644 (file)
@@ -1,7 +1,8 @@
 /*
 *                      GPAC - Multimedia Framework C SDK
 *
-*                      Copyright (c) ENST 2000-200X
+ *                     Authors: Cyril COncolato, Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2008-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / udp TS segmenter (udptsseg) application
index f91f14d48ec8cb557330e6147a9f342483265c1f..7ec194b3bd19d901b896120bc42c8a70a7dc923c 100644 (file)
@@ -2,7 +2,8 @@ set OLDDIR=%CD%
 cd /d %~dp0\r
 \r
 for /f "delims=" %%a in ('svnversion ') do set gpac_revision=%%a\r
+set gpac_version="0.5.1-DEV-r%gpac_revision%"\r
 \r
-zip "GPAC_0.5.0-r%gpac_revision%_WindowsMobile.zip" ../*.dll ../*.exe ../*.plg\r
+zip "GPAC_%gpac_version%_WindowsMobile.zip" ../*.dll ../*.exe ../*.plg\r
 \r
 cd /d %OLDDIR%\r
index 8591a040971618a8fd081fbb6a91d43cba93be60..ad3dcad5ce41fe3e2ff8bc08b3698ef9d55105ed 100644 (file)
@@ -3,8 +3,10 @@ cd /d %~dp0
 \r
 for /f "delims=" %%a in ('svnversion') do set gpac_revision=%%a\r
 \r
+set gpac_version="0.5.1-DEV-r%gpac_revision%"\r
+\r
 ECHO [Version] > gpaccab.inf\r
-ECHO Provider = "GPAC 0.5.0-r%gpac_revision%" >> gpaccab.inf\r
+ECHO Provider = "GPAC %gpac_version%" >> gpaccab.inf\r
 type gpac.inf >> gpaccab.inf\r
 \r
 CabWiz gpaccab.inf\r
@@ -12,7 +14,7 @@ CabWiz gpaccab.inf
 ECHO off\r
 \r
 ECHO [CEAppManager]> gpac.ini\r
-ECHO Version = 0.5.0-r%gpac_revision%>> gpac.ini\r
+ECHO Version = %gpac_version%>> gpac.ini\r
 ECHO Component = GPAC for Windows Mobile>> gpac.ini\r
 ECHO [GPAC for Windows Mobile]>> gpac.ini\r
 ECHO Description = GPAC MPEG-4 Player>> gpac.ini\r
@@ -24,7 +26,7 @@ ECHO CabFiles = gpaccab.cab >> gpac.ini
 ECHO on\r
 \r
 ezsetup -l english -i gpac.ini -r readme.txt -e ../../../../COPYING -o gpac.exe\r
-rename gpac.exe "GPAC_0.5.0-r%gpac_revision%_WindowsMobile.exe"\r
+rename gpac.exe "GPAC_%gpac_version%_WindowsMobile.exe"\r
 DEL gpaccab.cab\r
 DEL gpaccab.inf\r
 DEL gpac.ini\r
index 5879e325fb7cd0d9ebff88b4246cd474634b0791..0bce1e0f2c38c9439d105c88912b839a8717d5b2 100644 (file)
@@ -1,5 +1,4 @@
 ;[Version]
-;Provider = "GPAC 0.5.0"
 Signature = "$Windows NT$"
 CESignature = "$Windows CE$"
 
index 46dd6274f0d629e812b0c09b9e5919fe31e63024..08442c1c9b1c2dd950aaecc1eb0fb17a3e4e480a 100644 (file)
@@ -1,4 +1,4 @@
-This will install GPAC version 0.5.0 for ARM PocketPC/SmartPhones 2003 Platforms\r
+This will install GPAC for ARM PocketPC/SmartPhones 2003 Platforms\r
 \r
 GPAC is an open source MPEG-4 framework developped by ENST and available at:\r
        http://gpac.sourceforge.net\r
index 65437e95485534607f8860559d72b45d6cb9127f..d9645dacfeb43307f02a6a373743ceeaf9f14ea1 100644 (file)
@@ -1,6 +1,6 @@
 ;--------------------------------\r
 ;General\r
-!define GPAC_VERSION   0.5.0\r
+!define GPAC_VERSION   0.5.1-DEV\r
 !include default.out\r
 \r
 !define GPAC_ROOT ..\..\..\..\r
index 2da22e100f1b6d3b673563e0d855f7027157b5a9..e3220ac75d66bc2b229496062b0f130711e2211e 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,9 @@
 #!/bin/sh
 #
-# GPAC MPEG-4 SDK configure script (c) 2003-2005 Jean Le Feuvre (c) 2005-20XX Telecom ParisTech
-#      inspired from ffmpeg configure by Fabrice Bellard (c) 2000-2002
+# GPAC configure script 
+#     (c) 2003-2012 Telecom ParisTech 
+#     Authors: Jean Le Feuvre, Romain Bouqueau
+#
 #set -v
 
 
@@ -15,7 +17,7 @@ else
 fi
 
 
-#thanks to ffmpeg for this
+#remember the ./configure command line
 for v in "$@"; do
     r="${v#*=}"
     l="${v%$r}"
@@ -56,6 +58,7 @@ debuginfo="no"
 sdl_path=""
 sdl_local="no"
 sdl_static="no"
+verbose="no"
 xulsdk_path="/usr/lib/xulrunner/sdk/include"
 xul_flags=""
 libdir="lib"
@@ -108,6 +111,7 @@ has_joystick="no"
 has_xul="no"
 enable_joystick="no"
 static_mp4box="no"
+disable_core_tools="no"
 disable_3d="no"
 disable_svg="no"
 disable_vrml="no"
@@ -136,8 +140,11 @@ disable_loader_isoff="no"
 disable_loader_bt="no"
 disable_loader_xmt="no"
 disable_od_dump="no"
+disable_od_parse="no"
 disable_isom_dump="no"
 disable_mcrypt="no"
+disable_mpd="no"
+disable_dash="no"
 disable_isoff="no"
 disable_isoff_write="no"
 disable_isoff_frag="no"
@@ -146,7 +153,7 @@ disable_isoff_frag="no"
 disable_streaming="no"
 disable_player="no"
 disable_scenegraph="no"
-disable_dvbx="no"
+disable_dvbx="yes"
 disable_vobsub="no"
 disable_ttxt="no"
 enable_depth_compositor="no"
@@ -193,6 +200,7 @@ GPAC configuration options:
   --prefix=PREFIX          install in PREFIX [$prefix]
   --mandir=DIR             man documentation in DIR [PREFIX/man]
 
+  --verbose                enable verbose building [$verbose]
   --source-path=PATH       path of source code [$source_path]
   --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
   --cc =CC                 use C   compiler CC  [$cc]
@@ -276,7 +284,7 @@ Configuration options for libgpac - all options can be enabled with --enable-opt
   --disable-isoff-hint     disable ISO File Format hinting
   --disable-isoff-frag     disable fragments in ISO File Format
   --disable-streaming      disable RTP/RTSP/SDP
-  --disable-dvb            disable DVB-specific tools (MPE, FEC, DSM-CC)
+  --disable-dvbx           disable DVB-specific tools (MPE, FEC, DSM-CC)
   --disable-vobsub         disable VobSub support
   --disable-sman           disable scene manager
   --disable-ttxt           disable TTXT (3GPP / MPEG-4 Timed Text) support
@@ -334,6 +342,8 @@ for opt do
             ;;
         --enable-pic) want_pic="yes";
             ;;
+        --verbose) verbose="yes";
+            ;;
     esac
 done
 
@@ -646,14 +656,9 @@ fi
 if test "$has_zlib" = "no" ; then
   if $cc -o $TMPO $TMPC -I"$local_inc/zlib" -L$local_lib -lz 2> /dev/null  ; then
     has_zlib="local"
-  else
-    echo "error: zlib not found on system or in local libs"
-    exit 1
   fi
 fi
 
-
-
 #check dlopen
 cat > $TMPC << EOF
 #include <dlfcn.h>
@@ -664,16 +669,13 @@ if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then
     dlopen="yes"
 elif $cc -o $TMPE $TMPC $LDFLAGS -ldl > /dev/null 2>&1 ; then
     GPAC_SH_FLAGS="$GPAC_SH_FLAGS -ldl"
-else
-    if test "$win32" = "no"; then
-        echo "error: dlopen not found on system"
-        exit 1
-    fi
 fi
 
 
 
 #look for spidermonkey JS support
+mozjs_pkgcfg="no"
+
 
 #spidermonkey test for new API
 if test "$has_js" = "no" ; then
@@ -692,11 +694,19 @@ EOF
     else
         #try pkg-config
         if $pkg_config --exists mozilla-js 2> /dev/null  ; then
-            js_flags=`$pkg_config --cflags mozilla-js`
-            js_lib_pkg=`$pkg_config --libs mozilla-js`
+            mozjs_pkgcfg="mozilla-js"
+        elif $pkg_config --exists mozjs 2> /dev/null  ; then
+            mozjs_pkgcfg="mozjs"
+        elif $pkg_config --exists mozjs185 2> /dev/null  ; then
+            mozjs_pkgcfg="mozjs185"
+       fi
+
+        if test $mozjs_pkgcfg != "no" ; then
+            js_flags=`$pkg_config --cflags $mozjs_pkgcfg`
+            js_lib_pkg=`$pkg_config --libs $mozjs_pkgcfg`
             if $cc -o $TMPO $TMPC $js_flags $js_lib_pkg $LDFLAGS -lpthread 2> /dev/null  ; then
                 has_js="system"
-                js_lib=`$pkg_config --libs mozilla-js`
+                js_lib=`$pkg_config --libs $mozjs_pkgcfg`
             fi
         #try firefox folders (starting at ubuntu 11.10, no pkg-config)
         elif ls -d /usr/lib/firefox* > /dev/null 2>&1 ; then
@@ -787,11 +797,19 @@ EOF
             #dc added end
         else
             if $pkg_config --exists mozilla-js 2> /dev/null  ; then
-                js_flags=`$pkg_config --cflags mozilla-js`
-                js_lib_pkg=`$pkg_config --libs mozilla-js`
+               mozjs_pkgcfg="mozilla-js"
+            elif $pkg_config --exists mozjs 2> /dev/null  ; then
+               mozjs_pkgcfg="mozjs"
+            elif $pkg_config --exists mozjs185 2> /dev/null  ; then
+               mozjs_pkgcfg="mozjs185"
+           fi
+
+           if test mozjs_pkgcfg != "no" ; then
+                js_flags=`$pkg_config --cflags $mozjs_pkgcfg`
+                js_lib_pkg=`$pkg_config --libs $mozjs_pkgcfg`
                 if $cc -o $TMPO $TMPC $js_flags $js_lib_pkg $LDFLAGS -lpthread 2> /dev/null  ; then
                     has_js="system"
-                    js_lib=`$pkg_config --libs mozilla-js`
+                    js_lib=`$pkg_config --libs $mozjs_pkgcfg`
                 fi
             fi
             if test "$has_js" = "no" ; then
@@ -844,7 +862,20 @@ cat > $TMPC << EOF
 int main( void ) { JSObject *obj; JS_GetPrivate(obj); }
 EOF
                 if $cc -o $TMPO $TMPC $js_flags $LDFLAGS $js_lib 2> /dev/null  ; then
-                    js_flags="-DUSE_FFDEV_12 $js_flags"
+
+cat > $TMPC << EOF
+#include <jsapi.h>
+int main( void ) { jsval *vp; JSObject *obj = JS_NewObjectForConstructor(c, vp); }
+EOF
+                       if $cc -o $TMPO $TMPC $js_flags $LDFLAGS $js_lib 2> /dev/null  ; then
+                           js_flags="-DUSE_FFDEV_12 $js_flags"
+                       elif ! grep JS_ConstructObject $js_inc/jsapi.h > /dev/null 2>&1 ; then
+                               js_flags="-DUSE_FFDEV_16 $js_flags"
+                       elif grep JSHandleObject $js_inc/jsapi.h > /dev/null 2>&1 ; then
+                               js_flags="-DUSE_FFDEV_15 $js_flags"
+                        else
+                               js_flags="-DUSE_FFDEV_14 $js_flags"
+                       fi
                 else
 cat > $TMPC << EOF
 #include <jsapi.h>
@@ -962,15 +993,15 @@ if test "$cross_prefix" = "" ; then
     if $cc $CFLAGS_DIR -o $TMPO $TMPC $ft_cflags $ft_lflags $LDFLAGS 2> /dev/null  ; then
         has_ft="system"
     else
-        ft_cflags="`freetype-config --cflags`"
-        ft_lflags="`freetype-config --libs`"
+        ft_cflags="`freetype-config --cflags 2> /dev/null`"
+        ft_lflags="`freetype-config --libs 2> /dev/null`"
         if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags $LDFLAGS 2> /dev/null  ; then
             has_ft="system"
         fi
     fi
 fi
 if test "$has_ft" = "no" ; then
-    if test "`which freetype-config`" != ""; then
+    if test "`which freetype-config 2> /dev/null`" != ""; then
         ft_cflags="-I$local_inc/freetype"
         ft_lflags="-L$local_lib -lfreetype"
         if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null  ; then
@@ -1017,7 +1048,7 @@ if test "$cross_prefix" = "" ; then
         if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib $LDFLAGS -ljpeg 2> /dev/null ; then
             has_jpeg="system"
         fi
-    elif test "`which $prefix/bin/jpeg-config`" != ""; then
+    elif test "`which $prefix/bin/jpeg-config 2> /dev/null`" != ""; then
         jpeg_cflags="`$prefix/bin/jpeg-config --cflags`"
         jpeg_lflags="`$prefix/bin/jpeg-config --libs`"
         if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags $LDFLAGS 2> /dev/null  ; then
@@ -1698,7 +1729,7 @@ for opt do
         --enable-pulseaudio=*) has_pulseaudio="yes"
             ;;
 
-        --disable-all) has_pulseaudio="no"; has_alsa="no"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_seng="yes"; disable_qtvr="yes";  disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_isom_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"; disable_player="yes"; disable_vobsub="yes"; disable_ttxt="yes"; disable_saf="yes"; disable_smgr="yes"
+        --disable-all) has_pulseaudio="no"; has_alsa="no"; disable_core_tools="yes"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_seng="yes"; disable_qtvr="yes";  disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_od_parse="yes"; disable_isom_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"; disable_player="yes"; disable_vobsub="yes"; disable_scenegraph="yes"; disable_dvbx="yes"; disable_ttxt="yes"; disable_saf="yes"; disable_smgr="yes"; disable_mpd="yes"; disable_dash="yes"
             ;;
 
         --disable-3d) disable_3d="yes"
@@ -1807,6 +1838,10 @@ for opt do
             ;;
         --enable-od-dump) disable_od_dump="no"
             ;;
+        --disable-od-parse) disable_od_parse="yes"
+            ;;
+        --enable-od-parse) disable_od_parse="no"
+            ;;
         --disable-isom-dump) disable_isom_dump="yes"
             ;;
         --enable-isom-dump) disable_isom_dump="no"
@@ -1863,12 +1898,39 @@ for opt do
             ;;
         --enable-smgr) disable_smgr="no"
             ;; 
-
+        --disable-mpd) disable_mpd="yes"
+            ;;
+        --enable-mpd) disable_mpd="no"
+            ;; 
+        --disable-dash) disable_dash="yes"
+            ;;
+        --enable-dash) disable_dash="no"
+            ;; 
+        --disable-core) disable_core_tools="yes"
+            ;;
+        --enable-core) disable_core_tools="no"
+            ;; 
     esac
 done
 
 
 
+if test "$disable_core_tools" = "no"; then
+  if test "$has_zlib" = "no" ; then
+    echo "error: zlib not found on system or in local libs"
+    exit 1
+  fi
+  if test "$dlopen" = "no"; then
+    if test "$win32" = "no"; then
+      echo "error: dlopen not found on system"
+      exit 1
+    fi
+  fi
+else
+GPAC_SH_FLAGS=""
+has_ssl="no"
+fi
+
 #look for OpenGL support or for TinyGL support
 LINK3D=""
 INCL3D=""
@@ -1958,8 +2020,10 @@ if test "$has_xul" = "no" ; then
         #xulrunner directories are sometimes included through js/xul/ff packages
         if test ! "$has_js" = "no" -a ! "$has_js" = "local" ; then
             if $cc -o $TMPO $TMPCPP $js_flags $js_lib_pkg $LDFLAGS 2> /dev/null  ; then
-                xul_flags=`$pkg_config --cflags mozilla-js`
-                has_xul="$has_js"
+                if test "$mozjs_pkgcfg" != "no" ; then
+                    xul_flags=`$pkg_config --cflags $mozjs_pkgcfg`
+                    has_xul="$has_js"
+                fi
             fi
         fi
     fi
@@ -2093,12 +2157,15 @@ if test "$cpu" = "sh4"; then
     fi
 fi
 
+if test "$disable_player" = "yes" ; then
+disable_scenegraph="yes"
+fi
+
 if test "$disable_scenegraph" = "yes" ; then
 disable_3d="yes"
 disable_svg="yes"
 disable_vrml="yes"
 disable_x3d="yes"
-disable_od="no"
 disable_bifs="yes"
 disable_bifs_enc="yes"
 disable_laser="yes"
@@ -2113,6 +2180,23 @@ disable_loader_bt="yes"
 disable_loader_xmt="yes"
 disable_streaming="yes"
 disable_player="yes"
+disable_smgr="yes"
+has_js="no"
+fi
+
+if test "$disable_mpd" = "yes"; then
+disable_dash="yes"
+fi
+
+if test "$disable_od_parse" = "yes" ; then
+disable_loader_isoff="yes"
+disable_loader_bt="yes"
+disable_loader_xmt="yes"
+fi
+
+if test "$disable_parsers" = "yes" ; then
+has_jpeg="no"
+has_png="no"
 fi
 
 #prepare for config.h writing
@@ -2122,22 +2206,24 @@ echo "#ifndef GF_CONFIG_H" >> $TMPH
 echo "#define GF_CONFIG_H" >> $TMPH
 echo "#define GPAC_CONFIGURATION \"$GPAC_CONFIGURATION\"" >> $TMPH
 
-version="`grep '#define GPAC_VERSION ' \"$source_path/include/gpac/tools.h\" | cut -d '"' -f 2`"
-version_major=`grep '#define GPAC_VERSION_MAJOR ' $source_path/include/gpac/tools.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
-version_minor=`grep '#define GPAC_VERSION_MINOR ' $source_path/include/gpac/tools.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
-version_micro=`grep '#define GPAC_VERSION_MICRO ' $source_path/include/gpac/tools.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
+version="`grep '#define GPAC_VERSION ' \"$source_path/include/gpac/version.h\" | cut -d '"' -f 2`"
+version_major=`grep '#define GPAC_VERSION_MAJOR ' $source_path/include/gpac/version.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
+version_minor=`grep '#define GPAC_VERSION_MINOR ' $source_path/include/gpac/version.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
+version_micro=`grep '#define GPAC_VERSION_MICRO ' $source_path/include/gpac/version.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
 soname_version="${version_major}.${version_minor}.${version_micro}"
 
 if [ -d ".svn" ]; then
- if which svnversion >/dev/null
+ if which svnversion 2>/dev/null
  then
     revision="`svnversion \"$source_path\"`"
-    echo "#define GPAC_SVN_REVISION    \"$revision\"" > $source_path/include/gpac/version.h
+    echo "#define GPAC_SVN_REVISION    \"$revision\"" > $source_path/include/gpac/revision.h
  else
     echo "Cannot find SVN revision"
  fi
 else
-    echo "#define GPAC_SVN_REVISION    \"4065\"" > $source_path/include/gpac/version.h
+ if [ ! -e "$source_path/include/gpac/revision.h" ]; then
+    echo "#define GPAC_SVN_REVISION    \"4065\"" > $source_path/include/gpac/revision.h
+ fi
 fi
 
 echo ""
@@ -2182,6 +2268,10 @@ disable_svg="yes"
     echo "Scene Manager disabled"
     echo "#define GPAC_DISABLE_SMGR" >> $TMPH
 fi
+if test "$disable_core_tools" = "yes" ; then
+    echo "Core tools disabled"
+    echo "#define GPAC_DISABLE_CORE_TOOLS" >> $TMPH
+fi
 if test "$disable_svg" = "yes" ; then
     echo "SVG disabled"
     echo "#define GPAC_DISABLE_SVG" >> $TMPH
@@ -2199,6 +2289,10 @@ if test "$disable_od" = "yes" ; then
     echo "OD Full support disabled"
     echo "#define GPAC_MINIMAL_ODF" >> $TMPH
 fi
+if test "$disable_od_parse" = "yes" ; then
+    echo "OD Parsing disabled"
+    echo "#define GPAC_DISABLE_OD_PARSE" >> $TMPH
+fi
 if test "$disable_bifs" = "yes" ; then
     echo "BIFS coder disabled"
     echo "#define GPAC_DISABLE_BIFS" >> $TMPH
@@ -2315,10 +2409,10 @@ if test "$disable_streaming" = "yes" ; then
     echo "RTP/RTSP/SDP streaming disabled"
     echo "#define GPAC_DISABLE_STREAMING" >> $TMPH
 fi
-if test "$disable_dvbx" = "yes" ; then
+if test "$disable_dvbx" = "no" ; then
     echo "DVB MPE and DSM-CC disabled"
-    echo "#define GPAC_DISABLE_MPE" >> $TMPH
-    echo "#define GPAC_DISABLE_DSMCC" >> $TMPH
+    echo "#define GPAC_ENABLE_MPE" >> $TMPH
+    echo "#define GPAC_ENABLE_DSMCC" >> $TMPH
 fi
 if test "$disable_vobsub" = "yes" ; then
     echo "VobSub disabled"
@@ -2334,6 +2428,15 @@ if test "$enable_depth_compositor" = "yes" ; then
     echo "#define GF_SR_USE_DEPTH" >> $TMPH
 fi
 
+if test "$disable_mpd" = "yes" ; then
+    echo "HLS and DASH Manifest Disabled"
+fi
+
+if test "$disable_dash" = "yes" ; then
+    echo "Adaptive HTTP Streaming Client disabled"
+    echo "#define GPAC_DISABLE_DASH_CLIENT" >> $TMPH
+fi
+
 echo ""
 
 echo "** Detected libraries **"
@@ -2474,11 +2577,21 @@ echo "moddir_path=$prefix/$libdir/gpac" >> config.mak
 echo "mandir=$mandir" >> config.mak
 echo "tinygl_target_bin_dir=$target_bin_dir" >> config.mak
 echo "MAKE=$make" >> config.mak
+
+if test "$verbose" = "yes" ; then
 echo "CC=$cc_naked" >> config.mak
 echo "AR=$ar" >> config.mak
 echo "RANLIB=$ranlib" >> config.mak
 echo "STRIP=$strip" >> config.mak
+else
+echo "CC=@$cc_naked" >> config.mak
+echo "AR=@$ar" >> config.mak
+echo "RANLIB=@$ranlib" >> config.mak
+echo "STRIP=@$strip" >> config.mak
+fi
 echo "INSTALL=$install" >> config.mak
+echo "LIBTOOL=libtool" >> config.mak
+
 echo "INSTFLAGS=$instflags" >> config.mak
 echo "OPTFLAGS=$CFLAGS" >> config.mak
 echo "CPPFLAGS=$CPPFLAGS" >> config.mak
@@ -2643,15 +2756,21 @@ echo "DISABLE_ISOFF_HINT=$disable_isoff_hint" >> config.mak
 echo "DISABLE_VOBSUB=$disable_vobsub" >> config.mak
 echo "DISABLE_TTXT=$disable_ttxt" >> config.mak
 echo "DISABLE_SMGR=$disable_smgr" >> config.mak
+echo "DISABLE_AV_PARSERS=$disable_parsers" >> config.mak
+echo "DISABLE_MEDIA_IMPORT=$disable_import" >> config.mak
+echo "DISABLE_MEDIA_EXPORT=$disable_export" >> config.mak
+echo "DISABLE_MPD=$disable_mpd" >> config.mak
+echo "DISABLE_DASH_CLIENT=$disable_dash" >> config.mak
+echo "DISABLE_CORE_TOOLS=$disable_core_tools" >> config.mak
+echo "DISABLE_OD_DUMP=$disable_od_dump" >> config.mak
+echo "DISABLE_OD_PARSE=$disable_od_parse" >> config.mak
+echo "MINIMAL_OD=$disable_od" >> config.mak
 
 if test "$disable_parsers" = "yes" ; then
     disable_m2ts_mux="yes"
 fi
-if test "$disable_m2ts_mux" = "yes" -o "$disable_m2ts" = "yes" ; then
-    echo "DISABLE_M2TS=yes" >> config.mak
-else
-    echo "DISABLE_M2TS=no" >> config.mak
-fi
+echo "DISABLE_M2TS_MUX=$disable_m2ts_mux" >> config.mak
+echo "DISABLE_M2TS=$disable_m2ts" >> config.mak
 
 
 echo "GPAC_USE_TINYGL=$has_tinygl" >> config.mak
@@ -2882,13 +3001,29 @@ if [ ! -d "./bin/gcc/temp" ] ; then
     mkdir ./bin/gcc/temp
 fi
 
+
 echo '%.opic : %.c' >> config.mak
+if test "$verbose" = "no" ; then
+echo ' @echo "  CC $<"' >> config.mak
+fi
 echo ' $(CC) $(CFLAGS) $(PIC_CFLAGS) -c $< -o $@' >> config.mak
 
+echo '%.o : %.c' >> config.mak
+if test "$verbose" = "no" ; then
+echo ' @echo "  CC $<"' >> config.mak
+fi
+echo ' $(CC) $(CFLAGS) -c -o $@ $<' >> config.mak
+
+echo '%.o: %.cpp' >> config.mak
+if test "$verbose" = "no" ; then
+echo ' @echo "  CC $<"' >> config.mak
+fi
+echo ' $(CXX) $(CFLAGS) -c -o $@ $<' >> config.mak
+
 #pkg-config
 echo "prefix=$prefix"                           > gpac.pc
 echo "exec_prefix=\${prefix}"                  >> gpac.pc
-echo "libdir=\${exec_prefix}/lib"              >> gpac.pc
+echo "libdir=\${exec_prefix}/$libdir"          >> gpac.pc
 echo "includedir=\${exec_prefix}/include"      >> gpac.pc
 echo ""                                                >> gpac.pc
 echo "Name: gpac"                              >> gpac.pc
index 019f6c69c363349167d0bd7fed91ceb72dd5d701..1062bafc414c681975933268d163e75f4b55d034 100644 (file)
Binary files a/doc/configuration.html and b/doc/configuration.html differ
index cc318a7f49a838ef9c3ca22d2ba40980ba1d4523..94b390a6a4ac845aa7ace3ef04f42fcecec3d5ff 100644 (file)
 
 #ifdef AVCAP_LINUX
 # include <linux/types.h>
-# include <linux/videodev.h>
+# ifdef AVCAP_HAVE_V4L2
+#  include <linux/videodev2.h>
+# else
+#  include <linux/videodev.h>
+# endif
 #endif
 
 #include <string>
index b111c262fe53c974bdc288a823ef3f385f0e6f61..04bf1cedb6d25e9fa0b14bcc3d4e91a7832f2782 100644 (file)
 
 #ifdef AVCAP_LINUX
 # include <linux/types.h>
-# include <linux/videodev.h>
+# ifdef AVCAP_HAVE_V4L2
+#  include <linux/videodev2.h>
+# else
+#  include <linux/videodev.h>
+# endif
 #endif // AVCAP_LINUX
 
 #ifdef _WIN32
index 827b5eb70eb07c9dffdd9dc9acf377330819fbe5..db4e825720898a3d9e59780823da8b3d3f937129 100644 (file)
 #define V4L1_CONNECTOR_H_
 
 #include <linux/types.h>
-#include <linux/videodev.h>
 
 #include <string>
 #include <list>
 
 #include "Connector.h"
 
+#ifdef AVCAP_HAVE_V4L2
+#include <linux/videodev2.h>
+#else
+#include <linux/videodev.h>
+#endif
+
 namespace avcap
 {      
        // forward declaration
index f771b67dc43696b9f4c2acbcb3aba72ecaa16c71..4b211b6e902d6c407e7ed043ef259c1c6f7eedae 100644 (file)
 #ifndef V4L1_CONNECTORMANAGER_H_
 #define V4L1_CONNECTORMANAGER_H_
 
-#include <linux/videodev.h>
 #include <list>
 
 #include "ConnectorManager.h"
 
+#ifdef AVCAP_HAVE_V4L2
+#include <linux/videodev2.h>
+#else
+#include <linux/videodev.h>
+#endif
+
 namespace avcap
 {      
        class V4L1_DeviceDescriptor;
index 3927bf225bacf9d7a41c149e5fbe9e160a028efb..469d4efd4feeb7d9299d835e0873cf13fb877e79 100644 (file)
 #define V4L2_CONNECTOR_H_
 
 #include <linux/types.h>
-#include <linux/videodev.h>
 
 #include <string>
 #include <list>
 
 #include "Connector.h"
 
+#ifdef AVCAP_HAVE_V4L2
+#include <linux/videodev2.h>
+#else
+#include <linux/videodev.h>
+#endif
+
 namespace avcap
 {      
        // forward declaration
index 806574ceff33b17a2f95d1e55e27a5372824657e..f8efb75f6caa08f3b9b65f5399a8d85b0584ed24 100644 (file)
 
 #include <string>
 #include <list>
+
+#if !defined(_MSC_VER) && !defined(USE_PREBUILD_LIBS)
+# include "avcap-config.h"
+#endif
+
+#ifdef AVCAP_HAVE_V4L2
+#include <linux/videodev2.h>
+#else
 #include <linux/videodev.h>
+#endif
 
 namespace avcap
 {
index 043acb42adaaf1dcc219adc2c2ac40a1fe57e619..1dcdf6d6e4d23007c5b17971c28dbbe252a494c2 100644 (file)
 #define V4L2_TUNER_H_
 
 #include <linux/types.h>
-#include <linux/videodev.h>
 #include <sys/types.h>
 #include <string>
 
 #include "Tuner_avcap.h"
+#ifdef AVCAP_HAVE_V4L2
+#include <linux/videodev2.h>
+#else
+#include <linux/videodev.h>
+#endif
 
 namespace avcap
 {
index 594da5f0b7037af968d9c0caf48464dacbb3b2a5..0b3a19af1936ef718e123b958562502cf3cdfd38 100644 (file)
 #define AVCODEC_AVCODEC_H
 
 /**
- * @file libavcodec/avcodec.h
+ * @file
  * external API header
  */
 
 #include <errno.h>
+#include "libavutil/samplefmt.h"
 #include "libavutil/avutil.h"
+#include "libavutil/cpu.h"
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+#include "libavutil/audioconvert.h"
+
+#include "libavcodec/version.h"
+/**
+ * @defgroup libavc Encoding/Decoding Library
+ * @{
+ *
+ * @defgroup lavc_decoding Decoding
+ * @{
+ * @}
+ *
+ * @defgroup lavc_encoding Encoding
+ * @{
+ * @}
+ *
+ * @defgroup lavc_codec Codecs
+ * @{
+ * @defgroup lavc_codec_native Native Codecs
+ * @{
+ * @}
+ * @defgroup lavc_codec_wrappers External library wrappers
+ * @{
+ * @}
+ * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge
+ * @{
+ * @}
+ * @}
+ * @defgroup lavc_internal Internal
+ * @{
+ * @}
+ * @}
+ *
+ */
 
-#define LIBAVCODEC_VERSION_MAJOR 52
-#define LIBAVCODEC_VERSION_MINOR 29
-#define LIBAVCODEC_VERSION_MICRO  0
-
-#define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
-                                               LIBAVCODEC_VERSION_MINOR, \
-                                               LIBAVCODEC_VERSION_MICRO)
-#define LIBAVCODEC_VERSION      AV_VERSION(LIBAVCODEC_VERSION_MAJOR,    \
-                                           LIBAVCODEC_VERSION_MINOR,    \
-                                           LIBAVCODEC_VERSION_MICRO)
-#define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
-
-#define LIBAVCODEC_IDENT        "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
+/**
+ * @defgroup lavc_core Core functions/structures.
+ * @ingroup libavc
+ *
+ * Basic definitions, functions for querying libavcodec capabilities,
+ * allocating core structures, etc.
+ * @{
+ */
 
-#define AV_NOPTS_VALUE          INT64_C(0x8000000000000000)
-#define AV_TIME_BASE            1000000
-#define AV_TIME_BASE_Q          (AVRational){1, AV_TIME_BASE}
 
 /**
- * Identifies the syntax and semantics of the bitstream.
+ * Identify the syntax and semantics of the bitstream.
  * The principle is roughly:
  * Two decoders with the same ID can decode the same streams.
  * Two encoders with the same ID can encode compatible streams.
  *
  * If you add a codec ID to this list, add it so that
  * 1. no value of a existing codec ID changes (that would break ABI),
- * 2. it is as close as possible to similar codecs.
+ * 2. Give it a value which when taken as ASCII is recognized uniquely by a human as this specific codec.
+ *    This ensures that 2 forks can independently add AVCodecIDs without producing conflicts.
+ *
+ * After adding new codec IDs, do not forget to add an entry to the codec
+ * descriptor list and bump libavcodec minor version.
  */
-enum CodecID {
-    CODEC_ID_NONE,
+enum AVCodecID {
+    AV_CODEC_ID_NONE,
 
     /* video codecs */
-    CODEC_ID_MPEG1VIDEO,
-    CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
-    CODEC_ID_MPEG2VIDEO_XVMC,
-    CODEC_ID_H261,
-    CODEC_ID_H263,
-    CODEC_ID_RV10,
-    CODEC_ID_RV20,
-    CODEC_ID_MJPEG,
-    CODEC_ID_MJPEGB,
-    CODEC_ID_LJPEG,
-    CODEC_ID_SP5X,
-    CODEC_ID_JPEGLS,
-    CODEC_ID_MPEG4,
-    CODEC_ID_RAWVIDEO,
-    CODEC_ID_MSMPEG4V1,
-    CODEC_ID_MSMPEG4V2,
-    CODEC_ID_MSMPEG4V3,
-    CODEC_ID_WMV1,
-    CODEC_ID_WMV2,
-    CODEC_ID_H263P,
-    CODEC_ID_H263I,
-    CODEC_ID_FLV1,
-    CODEC_ID_SVQ1,
-    CODEC_ID_SVQ3,
-    CODEC_ID_DVVIDEO,
-    CODEC_ID_HUFFYUV,
-    CODEC_ID_CYUV,
-    CODEC_ID_H264,
-    CODEC_ID_INDEO3,
-    CODEC_ID_VP3,
-    CODEC_ID_THEORA,
-    CODEC_ID_ASV1,
-    CODEC_ID_ASV2,
-    CODEC_ID_FFV1,
-    CODEC_ID_4XM,
-    CODEC_ID_VCR1,
-    CODEC_ID_CLJR,
-    CODEC_ID_MDEC,
-    CODEC_ID_ROQ,
-    CODEC_ID_INTERPLAY_VIDEO,
-    CODEC_ID_XAN_WC3,
-    CODEC_ID_XAN_WC4,
-    CODEC_ID_RPZA,
-    CODEC_ID_CINEPAK,
-    CODEC_ID_WS_VQA,
-    CODEC_ID_MSRLE,
-    CODEC_ID_MSVIDEO1,
-    CODEC_ID_IDCIN,
-    CODEC_ID_8BPS,
-    CODEC_ID_SMC,
-    CODEC_ID_FLIC,
-    CODEC_ID_TRUEMOTION1,
-    CODEC_ID_VMDVIDEO,
-    CODEC_ID_MSZH,
-    CODEC_ID_ZLIB,
-    CODEC_ID_QTRLE,
-    CODEC_ID_SNOW,
-    CODEC_ID_TSCC,
-    CODEC_ID_ULTI,
-    CODEC_ID_QDRAW,
-    CODEC_ID_VIXL,
-    CODEC_ID_QPEG,
-    CODEC_ID_XVID,
-    CODEC_ID_PNG,
-    CODEC_ID_PPM,
-    CODEC_ID_PBM,
-    CODEC_ID_PGM,
-    CODEC_ID_PGMYUV,
-    CODEC_ID_PAM,
-    CODEC_ID_FFVHUFF,
-    CODEC_ID_RV30,
-    CODEC_ID_RV40,
-    CODEC_ID_VC1,
-    CODEC_ID_WMV3,
-    CODEC_ID_LOCO,
-    CODEC_ID_WNV1,
-    CODEC_ID_AASC,
-    CODEC_ID_INDEO2,
-    CODEC_ID_FRAPS,
-    CODEC_ID_TRUEMOTION2,
-    CODEC_ID_BMP,
-    CODEC_ID_CSCD,
-    CODEC_ID_MMVIDEO,
-    CODEC_ID_ZMBV,
-    CODEC_ID_AVS,
-    CODEC_ID_SMACKVIDEO,
-    CODEC_ID_NUV,
-    CODEC_ID_KMVC,
-    CODEC_ID_FLASHSV,
-    CODEC_ID_CAVS,
-    CODEC_ID_JPEG2000,
-    CODEC_ID_VMNC,
-    CODEC_ID_VP5,
-    CODEC_ID_VP6,
-    CODEC_ID_VP6F,
-    CODEC_ID_TARGA,
-    CODEC_ID_DSICINVIDEO,
-    CODEC_ID_TIERTEXSEQVIDEO,
-    CODEC_ID_TIFF,
-    CODEC_ID_GIF,
-    CODEC_ID_FFH264,
-    CODEC_ID_DXA,
-    CODEC_ID_DNXHD,
-    CODEC_ID_THP,
-    CODEC_ID_SGI,
-    CODEC_ID_C93,
-    CODEC_ID_BETHSOFTVID,
-    CODEC_ID_PTX,
-    CODEC_ID_TXD,
-    CODEC_ID_VP6A,
-    CODEC_ID_AMV,
-    CODEC_ID_VB,
-    CODEC_ID_PCX,
-    CODEC_ID_SUNRAST,
-    CODEC_ID_INDEO4,
-    CODEC_ID_INDEO5,
-    CODEC_ID_MIMIC,
-    CODEC_ID_RL2,
-    CODEC_ID_8SVX_EXP,
-    CODEC_ID_8SVX_FIB,
-    CODEC_ID_ESCAPE124,
-    CODEC_ID_DIRAC,
-    CODEC_ID_BFI,
-    CODEC_ID_CMV,
-    CODEC_ID_MOTIONPIXELS,
-    CODEC_ID_TGV,
-    CODEC_ID_TGQ,
-    CODEC_ID_TQI,
-    CODEC_ID_AURA,
-    CODEC_ID_AURA2,
-    CODEC_ID_V210X,
-    CODEC_ID_TMV,
-    CODEC_ID_V210,
+    AV_CODEC_ID_MPEG1VIDEO,
+    AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+    AV_CODEC_ID_MPEG2VIDEO_XVMC,
+    AV_CODEC_ID_H261,
+    AV_CODEC_ID_H263,
+    AV_CODEC_ID_RV10,
+    AV_CODEC_ID_RV20,
+    AV_CODEC_ID_MJPEG,
+    AV_CODEC_ID_MJPEGB,
+    AV_CODEC_ID_LJPEG,
+    AV_CODEC_ID_SP5X,
+    AV_CODEC_ID_JPEGLS,
+    AV_CODEC_ID_MPEG4,
+    AV_CODEC_ID_RAWVIDEO,
+    AV_CODEC_ID_MSMPEG4V1,
+    AV_CODEC_ID_MSMPEG4V2,
+    AV_CODEC_ID_MSMPEG4V3,
+    AV_CODEC_ID_WMV1,
+    AV_CODEC_ID_WMV2,
+    AV_CODEC_ID_H263P,
+    AV_CODEC_ID_H263I,
+    AV_CODEC_ID_FLV1,
+    AV_CODEC_ID_SVQ1,
+    AV_CODEC_ID_SVQ3,
+    AV_CODEC_ID_DVVIDEO,
+    AV_CODEC_ID_HUFFYUV,
+    AV_CODEC_ID_CYUV,
+    AV_CODEC_ID_H264,
+    AV_CODEC_ID_INDEO3,
+    AV_CODEC_ID_VP3,
+    AV_CODEC_ID_THEORA,
+    AV_CODEC_ID_ASV1,
+    AV_CODEC_ID_ASV2,
+    AV_CODEC_ID_FFV1,
+    AV_CODEC_ID_4XM,
+    AV_CODEC_ID_VCR1,
+    AV_CODEC_ID_CLJR,
+    AV_CODEC_ID_MDEC,
+    AV_CODEC_ID_ROQ,
+    AV_CODEC_ID_INTERPLAY_VIDEO,
+    AV_CODEC_ID_XAN_WC3,
+    AV_CODEC_ID_XAN_WC4,
+    AV_CODEC_ID_RPZA,
+    AV_CODEC_ID_CINEPAK,
+    AV_CODEC_ID_WS_VQA,
+    AV_CODEC_ID_MSRLE,
+    AV_CODEC_ID_MSVIDEO1,
+    AV_CODEC_ID_IDCIN,
+    AV_CODEC_ID_8BPS,
+    AV_CODEC_ID_SMC,
+    AV_CODEC_ID_FLIC,
+    AV_CODEC_ID_TRUEMOTION1,
+    AV_CODEC_ID_VMDVIDEO,
+    AV_CODEC_ID_MSZH,
+    AV_CODEC_ID_ZLIB,
+    AV_CODEC_ID_QTRLE,
+    AV_CODEC_ID_SNOW,
+    AV_CODEC_ID_TSCC,
+    AV_CODEC_ID_ULTI,
+    AV_CODEC_ID_QDRAW,
+    AV_CODEC_ID_VIXL,
+    AV_CODEC_ID_QPEG,
+    AV_CODEC_ID_PNG,
+    AV_CODEC_ID_PPM,
+    AV_CODEC_ID_PBM,
+    AV_CODEC_ID_PGM,
+    AV_CODEC_ID_PGMYUV,
+    AV_CODEC_ID_PAM,
+    AV_CODEC_ID_FFVHUFF,
+    AV_CODEC_ID_RV30,
+    AV_CODEC_ID_RV40,
+    AV_CODEC_ID_VC1,
+    AV_CODEC_ID_WMV3,
+    AV_CODEC_ID_LOCO,
+    AV_CODEC_ID_WNV1,
+    AV_CODEC_ID_AASC,
+    AV_CODEC_ID_INDEO2,
+    AV_CODEC_ID_FRAPS,
+    AV_CODEC_ID_TRUEMOTION2,
+    AV_CODEC_ID_BMP,
+    AV_CODEC_ID_CSCD,
+    AV_CODEC_ID_MMVIDEO,
+    AV_CODEC_ID_ZMBV,
+    AV_CODEC_ID_AVS,
+    AV_CODEC_ID_SMACKVIDEO,
+    AV_CODEC_ID_NUV,
+    AV_CODEC_ID_KMVC,
+    AV_CODEC_ID_FLASHSV,
+    AV_CODEC_ID_CAVS,
+    AV_CODEC_ID_JPEG2000,
+    AV_CODEC_ID_VMNC,
+    AV_CODEC_ID_VP5,
+    AV_CODEC_ID_VP6,
+    AV_CODEC_ID_VP6F,
+    AV_CODEC_ID_TARGA,
+    AV_CODEC_ID_DSICINVIDEO,
+    AV_CODEC_ID_TIERTEXSEQVIDEO,
+    AV_CODEC_ID_TIFF,
+    AV_CODEC_ID_GIF,
+    AV_CODEC_ID_DXA,
+    AV_CODEC_ID_DNXHD,
+    AV_CODEC_ID_THP,
+    AV_CODEC_ID_SGI,
+    AV_CODEC_ID_C93,
+    AV_CODEC_ID_BETHSOFTVID,
+    AV_CODEC_ID_PTX,
+    AV_CODEC_ID_TXD,
+    AV_CODEC_ID_VP6A,
+    AV_CODEC_ID_AMV,
+    AV_CODEC_ID_VB,
+    AV_CODEC_ID_PCX,
+    AV_CODEC_ID_SUNRAST,
+    AV_CODEC_ID_INDEO4,
+    AV_CODEC_ID_INDEO5,
+    AV_CODEC_ID_MIMIC,
+    AV_CODEC_ID_RL2,
+    AV_CODEC_ID_ESCAPE124,
+    AV_CODEC_ID_DIRAC,
+    AV_CODEC_ID_BFI,
+    AV_CODEC_ID_CMV,
+    AV_CODEC_ID_MOTIONPIXELS,
+    AV_CODEC_ID_TGV,
+    AV_CODEC_ID_TGQ,
+    AV_CODEC_ID_TQI,
+    AV_CODEC_ID_AURA,
+    AV_CODEC_ID_AURA2,
+    AV_CODEC_ID_V210X,
+    AV_CODEC_ID_TMV,
+    AV_CODEC_ID_V210,
+    AV_CODEC_ID_DPX,
+    AV_CODEC_ID_MAD,
+    AV_CODEC_ID_FRWU,
+    AV_CODEC_ID_FLASHSV2,
+    AV_CODEC_ID_CDGRAPHICS,
+    AV_CODEC_ID_R210,
+    AV_CODEC_ID_ANM,
+    AV_CODEC_ID_BINKVIDEO,
+    AV_CODEC_ID_IFF_ILBM,
+    AV_CODEC_ID_IFF_BYTERUN1,
+    AV_CODEC_ID_KGV1,
+    AV_CODEC_ID_YOP,
+    AV_CODEC_ID_VP8,
+    AV_CODEC_ID_PICTOR,
+    AV_CODEC_ID_ANSI,
+    AV_CODEC_ID_A64_MULTI,
+    AV_CODEC_ID_A64_MULTI5,
+    AV_CODEC_ID_R10K,
+    AV_CODEC_ID_MXPEG,
+    AV_CODEC_ID_LAGARITH,
+    AV_CODEC_ID_PRORES,
+    AV_CODEC_ID_JV,
+    AV_CODEC_ID_DFA,
+    AV_CODEC_ID_WMV3IMAGE,
+    AV_CODEC_ID_VC1IMAGE,
+    AV_CODEC_ID_UTVIDEO,
+    AV_CODEC_ID_BMV_VIDEO,
+    AV_CODEC_ID_VBLE,
+    AV_CODEC_ID_DXTORY,
+    AV_CODEC_ID_V410,
+    AV_CODEC_ID_XWD,
+    AV_CODEC_ID_CDXL,
+    AV_CODEC_ID_XBM,
+    AV_CODEC_ID_ZEROCODEC,
+    AV_CODEC_ID_MSS1,
+    AV_CODEC_ID_MSA1,
+    AV_CODEC_ID_TSCC2,
+    AV_CODEC_ID_MTS2,
+    AV_CODEC_ID_CLLC,
+    AV_CODEC_ID_MSS2,
+    AV_CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
+    AV_CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'),
+    AV_CODEC_ID_EXR        = MKBETAG('0','E','X','R'),
+    AV_CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
+
+    AV_CODEC_ID_G2M        = MKBETAG( 0 ,'G','2','M'),
+    AV_CODEC_ID_AVUI       = MKBETAG('A','V','U','I'),
+    AV_CODEC_ID_AYUV       = MKBETAG('A','Y','U','V'),
+    AV_CODEC_ID_TARGA_Y216 = MKBETAG('T','2','1','6'),
+    AV_CODEC_ID_V308       = MKBETAG('V','3','0','8'),
+    AV_CODEC_ID_V408       = MKBETAG('V','4','0','8'),
+    AV_CODEC_ID_YUV4       = MKBETAG('Y','U','V','4'),
+    AV_CODEC_ID_SANM       = MKBETAG('S','A','N','M'),
+    AV_CODEC_ID_PAF_VIDEO  = MKBETAG('P','A','F','V'),
+    AV_CODEC_ID_AVRN       = MKBETAG('A','V','R','n'),
+    AV_CODEC_ID_CPIA       = MKBETAG('C','P','I','A'),
+    AV_CODEC_ID_XFACE      = MKBETAG('X','F','A','C'),
 
     /* various PCM "codecs" */
-    CODEC_ID_PCM_S16LE= 0x10000,
-    CODEC_ID_PCM_S16BE,
-    CODEC_ID_PCM_U16LE,
-    CODEC_ID_PCM_U16BE,
-    CODEC_ID_PCM_S8,
-    CODEC_ID_PCM_U8,
-    CODEC_ID_PCM_MULAW,
-    CODEC_ID_PCM_ALAW,
-    CODEC_ID_PCM_S32LE,
-    CODEC_ID_PCM_S32BE,
-    CODEC_ID_PCM_U32LE,
-    CODEC_ID_PCM_U32BE,
-    CODEC_ID_PCM_S24LE,
-    CODEC_ID_PCM_S24BE,
-    CODEC_ID_PCM_U24LE,
-    CODEC_ID_PCM_U24BE,
-    CODEC_ID_PCM_S24DAUD,
-    CODEC_ID_PCM_ZORK,
-    CODEC_ID_PCM_S16LE_PLANAR,
-    CODEC_ID_PCM_DVD,
-    CODEC_ID_PCM_F32BE,
-    CODEC_ID_PCM_F32LE,
-    CODEC_ID_PCM_F64BE,
-    CODEC_ID_PCM_F64LE,
+    AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
+    AV_CODEC_ID_PCM_S16LE = 0x10000,
+    AV_CODEC_ID_PCM_S16BE,
+    AV_CODEC_ID_PCM_U16LE,
+    AV_CODEC_ID_PCM_U16BE,
+    AV_CODEC_ID_PCM_S8,
+    AV_CODEC_ID_PCM_U8,
+    AV_CODEC_ID_PCM_MULAW,
+    AV_CODEC_ID_PCM_ALAW,
+    AV_CODEC_ID_PCM_S32LE,
+    AV_CODEC_ID_PCM_S32BE,
+    AV_CODEC_ID_PCM_U32LE,
+    AV_CODEC_ID_PCM_U32BE,
+    AV_CODEC_ID_PCM_S24LE,
+    AV_CODEC_ID_PCM_S24BE,
+    AV_CODEC_ID_PCM_U24LE,
+    AV_CODEC_ID_PCM_U24BE,
+    AV_CODEC_ID_PCM_S24DAUD,
+    AV_CODEC_ID_PCM_ZORK,
+    AV_CODEC_ID_PCM_S16LE_PLANAR,
+    AV_CODEC_ID_PCM_DVD,
+    AV_CODEC_ID_PCM_F32BE,
+    AV_CODEC_ID_PCM_F32LE,
+    AV_CODEC_ID_PCM_F64BE,
+    AV_CODEC_ID_PCM_F64LE,
+    AV_CODEC_ID_PCM_BLURAY,
+    AV_CODEC_ID_PCM_LXF,
+    AV_CODEC_ID_S302M,
+    AV_CODEC_ID_PCM_S8_PLANAR,
 
     /* various ADPCM codecs */
-    CODEC_ID_ADPCM_IMA_QT= 0x11000,
-    CODEC_ID_ADPCM_IMA_WAV,
-    CODEC_ID_ADPCM_IMA_DK3,
-    CODEC_ID_ADPCM_IMA_DK4,
-    CODEC_ID_ADPCM_IMA_WS,
-    CODEC_ID_ADPCM_IMA_SMJPEG,
-    CODEC_ID_ADPCM_MS,
-    CODEC_ID_ADPCM_4XM,
-    CODEC_ID_ADPCM_XA,
-    CODEC_ID_ADPCM_ADX,
-    CODEC_ID_ADPCM_EA,
-    CODEC_ID_ADPCM_G726,
-    CODEC_ID_ADPCM_CT,
-    CODEC_ID_ADPCM_SWF,
-    CODEC_ID_ADPCM_YAMAHA,
-    CODEC_ID_ADPCM_SBPRO_4,
-    CODEC_ID_ADPCM_SBPRO_3,
-    CODEC_ID_ADPCM_SBPRO_2,
-    CODEC_ID_ADPCM_THP,
-    CODEC_ID_ADPCM_IMA_AMV,
-    CODEC_ID_ADPCM_EA_R1,
-    CODEC_ID_ADPCM_EA_R3,
-    CODEC_ID_ADPCM_EA_R2,
-    CODEC_ID_ADPCM_IMA_EA_SEAD,
-    CODEC_ID_ADPCM_IMA_EA_EACS,
-    CODEC_ID_ADPCM_EA_XAS,
-    CODEC_ID_ADPCM_EA_MAXIS_XA,
-    CODEC_ID_ADPCM_IMA_ISS,
+    AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
+    AV_CODEC_ID_ADPCM_IMA_WAV,
+    AV_CODEC_ID_ADPCM_IMA_DK3,
+    AV_CODEC_ID_ADPCM_IMA_DK4,
+    AV_CODEC_ID_ADPCM_IMA_WS,
+    AV_CODEC_ID_ADPCM_IMA_SMJPEG,
+    AV_CODEC_ID_ADPCM_MS,
+    AV_CODEC_ID_ADPCM_4XM,
+    AV_CODEC_ID_ADPCM_XA,
+    AV_CODEC_ID_ADPCM_ADX,
+    AV_CODEC_ID_ADPCM_EA,
+    AV_CODEC_ID_ADPCM_G726,
+    AV_CODEC_ID_ADPCM_CT,
+    AV_CODEC_ID_ADPCM_SWF,
+    AV_CODEC_ID_ADPCM_YAMAHA,
+    AV_CODEC_ID_ADPCM_SBPRO_4,
+    AV_CODEC_ID_ADPCM_SBPRO_3,
+    AV_CODEC_ID_ADPCM_SBPRO_2,
+    AV_CODEC_ID_ADPCM_THP,
+    AV_CODEC_ID_ADPCM_IMA_AMV,
+    AV_CODEC_ID_ADPCM_EA_R1,
+    AV_CODEC_ID_ADPCM_EA_R3,
+    AV_CODEC_ID_ADPCM_EA_R2,
+    AV_CODEC_ID_ADPCM_IMA_EA_SEAD,
+    AV_CODEC_ID_ADPCM_IMA_EA_EACS,
+    AV_CODEC_ID_ADPCM_EA_XAS,
+    AV_CODEC_ID_ADPCM_EA_MAXIS_XA,
+    AV_CODEC_ID_ADPCM_IMA_ISS,
+    AV_CODEC_ID_ADPCM_G722,
+    AV_CODEC_ID_ADPCM_IMA_APC,
+    AV_CODEC_ID_VIMA       = MKBETAG('V','I','M','A'),
 
     /* AMR */
-    CODEC_ID_AMR_NB= 0x12000,
-    CODEC_ID_AMR_WB,
+    AV_CODEC_ID_AMR_NB = 0x12000,
+    AV_CODEC_ID_AMR_WB,
 
     /* RealAudio codecs*/
-    CODEC_ID_RA_144= 0x13000,
-    CODEC_ID_RA_288,
+    AV_CODEC_ID_RA_144 = 0x13000,
+    AV_CODEC_ID_RA_288,
 
     /* various DPCM codecs */
-    CODEC_ID_ROQ_DPCM= 0x14000,
-    CODEC_ID_INTERPLAY_DPCM,
-    CODEC_ID_XAN_DPCM,
-    CODEC_ID_SOL_DPCM,
+    AV_CODEC_ID_ROQ_DPCM = 0x14000,
+    AV_CODEC_ID_INTERPLAY_DPCM,
+    AV_CODEC_ID_XAN_DPCM,
+    AV_CODEC_ID_SOL_DPCM,
 
     /* audio codecs */
-    CODEC_ID_MP2= 0x15000,
-    CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
-    CODEC_ID_AAC,
-    CODEC_ID_AC3,
-    CODEC_ID_DTS,
-    CODEC_ID_VORBIS,
-    CODEC_ID_DVAUDIO,
-    CODEC_ID_WMAV1,
-    CODEC_ID_WMAV2,
-    CODEC_ID_MACE3,
-    CODEC_ID_MACE6,
-    CODEC_ID_VMDAUDIO,
-    CODEC_ID_SONIC,
-    CODEC_ID_SONIC_LS,
-    CODEC_ID_FLAC,
-    CODEC_ID_MP3ADU,
-    CODEC_ID_MP3ON4,
-    CODEC_ID_SHORTEN,
-    CODEC_ID_ALAC,
-    CODEC_ID_WESTWOOD_SND1,
-    CODEC_ID_GSM, ///< as in Berlin toast format
-    CODEC_ID_QDM2,
-    CODEC_ID_COOK,
-    CODEC_ID_TRUESPEECH,
-    CODEC_ID_TTA,
-    CODEC_ID_SMACKAUDIO,
-    CODEC_ID_QCELP,
-    CODEC_ID_WAVPACK,
-    CODEC_ID_DSICINAUDIO,
-    CODEC_ID_IMC,
-    CODEC_ID_MUSEPACK7,
-    CODEC_ID_MLP,
-    CODEC_ID_GSM_MS, /* as found in WAV */
-    CODEC_ID_ATRAC3,
-    CODEC_ID_VOXWARE,
-    CODEC_ID_APE,
-    CODEC_ID_NELLYMOSER,
-    CODEC_ID_MUSEPACK8,
-    CODEC_ID_SPEEX,
-    CODEC_ID_WMAVOICE,
-    CODEC_ID_WMAPRO,
-    CODEC_ID_WMALOSSLESS,
-    CODEC_ID_ATRAC3P,
-    CODEC_ID_EAC3,
-    CODEC_ID_SIPR,
-    CODEC_ID_MP1,
-    CODEC_ID_TWINVQ,
-    CODEC_ID_TRUEHD,
-    CODEC_ID_MP4ALS,
+    AV_CODEC_ID_MP2 = 0x15000,
+    AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
+    AV_CODEC_ID_AAC,
+    AV_CODEC_ID_AC3,
+    AV_CODEC_ID_DTS,
+    AV_CODEC_ID_VORBIS,
+    AV_CODEC_ID_DVAUDIO,
+    AV_CODEC_ID_WMAV1,
+    AV_CODEC_ID_WMAV2,
+    AV_CODEC_ID_MACE3,
+    AV_CODEC_ID_MACE6,
+    AV_CODEC_ID_VMDAUDIO,
+    AV_CODEC_ID_FLAC,
+    AV_CODEC_ID_MP3ADU,
+    AV_CODEC_ID_MP3ON4,
+    AV_CODEC_ID_SHORTEN,
+    AV_CODEC_ID_ALAC,
+    AV_CODEC_ID_WESTWOOD_SND1,
+    AV_CODEC_ID_GSM, ///< as in Berlin toast format
+    AV_CODEC_ID_QDM2,
+    AV_CODEC_ID_COOK,
+    AV_CODEC_ID_TRUESPEECH,
+    AV_CODEC_ID_TTA,
+    AV_CODEC_ID_SMACKAUDIO,
+    AV_CODEC_ID_QCELP,
+    AV_CODEC_ID_WAVPACK,
+    AV_CODEC_ID_DSICINAUDIO,
+    AV_CODEC_ID_IMC,
+    AV_CODEC_ID_MUSEPACK7,
+    AV_CODEC_ID_MLP,
+    AV_CODEC_ID_GSM_MS, /* as found in WAV */
+    AV_CODEC_ID_ATRAC3,
+    AV_CODEC_ID_VOXWARE,
+    AV_CODEC_ID_APE,
+    AV_CODEC_ID_NELLYMOSER,
+    AV_CODEC_ID_MUSEPACK8,
+    AV_CODEC_ID_SPEEX,
+    AV_CODEC_ID_WMAVOICE,
+    AV_CODEC_ID_WMAPRO,
+    AV_CODEC_ID_WMALOSSLESS,
+    AV_CODEC_ID_ATRAC3P,
+    AV_CODEC_ID_EAC3,
+    AV_CODEC_ID_SIPR,
+    AV_CODEC_ID_MP1,
+    AV_CODEC_ID_TWINVQ,
+    AV_CODEC_ID_TRUEHD,
+    AV_CODEC_ID_MP4ALS,
+    AV_CODEC_ID_ATRAC1,
+    AV_CODEC_ID_BINKAUDIO_RDFT,
+    AV_CODEC_ID_BINKAUDIO_DCT,
+    AV_CODEC_ID_AAC_LATM,
+    AV_CODEC_ID_QDMC,
+    AV_CODEC_ID_CELT,
+    AV_CODEC_ID_G723_1,
+    AV_CODEC_ID_G729,
+    AV_CODEC_ID_8SVX_EXP,
+    AV_CODEC_ID_8SVX_FIB,
+    AV_CODEC_ID_BMV_AUDIO,
+    AV_CODEC_ID_RALF,
+    AV_CODEC_ID_IAC,
+    AV_CODEC_ID_ILBC,
+    AV_CODEC_ID_OPUS_DEPRECATED,
+    AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
+    AV_CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
+    AV_CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
+    AV_CODEC_ID_SONIC_LS    = MKBETAG('S','O','N','L'),
+    AV_CODEC_ID_PAF_AUDIO   = MKBETAG('P','A','F','A'),
+    AV_CODEC_ID_OPUS        = MKBETAG('O','P','U','S'),
+    AV_CODEC_ID_TAK         = MKBETAG('t','B','a','K'),
 
     /* subtitle codecs */
-    CODEC_ID_DVD_SUBTITLE= 0x17000,
-    CODEC_ID_DVB_SUBTITLE,
-    CODEC_ID_TEXT,  ///< raw UTF-8 text
-    CODEC_ID_XSUB,
-    CODEC_ID_SSA,
-    CODEC_ID_MOV_TEXT,
+    AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
+    AV_CODEC_ID_DVD_SUBTITLE = 0x17000,
+    AV_CODEC_ID_DVB_SUBTITLE,
+    AV_CODEC_ID_TEXT,  ///< raw UTF-8 text
+    AV_CODEC_ID_XSUB,
+    AV_CODEC_ID_SSA,
+    AV_CODEC_ID_MOV_TEXT,
+    AV_CODEC_ID_HDMV_PGS_SUBTITLE,
+    AV_CODEC_ID_DVB_TELETEXT,
+    AV_CODEC_ID_SRT,
+    AV_CODEC_ID_MICRODVD   = MKBETAG('m','D','V','D'),
+    AV_CODEC_ID_EIA_608    = MKBETAG('c','6','0','8'),
+    AV_CODEC_ID_JACOSUB    = MKBETAG('J','S','U','B'),
+    AV_CODEC_ID_SAMI       = MKBETAG('S','A','M','I'),
+    AV_CODEC_ID_REALTEXT   = MKBETAG('R','T','X','T'),
+    AV_CODEC_ID_SUBVIEWER  = MKBETAG('S','u','b','V'),
+    AV_CODEC_ID_SUBRIP     = MKBETAG('S','R','i','p'),
+    AV_CODEC_ID_WEBVTT     = MKBETAG('W','V','T','T'),
 
     /* other specific kind of codecs (generally used for attachments) */
-    CODEC_ID_TTF= 0x18000,
+    AV_CODEC_ID_FIRST_UNKNOWN = 0x18000,           ///< A dummy ID pointing at the start of various fake codecs.
+    AV_CODEC_ID_TTF = 0x18000,
+    AV_CODEC_ID_BINTEXT    = MKBETAG('B','T','X','T'),
+    AV_CODEC_ID_XBIN       = MKBETAG('X','B','I','N'),
+    AV_CODEC_ID_IDF        = MKBETAG( 0 ,'I','D','F'),
+    AV_CODEC_ID_OTF        = MKBETAG( 0 ,'O','T','F'),
 
-    CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
+    AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
 
-    CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
+    AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
                                 * stream (only used by libavformat) */
-};
+    AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
+                                * stream (only used by libavformat) */
+    AV_CODEC_ID_FFMETADATA = 0x21000,   ///< Dummy codec for streams containing only metadata information.
 
-enum CodecType {
-    CODEC_TYPE_UNKNOWN = -1,
-    CODEC_TYPE_VIDEO,
-    CODEC_TYPE_AUDIO,
-    CODEC_TYPE_DATA,
-    CODEC_TYPE_SUBTITLE,
-    CODEC_TYPE_ATTACHMENT,
-    CODEC_TYPE_NB
+#if FF_API_CODEC_ID
+#include "old_codec_ids.h"
+#endif
 };
 
+#if FF_API_CODEC_ID
+#define CodecID AVCodecID
+#endif
+
 /**
- * all in native-endian format
+ * This struct describes the properties of a single codec described by an
+ * AVCodecID.
+ * @see avcodec_get_descriptor()
  */
-enum SampleFormat {
-    SAMPLE_FMT_NONE = -1,
-    SAMPLE_FMT_U8,              ///< unsigned 8 bits
-    SAMPLE_FMT_S16,             ///< signed 16 bits
-    SAMPLE_FMT_S32,             ///< signed 32 bits
-    SAMPLE_FMT_FLT,             ///< float
-    SAMPLE_FMT_DBL,             ///< double
-    SAMPLE_FMT_NB               ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec
-};
+typedef struct AVCodecDescriptor {
+    enum AVCodecID     id;
+    enum AVMediaType type;
+    /**
+     * Name of the codec described by this descriptor. It is non-empty and
+     * unique for each codec descriptor. It should contain alphanumeric
+     * characters and '_' only.
+     */
+    const char      *name;
+    /**
+     * A more descriptive name for this codec. May be NULL.
+     */
+    const char *long_name;
+    /**
+     * Codec properties, a combination of AV_CODEC_PROP_* flags.
+     */
+    int             props;
+} AVCodecDescriptor;
 
-/* Audio channel masks */
-#define CH_FRONT_LEFT             0x00000001
-#define CH_FRONT_RIGHT            0x00000002
-#define CH_FRONT_CENTER           0x00000004
-#define CH_LOW_FREQUENCY          0x00000008
-#define CH_BACK_LEFT              0x00000010
-#define CH_BACK_RIGHT             0x00000020
-#define CH_FRONT_LEFT_OF_CENTER   0x00000040
-#define CH_FRONT_RIGHT_OF_CENTER  0x00000080
-#define CH_BACK_CENTER            0x00000100
-#define CH_SIDE_LEFT              0x00000200
-#define CH_SIDE_RIGHT             0x00000400
-#define CH_TOP_CENTER             0x00000800
-#define CH_TOP_FRONT_LEFT         0x00001000
-#define CH_TOP_FRONT_CENTER       0x00002000
-#define CH_TOP_FRONT_RIGHT        0x00004000
-#define CH_TOP_BACK_LEFT          0x00008000
-#define CH_TOP_BACK_CENTER        0x00010000
-#define CH_TOP_BACK_RIGHT         0x00020000
-#define CH_STEREO_LEFT            0x20000000  ///< Stereo downmix.
-#define CH_STEREO_RIGHT           0x40000000  ///< See CH_STEREO_LEFT.
-
-/* Audio channel convenience macros */
-#define CH_LAYOUT_MONO              (CH_FRONT_CENTER)
-#define CH_LAYOUT_STEREO            (CH_FRONT_LEFT|CH_FRONT_RIGHT)
-#define CH_LAYOUT_2_1               (CH_LAYOUT_STEREO|CH_BACK_CENTER)
-#define CH_LAYOUT_SURROUND          (CH_LAYOUT_STEREO|CH_FRONT_CENTER)
-#define CH_LAYOUT_4POINT0           (CH_LAYOUT_SURROUND|CH_BACK_CENTER)
-#define CH_LAYOUT_2_2               (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT)
-#define CH_LAYOUT_QUAD              (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT)
-#define CH_LAYOUT_5POINT0           (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT)
-#define CH_LAYOUT_5POINT1           (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY)
-#define CH_LAYOUT_5POINT0_BACK      (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT)
-#define CH_LAYOUT_5POINT1_BACK      (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY)
-#define CH_LAYOUT_7POINT1           (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT)
-#define CH_LAYOUT_7POINT1_WIDE      (CH_LAYOUT_5POINT1_BACK|\
-                                          CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER)
-#define CH_LAYOUT_STEREO_DOWNMIX    (CH_STEREO_LEFT|CH_STEREO_RIGHT)
+/**
+ * Codec uses only intra compression.
+ * Video codecs only.
+ */
+#define AV_CODEC_PROP_INTRA_ONLY    (1 << 0)
+/**
+ * Codec supports lossy compression. Audio and video codecs only.
+ * @note a codec may support both lossy and lossless
+ * compression modes
+ */
+#define AV_CODEC_PROP_LOSSY         (1 << 1)
+/**
+ * Codec supports lossless compression. Audio and video codecs only.
+ */
+#define AV_CODEC_PROP_LOSSLESS      (1 << 2)
 
+#if FF_API_OLD_DECODE_AUDIO
 /* in bytes */
 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+#endif
 
 /**
+ * @ingroup lavc_decoding
  * Required number of additionally allocated bytes at the end of the input bitstream for decoding.
  * This is mainly needed because some optimized bitstream readers read
  * 32 or 64 bit at once and could read over the end.<br>
  * Note: If the first 23 bits of the additional bytes are not 0, then damaged
  * MPEG bitstreams could cause overread and segfault.
  */
-#define FF_INPUT_BUFFER_PADDING_SIZE 8
+#define FF_INPUT_BUFFER_PADDING_SIZE 16
 
 /**
+ * @ingroup lavc_encoding
  * minimum encoding buffer size
  * Used to avoid some checks during header writing.
  */
@@ -417,6 +543,7 @@ enum SampleFormat {
 
 
 /**
+ * @ingroup lavc_encoding
  * motion estimation type.
  */
 enum Motion_Est_ID {
@@ -432,52 +559,58 @@ enum Motion_Est_ID {
     ME_TESA,        ///< transformed exhaustive search algorithm
 };
 
+/**
+ * @ingroup lavc_decoding
+ */
 enum AVDiscard{
     /* We leave some space between them for extensions (drop some
      * keyframes for intra-only or drop just some bidir frames). */
-    AVDISCARD_NONE   =-16, ///< discard nothing
-    AVDISCARD_DEFAULT=  0, ///< discard useless packets like 0 size packets in avi
-    AVDISCARD_NONREF =  8, ///< discard all non reference
-    AVDISCARD_BIDIR  = 16, ///< discard all bidirectional frames
-    AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
-    AVDISCARD_ALL    = 48, ///< discard all
+    AVDISCARD_NONE    =-16, ///< discard nothing
+    AVDISCARD_DEFAULT =  0, ///< discard useless packets like 0 size packets in avi
+    AVDISCARD_NONREF  =  8, ///< discard all non reference
+    AVDISCARD_BIDIR   = 16, ///< discard all bidirectional frames
+    AVDISCARD_NONKEY  = 32, ///< discard all frames except keyframes
+    AVDISCARD_ALL     = 48, ///< discard all
 };
 
 enum AVColorPrimaries{
-    AVCOL_PRI_BT709      =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
-    AVCOL_PRI_UNSPECIFIED=2,
-    AVCOL_PRI_BT470M     =4,
-    AVCOL_PRI_BT470BG    =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
-    AVCOL_PRI_SMPTE170M  =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
-    AVCOL_PRI_SMPTE240M  =7, ///< functionally identical to above
-    AVCOL_PRI_FILM       =8,
-    AVCOL_PRI_NB           , ///< Not part of ABI
+    AVCOL_PRI_BT709       = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
+    AVCOL_PRI_UNSPECIFIED = 2,
+    AVCOL_PRI_BT470M      = 4,
+    AVCOL_PRI_BT470BG     = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
+    AVCOL_PRI_SMPTE170M   = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+    AVCOL_PRI_SMPTE240M   = 7, ///< functionally identical to above
+    AVCOL_PRI_FILM        = 8,
+    AVCOL_PRI_NB             , ///< Not part of ABI
 };
 
 enum AVColorTransferCharacteristic{
-    AVCOL_TRC_BT709      =1, ///< also ITU-R BT1361
-    AVCOL_TRC_UNSPECIFIED=2,
-    AVCOL_TRC_GAMMA22    =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
-    AVCOL_TRC_GAMMA28    =5, ///< also ITU-R BT470BG
-    AVCOL_TRC_NB           , ///< Not part of ABI
+    AVCOL_TRC_BT709       = 1, ///< also ITU-R BT1361
+    AVCOL_TRC_UNSPECIFIED = 2,
+    AVCOL_TRC_GAMMA22     = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+    AVCOL_TRC_GAMMA28     = 5, ///< also ITU-R BT470BG
+    AVCOL_TRC_SMPTE240M   = 7,
+    AVCOL_TRC_NB             , ///< Not part of ABI
 };
 
 enum AVColorSpace{
-    AVCOL_SPC_RGB        =0,
-    AVCOL_SPC_BT709      =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
-    AVCOL_SPC_UNSPECIFIED=2,
-    AVCOL_SPC_FCC        =4,
-    AVCOL_SPC_BT470BG    =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
-    AVCOL_SPC_SMPTE170M  =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
-    AVCOL_SPC_SMPTE240M  =7,
-    AVCOL_SPC_NB           , ///< Not part of ABI
+    AVCOL_SPC_RGB         = 0,
+    AVCOL_SPC_BT709       = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+    AVCOL_SPC_UNSPECIFIED = 2,
+    AVCOL_SPC_FCC         = 4,
+    AVCOL_SPC_BT470BG     = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+    AVCOL_SPC_SMPTE170M   = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+    AVCOL_SPC_SMPTE240M   = 7,
+    AVCOL_SPC_YCOCG       = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+    AVCOL_SPC_NB             , ///< Not part of ABI
 };
+#define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG
 
 enum AVColorRange{
-    AVCOL_RANGE_UNSPECIFIED=0,
-    AVCOL_RANGE_MPEG       =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
-    AVCOL_RANGE_JPEG       =2, ///< the normal     2^n-1   "JPEG" YUV ranges
-    AVCOL_RANGE_NB           , ///< Not part of ABI
+    AVCOL_RANGE_UNSPECIFIED = 0,
+    AVCOL_RANGE_MPEG        = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
+    AVCOL_RANGE_JPEG        = 2, ///< the normal     2^n-1   "JPEG" YUV ranges
+    AVCOL_RANGE_NB             , ///< Not part of ABI
 };
 
 /**
@@ -486,16 +619,32 @@ enum AVColorRange{
  *  X   X      5 6 X      0 is undefined/unknown position
  */
 enum AVChromaLocation{
-    AVCHROMA_LOC_UNSPECIFIED=0,
-    AVCHROMA_LOC_LEFT       =1, ///< mpeg2/4, h264 default
-    AVCHROMA_LOC_CENTER     =2, ///< mpeg1, jpeg, h263
-    AVCHROMA_LOC_TOPLEFT    =3, ///< DV
-    AVCHROMA_LOC_TOP        =4,
-    AVCHROMA_LOC_BOTTOMLEFT =5,
-    AVCHROMA_LOC_BOTTOM     =6,
-    AVCHROMA_LOC_NB           , ///< Not part of ABI
+    AVCHROMA_LOC_UNSPECIFIED = 0,
+    AVCHROMA_LOC_LEFT        = 1, ///< mpeg2/4, h264 default
+    AVCHROMA_LOC_CENTER      = 2, ///< mpeg1, jpeg, h263
+    AVCHROMA_LOC_TOPLEFT     = 3, ///< DV
+    AVCHROMA_LOC_TOP         = 4,
+    AVCHROMA_LOC_BOTTOMLEFT  = 5,
+    AVCHROMA_LOC_BOTTOM      = 6,
+    AVCHROMA_LOC_NB             , ///< Not part of ABI
+};
+
+enum AVAudioServiceType {
+    AV_AUDIO_SERVICE_TYPE_MAIN              = 0,
+    AV_AUDIO_SERVICE_TYPE_EFFECTS           = 1,
+    AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2,
+    AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED  = 3,
+    AV_AUDIO_SERVICE_TYPE_DIALOGUE          = 4,
+    AV_AUDIO_SERVICE_TYPE_COMMENTARY        = 5,
+    AV_AUDIO_SERVICE_TYPE_EMERGENCY         = 6,
+    AV_AUDIO_SERVICE_TYPE_VOICE_OVER        = 7,
+    AV_AUDIO_SERVICE_TYPE_KARAOKE           = 8,
+    AV_AUDIO_SERVICE_TYPE_NB                   , ///< Not part of ABI
 };
 
+/**
+ * @ingroup lavc_encoding
+ */
 typedef struct RcOverride{
     int start_frame;
     int end_frame;
@@ -515,7 +664,6 @@ typedef struct RcOverride{
 #define CODEC_FLAG_QPEL   0x0010  ///< Use qpel MC.
 #define CODEC_FLAG_GMC    0x0020  ///< Use GMC.
 #define CODEC_FLAG_MV0    0x0040  ///< Always try a MB with MV=<0,0>.
-#define CODEC_FLAG_PART   0x0080  ///< Use data partitioning.
 /**
  * The parent program guarantees that the input for B-frames containing
  * streams is not written to for at least s->max_b_frames+1 frames, if
@@ -524,7 +672,6 @@ typedef struct RcOverride{
 #define CODEC_FLAG_INPUT_PRESERVED 0x0100
 #define CODEC_FLAG_PASS1           0x0200   ///< Use internal 2pass ratecontrol in first pass mode.
 #define CODEC_FLAG_PASS2           0x0400   ///< Use internal 2pass ratecontrol in second pass mode.
-#define CODEC_FLAG_EXTERN_HUFF     0x1000   ///< Use external Huffman table (for MJPEG).
 #define CODEC_FLAG_GRAY            0x2000   ///< Only decode/encode grayscale.
 #define CODEC_FLAG_EMU_EDGE        0x4000   ///< Don't draw edges.
 #define CODEC_FLAG_PSNR            0x8000   ///< error[?] variables will be set during encoding.
@@ -533,39 +680,25 @@ typedef struct RcOverride{
 #define CODEC_FLAG_NORMALIZE_AQP  0x00020000 ///< Normalize adaptive quantization.
 #define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT.
 #define CODEC_FLAG_LOW_DELAY      0x00080000 ///< Force low delay.
-#define CODEC_FLAG_ALT_SCAN       0x00100000 ///< Use alternate scan.
 #define CODEC_FLAG_GLOBAL_HEADER  0x00400000 ///< Place global headers in extradata instead of every keyframe.
 #define CODEC_FLAG_BITEXACT       0x00800000 ///< Use only bitexact stuff (except (I)DCT).
 /* Fx : Flag for h263+ extra options */
 #define CODEC_FLAG_AC_PRED        0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction
-#define CODEC_FLAG_H263P_UMV      0x02000000 ///< unlimited motion vector
-#define CODEC_FLAG_CBP_RD         0x04000000 ///< Use rate distortion optimization for cbp.
-#define CODEC_FLAG_QP_RD          0x08000000 ///< Use rate distortion optimization for qp selectioon.
-#define CODEC_FLAG_H263P_AIV      0x00000008 ///< H.263 alternative inter VLC
-#define CODEC_FLAG_OBMC           0x00000001 ///< OBMC
 #define CODEC_FLAG_LOOP_FILTER    0x00000800 ///< loop filter
-#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000
 #define CODEC_FLAG_INTERLACED_ME  0x20000000 ///< interlaced motion estimation
-#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data.
 #define CODEC_FLAG_CLOSED_GOP     0x80000000
 #define CODEC_FLAG2_FAST          0x00000001 ///< Allow non spec compliant speedup tricks.
-#define CODEC_FLAG2_STRICT_GOP    0x00000002 ///< Strictly enforce GOP size.
 #define CODEC_FLAG2_NO_OUTPUT     0x00000004 ///< Skip bitstream encoding.
 #define CODEC_FLAG2_LOCAL_HEADER  0x00000008 ///< Place global headers at every keyframe instead of in extradata.
-#define CODEC_FLAG2_BPYRAMID      0x00000010 ///< H.264 allow B-frames to be used as references.
-#define CODEC_FLAG2_WPRED         0x00000020 ///< H.264 weighted biprediction for B-frames
-#define CODEC_FLAG2_MIXED_REFS    0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock
-#define CODEC_FLAG2_8X8DCT        0x00000080 ///< H.264 high profile 8x8 transform
-#define CODEC_FLAG2_FASTPSKIP     0x00000100 ///< H.264 fast pskip
-#define CODEC_FLAG2_AUD           0x00000200 ///< H.264 access unit delimiters
-#define CODEC_FLAG2_BRDO          0x00000400 ///< B-frame rate-distortion optimization
-#define CODEC_FLAG2_INTRA_VLC     0x00000800 ///< Use MPEG-2 intra VLC table.
-#define CODEC_FLAG2_MEMC_ONLY     0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
-#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format.
+#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. DEPRECATED!!!!
+#if FF_API_MPV_GLOBAL_OPTS
+#define CODEC_FLAG_CBP_RD         0x04000000 ///< Use rate distortion optimization for cbp.
+#define CODEC_FLAG_QP_RD          0x08000000 ///< Use rate distortion optimization for qp selectioon.
+#define CODEC_FLAG2_STRICT_GOP    0x00000002 ///< Strictly enforce GOP size.
 #define CODEC_FLAG2_SKIP_RD       0x00004000 ///< RD optimal MB level residual skipping
+#endif
 #define CODEC_FLAG2_CHUNKS        0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
-#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer.
-#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible
+#define CODEC_FLAG2_SHOW_ALL      0x00400000 ///< Show all frames before the first keyframe
 
 /* Unsupported options :
  *              Syntax Arithmetic coding (SAC)
@@ -576,18 +709,36 @@ typedef struct RcOverride{
 
 #define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback.
 /**
- * Codec uses get_buffer() for allocating buffers.
- * direct rendering method 1
+ * Codec uses get_buffer() for allocating buffers and supports custom allocators.
+ * If not set, it might not use get_buffer() at all or use operations that
+ * assume the buffer was allocated by avcodec_default_get_buffer.
  */
 #define CODEC_CAP_DR1             0x0002
-/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */
-#define CODEC_CAP_PARSE_ONLY      0x0004
 #define CODEC_CAP_TRUNCATED       0x0008
 /* Codec can export data for HW decoding (XvMC). */
 #define CODEC_CAP_HWACCEL         0x0010
 /**
- * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data.
- * If this is not set, the codec is guaranteed to never be fed with NULL data.
+ * Encoder or decoder requires flushing with NULL input at the end in order to
+ * give the complete and correct output.
+ *
+ * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
+ *       with NULL data. The user can still send NULL data to the public encode
+ *       or decode function, but libavcodec will not pass it along to the codec
+ *       unless this flag is set.
+ *
+ * Decoders:
+ * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to get the delayed data until the decoder no longer
+ * returns frames.
+ *
+ * Encoders:
+ * The encoder needs to be fed with NULL data at the end of encoding until the
+ * encoder no longer returns data.
+ *
+ * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
+ *       flag also means that the encoder must set the pts and duration for
+ *       each output packet. If this flag is not set, the pts and duration will
+ *       be determined by libavcodec from the input frame.
  */
 #define CODEC_CAP_DELAY           0x0020
 /**
@@ -599,6 +750,61 @@ typedef struct RcOverride{
  * Codec can export data for HW decoding (VDPAU).
  */
 #define CODEC_CAP_HWACCEL_VDPAU    0x0080
+/**
+ * Codec can output multiple frames per AVPacket
+ * Normally demuxers return one frame at a time, demuxers which do not do
+ * are connected to a parser to split what they return into proper frames.
+ * This flag is reserved to the very rare category of codecs which have a
+ * bitstream that cannot be split into frames without timeconsuming
+ * operations like full decoding. Demuxers carring such bitstreams thus
+ * may return multiple frames in a packet. This has many disadvantages like
+ * prohibiting stream copy in many cases thus it should only be considered
+ * as a last resort.
+ */
+#define CODEC_CAP_SUBFRAMES        0x0100
+/**
+ * Codec is experimental and is thus avoided in favor of non experimental
+ * encoders
+ */
+#define CODEC_CAP_EXPERIMENTAL     0x0200
+/**
+ * Codec should fill in channel configuration and samplerate instead of container
+ */
+#define CODEC_CAP_CHANNEL_CONF     0x0400
+
+/**
+ * Codec is able to deal with negative linesizes
+ */
+#define CODEC_CAP_NEG_LINESIZES    0x0800
+
+/**
+ * Codec supports frame-level multithreading.
+ */
+#define CODEC_CAP_FRAME_THREADS    0x1000
+/**
+ * Codec supports slice-based (or partition-based) multithreading.
+ */
+#define CODEC_CAP_SLICE_THREADS    0x2000
+/**
+ * Codec supports changed parameters at any point.
+ */
+#define CODEC_CAP_PARAM_CHANGE     0x4000
+/**
+ * Codec supports avctx->thread_count == 0 (auto).
+ */
+#define CODEC_CAP_AUTO_THREADS     0x8000
+/**
+ * Audio encoder supports receiving a different number of samples in each call.
+ */
+#define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000
+/**
+ * Codec is intra only.
+ */
+#define CODEC_CAP_INTRA_ONLY       0x40000000
+/**
+ * Codec is lossless.
+ */
+#define CODEC_CAP_LOSSLESS         0x80000000
 
 //The following defines may change, don't expect compatibility if you use them.
 #define MB_TYPE_INTRA4x4   0x0001
@@ -653,256 +859,91 @@ typedef struct AVPanScan{
     int16_t position[3][2];
 }AVPanScan;
 
-#define FF_COMMON_FRAME \
-    /**\
-     * pointer to the picture planes.\
-     * This might be different from the first allocated byte\
-     * - encoding: \
-     * - decoding: \
-     */\
-    uint8_t *data[4];\
-    int linesize[4];\
-    /**\
-     * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\
-     * This isn't used by libavcodec unless the default get/release_buffer() is used.\
-     * - encoding: \
-     * - decoding: \
-     */\
-    uint8_t *base[4];\
-    /**\
-     * 1 -> keyframe, 0-> not\
-     * - encoding: Set by libavcodec.\
-     * - decoding: Set by libavcodec.\
-     */\
-    int key_frame;\
-\
-    /**\
-     * Picture type of the frame, see ?_TYPE below.\
-     * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\
-     * - decoding: Set by libavcodec.\
-     */\
-    int pict_type;\
-\
-    /**\
-     * presentation timestamp in time_base units (time when frame should be shown to user)\
-     * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\
-     * - encoding: MUST be set by user.\
-     * - decoding: Set by libavcodec.\
-     */\
-    int64_t pts;\
-\
-    /**\
-     * picture number in bitstream order\
-     * - encoding: set by\
-     * - decoding: Set by libavcodec.\
-     */\
-    int coded_picture_number;\
-    /**\
-     * picture number in display order\
-     * - encoding: set by\
-     * - decoding: Set by libavcodec.\
-     */\
-    int display_picture_number;\
-\
-    /**\
-     * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \
-     * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\
-     * - decoding: Set by libavcodec.\
-     */\
-    int quality; \
-\
-    /**\
-     * buffer age (1->was last buffer and dint change, 2->..., ...).\
-     * Set to INT_MAX if the buffer has not been used yet.\
-     * - encoding: unused\
-     * - decoding: MUST be set by get_buffer().\
-     */\
-    int age;\
-\
-    /**\
-     * is this picture used as reference\
-     * The values for this are the same as the MpegEncContext.picture_structure\
-     * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\
-     * Set to 4 for delayed, non-reference frames.\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec. (before get_buffer() call)).\
-     */\
-    int reference;\
-\
-    /**\
-     * QP table\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec.\
-     */\
-    int8_t *qscale_table;\
-    /**\
-     * QP store stride\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec.\
-     */\
-    int qstride;\
-\
-    /**\
-     * mbskip_table[mb]>=1 if MB didn't change\
-     * stride= mb_width = (width+15)>>4\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec.\
-     */\
-    uint8_t *mbskip_table;\
-\
-    /**\
-     * motion vector table\
-     * @code\
-     * example:\
-     * int mv_sample_log2= 4 - motion_subsample_log2;\
-     * int mb_width= (width+15)>>4;\
-     * int mv_stride= (mb_width << mv_sample_log2) + 1;\
-     * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\
-     * @endcode\
-     * - encoding: Set by user.\
-     * - decoding: Set by libavcodec.\
-     */\
-    int16_t (*motion_val[2])[2];\
-\
-    /**\
-     * macroblock type table\
-     * mb_type_base + mb_width + 2\
-     * - encoding: Set by user.\
-     * - decoding: Set by libavcodec.\
-     */\
-    uint32_t *mb_type;\
-\
-    /**\
-     * log2 of the size of the block which a single vector in motion_val represents: \
-     * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec.\
-     */\
-    uint8_t motion_subsample_log2;\
-\
-    /**\
-     * for some private data of the user\
-     * - encoding: unused\
-     * - decoding: Set by user.\
-     */\
-    void *opaque;\
-\
-    /**\
-     * error\
-     * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\
-     * - decoding: unused\
-     */\
-    uint64_t error[4];\
-\
-    /**\
-     * type of the buffer (to keep track of who has to deallocate data[*])\
-     * - encoding: Set by the one who allocates it.\
-     * - decoding: Set by the one who allocates it.\
-     * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\
-     */\
-    int type;\
-    \
-    /**\
-     * When decoding, this signals how much the picture must be delayed.\
-     * extra_delay = repeat_pict / (2*fps)\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec.\
-     */\
-    int repeat_pict;\
-    \
-    /**\
-     * \
-     */\
-    int qscale_type;\
-    \
-    /**\
-     * The content of the picture is interlaced.\
-     * - encoding: Set by user.\
-     * - decoding: Set by libavcodec. (default 0)\
-     */\
-    int interlaced_frame;\
-    \
-    /**\
-     * If the content is interlaced, is top field displayed first.\
-     * - encoding: Set by user.\
-     * - decoding: Set by libavcodec.\
-     */\
-    int top_field_first;\
-    \
-    /**\
-     * Pan scan.\
-     * - encoding: Set by user.\
-     * - decoding: Set by libavcodec.\
-     */\
-    AVPanScan *pan_scan;\
-    \
-    /**\
-     * Tell user application that palette has changed from previous frame.\
-     * - encoding: ??? (no palette-enabled encoder yet)\
-     * - decoding: Set by libavcodec. (default 0).\
-     */\
-    int palette_has_changed;\
-    \
-    /**\
-     * codec suggestion on buffer type if != 0\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec. (before get_buffer() call)).\
-     */\
-    int buffer_hints;\
-\
-    /**\
-     * DCT coefficients\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec.\
-     */\
-    short *dct_coeff;\
-\
-    /**\
-     * motion referece frame index\
-     * - encoding: Set by user.\
-     * - decoding: Set by libavcodec.\
-     */\
-    int8_t *ref_index[2];\
-\
-    /**\
-     * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\
-     * output in AVFrame.reordered_opaque\
-     * - encoding: unused\
-     * - decoding: Read by user.\
-     */\
-    int64_t reordered_opaque;\
-\
-    /**\
-     * hardware accelerator private data (FFmpeg allocated)\
-     * - encoding: unused\
-     * - decoding: Set by libavcodec\
-     */\
-    void *hwaccel_picture_private;\
-
-
 #define FF_QSCALE_TYPE_MPEG1 0
 #define FF_QSCALE_TYPE_MPEG2 1
 #define FF_QSCALE_TYPE_H264  2
+#define FF_QSCALE_TYPE_VP56  3
 
 #define FF_BUFFER_TYPE_INTERNAL 1
 #define FF_BUFFER_TYPE_USER     2 ///< direct rendering buffers (image is (de)allocated by user)
 #define FF_BUFFER_TYPE_SHARED   4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
 #define FF_BUFFER_TYPE_COPY     8 ///< Just a (modified) copy of some other buffer, don't deallocate anything.
 
-
-#define FF_I_TYPE  1 ///< Intra
-#define FF_P_TYPE  2 ///< Predicted
-#define FF_B_TYPE  3 ///< Bi-dir predicted
-#define FF_S_TYPE  4 ///< S(GMC)-VOP MPEG4
-#define FF_SI_TYPE 5 ///< Switching Intra
-#define FF_SP_TYPE 6 ///< Switching Predicted
-#define FF_BI_TYPE 7
-
 #define FF_BUFFER_HINTS_VALID    0x01 // Buffer hints value is meaningful (if 0 ignore).
 #define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
 #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
 #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
 
+/**
+ * @defgroup lavc_packet AVPacket
+ *
+ * Types and functions for working with AVPacket.
+ * @{
+ */
+enum AVPacketSideDataType {
+    AV_PKT_DATA_PALETTE,
+    AV_PKT_DATA_NEW_EXTRADATA,
+
+    /**
+     * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
+     * @code
+     * u32le param_flags
+     * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
+     *     s32le channel_count
+     * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)
+     *     u64le channel_layout
+     * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE)
+     *     s32le sample_rate
+     * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
+     *     s32le width
+     *     s32le height
+     * @endcode
+     */
+    AV_PKT_DATA_PARAM_CHANGE,
+
+    /**
+     * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of
+     * structures with info about macroblocks relevant to splitting the
+     * packet into smaller packets on macroblock edges (e.g. as for RFC 2190).
+     * That is, it does not necessarily contain info about all macroblocks,
+     * as long as the distance between macroblocks in the info is smaller
+     * than the target payload size.
+     * Each MB info structure is 12 bytes, and is laid out as follows:
+     * @code
+     * u32le bit offset from the start of the packet
+     * u8    current quantizer at the start of the macroblock
+     * u8    GOB number
+     * u16le macroblock address within the GOB
+     * u8    horizontal MV predictor
+     * u8    vertical MV predictor
+     * u8    horizontal MV predictor for block number 3
+     * u8    vertical MV predictor for block number 3
+     * @endcode
+     */
+    AV_PKT_DATA_H263_MB_INFO,
+
+    /**
+     * Recommmends skipping the specified number of samples
+     * @code
+     * u32le number of samples to skip from start of this packet
+     * u32le number of samples to skip from end of this packet
+     * u8    reason for start skip
+     * u8    reason for end   skip (0=padding silence, 1=convergence)
+     * @endcode
+     */
+    AV_PKT_DATA_SKIP_SAMPLES=70,
+
+    /**
+     * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that
+     * the packet may contain "dual mono" audio specific to Japanese DTV
+     * and if it is true, recommends only the selected channel to be used.
+     * @code
+     * u8    selected channels (0=mail/left, 1=sub/right, 2=both)
+     * @endcode
+     */
+    AV_PKT_DATA_JP_DUALMONO,
+};
+
 typedef struct AVPacket {
     /**
      * Presentation timestamp in AVStream->time_base units; the time at which
@@ -923,7 +964,21 @@ typedef struct AVPacket {
     uint8_t *data;
     int   size;
     int   stream_index;
+    /**
+     * A combination of AV_PKT_FLAG values
+     */
     int   flags;
+    /**
+     * Additional packet data that can be provided by the container.
+     * Packet can contain several types of side information.
+     */
+    struct {
+        uint8_t *data;
+        int      size;
+        enum AVPacketSideDataType type;
+    } *side_data;
+    int side_data_elems;
+
     /**
      * Duration of this packet in AVStream->time_base units, 0 if unknown.
      * Equals next_pts - this_pts in presentation order.
@@ -941,6 +996,8 @@ typedef struct AVPacket {
      * the very first frame or from this keyframe.
      * Is AV_NOPTS_VALUE if unknown.
      * This field is not the display duration of the current packet.
+     * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
+     * set.
      *
      * The purpose of this field is to allow seeking in streams that have no
      * keyframes in the conventional sense. It corresponds to the
@@ -950,780 +1007,909 @@ typedef struct AVPacket {
      */
     int64_t convergence_duration;
 } AVPacket;
-#define PKT_FLAG_KEY   0x0001
+#define AV_PKT_FLAG_KEY     0x0001 ///< The packet contains a keyframe
+#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
+
+enum AVSideDataParamChangeFlags {
+    AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT  = 0x0001,
+    AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
+    AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE    = 0x0004,
+    AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS     = 0x0008,
+};
+/**
+ * @}
+ */
 
 /**
  * Audio Video Frame.
- * New fields can be added to the end of FF_COMMON_FRAME with minor version
- * bumps.
- * Removal, reordering and changes to existing fields require a major
- * version bump. No fields should be added into AVFrame before or after
- * FF_COMMON_FRAME!
- * sizeof(AVFrame) must not be used outside libav*.
+ * New fields can be added to the end of AVFRAME with minor version
+ * bumps. Similarly fields that are marked as to be only accessed by
+ * av_opt_ptr() can be reordered. This allows 2 forks to add fields
+ * without breaking compatibility with each other.
+ * Removal, reordering and changes in the remaining cases require
+ * a major version bump.
+ * sizeof(AVFrame) must not be used outside libavcodec.
  */
 typedef struct AVFrame {
-    FF_COMMON_FRAME
-} AVFrame;
+#define AV_NUM_DATA_POINTERS 8
+    /**
+     * pointer to the picture/channel planes.
+     * This might be different from the first allocated byte
+     * - encoding: Set by user
+     * - decoding: set by AVCodecContext.get_buffer()
+     */
+    uint8_t *data[AV_NUM_DATA_POINTERS];
 
-/**
- * main external API structure.
- * New fields can be added to the end with minor version bumps.
- * Removal, reordering and changes to existing fields require a major
- * version bump.
- * sizeof(AVCodecContext) must not be used outside libav*.
- */
-typedef struct AVCodecContext {
     /**
-     * information on struct for av_log
-     * - set by avcodec_alloc_context
+     * Size, in bytes, of the data for each picture/channel plane.
+     *
+     * For audio, only linesize[0] may be set. For planar audio, each channel
+     * plane must be the same size.
+     *
+     * - encoding: Set by user
+     * - decoding: set by AVCodecContext.get_buffer()
      */
-    const AVClass *av_class;
+    int linesize[AV_NUM_DATA_POINTERS];
+
     /**
-     * the average bitrate
-     * - encoding: Set by user; unused for constant quantizer encoding.
-     * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream.
+     * pointers to the data planes/channels.
+     *
+     * For video, this should simply point to data[].
+     *
+     * For planar audio, each channel has a separate data pointer, and
+     * linesize[0] contains the size of each channel buffer.
+     * For packed audio, there is just one data pointer, and linesize[0]
+     * contains the total size of the buffer for all channels.
+     *
+     * Note: Both data and extended_data will always be set by get_buffer(),
+     * but for planar audio with more channels that can fit in data,
+     * extended_data must be used by the decoder in order to access all
+     * channels.
+     *
+     * encoding: set by user
+     * decoding: set by AVCodecContext.get_buffer()
      */
-    int bit_rate;
+    uint8_t **extended_data;
 
     /**
-     * number of bits the bitstream is allowed to diverge from the reference.
-     *           the reference can be CBR (for CBR pass1) or VBR (for pass2)
-     * - encoding: Set by user; unused for constant quantizer encoding.
-     * - decoding: unused
+     * width and height of the video frame
+     * - encoding: unused
+     * - decoding: Read by user.
      */
-    int bit_rate_tolerance;
+    int width, height;
 
     /**
-     * CODEC_FLAG_*.
-     * - encoding: Set by user.
-     * - decoding: Set by user.
+     * number of audio samples (per channel) described by this frame
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
      */
-    int flags;
+    int nb_samples;
+
+    /**
+     * format of the frame, -1 if unknown or unset
+     * Values correspond to enum AVPixelFormat for video frames,
+     * enum AVSampleFormat for audio)
+     * - encoding: unused
+     * - decoding: Read by user.
+     */
+    int format;
 
     /**
-     * Some codecs need additional format info. It is stored here.
-     * If any muxer uses this then ALL demuxers/parsers AND encoders for the
-     * specific codec MUST set it correctly otherwise stream copy breaks.
-     * In general use of this field by muxers is not recommanded.
+     * 1 -> keyframe, 0-> not
      * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec. (FIXME: Is this OK?)
+     * - decoding: Set by libavcodec.
      */
-    int sub_id;
+    int key_frame;
 
     /**
-     * Motion estimation algorithm used for video coding.
-     * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex),
-     * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific]
-     * - encoding: MUST be set by user.
-     * - decoding: unused
+     * Picture type of the frame, see ?_TYPE below.
+     * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
+     * - decoding: Set by libavcodec.
      */
-    int me_method;
+    enum AVPictureType pict_type;
 
     /**
-     * some codecs need / can use extradata like Huffman tables.
-     * mjpeg: Huffman tables
-     * rv10: additional flags
-     * mpeg4: global headers (they can be in the bitstream or here)
-     * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger
-     * than extradata_size to avoid prolems if it is read with the bitstream reader.
-     * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
-     * - encoding: Set/allocated/freed by libavcodec.
-     * - decoding: Set/allocated/freed by user.
+     * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.
+     * This isn't used by libavcodec unless the default get/release_buffer() is used.
+     * - encoding:
+     * - decoding:
      */
-    uint8_t *extradata;
-    int extradata_size;
+    uint8_t *base[AV_NUM_DATA_POINTERS];
 
     /**
-     * This is the fundamental unit of time (in seconds) in terms
-     * of which frame timestamps are represented. For fixed-fps content,
-     * timebase should be 1/framerate and timestamp increments should be
-     * identically 1.
-     * - encoding: MUST be set by user.
-     * - decoding: Set by libavcodec.
+     * sample aspect ratio for the video frame, 0/1 if unknown/unspecified
+     * - encoding: unused
+     * - decoding: Read by user.
      */
-    AVRational time_base;
+    AVRational sample_aspect_ratio;
 
-    /* video only */
     /**
-     * picture width / height.
+     * presentation timestamp in time_base units (time when frame should be shown to user)
+     * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.
      * - encoding: MUST be set by user.
      * - decoding: Set by libavcodec.
-     * Note: For compatibility it is possible to set this instead of
-     * coded_width/height before decoding.
      */
-    int width, height;
+    int64_t pts;
 
-#define FF_ASPECT_EXTENDED 15
+    /**
+     * reordered pts from the last AVPacket that has been input into the decoder
+     * - encoding: unused
+     * - decoding: Read by user.
+     */
+    int64_t pkt_pts;
 
     /**
-     * the number of pictures in a group of pictures, or 0 for intra_only
-     * - encoding: Set by user.
-     * - decoding: unused
+     * dts from the last AVPacket that has been input into the decoder
+     * - encoding: unused
+     * - decoding: Read by user.
      */
-    int gop_size;
+    int64_t pkt_dts;
 
     /**
-     * Pixel format, see PIX_FMT_xxx.
-     * - encoding: Set by user.
+     * picture number in bitstream order
+     * - encoding: set by
+     * - decoding: Set by libavcodec.
+     */
+    int coded_picture_number;
+    /**
+     * picture number in display order
+     * - encoding: set by
      * - decoding: Set by libavcodec.
      */
-    enum PixelFormat pix_fmt;
+    int display_picture_number;
 
     /**
-     * Frame rate emulation. If not zero, the lower layer (i.e. format handler)
-     * has to read frames at native frame rate.
-     * - encoding: Set by user.
-     * - decoding: unused
+     * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
+     * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
+     * - decoding: Set by libavcodec.
      */
-    int rate_emu;
+    int quality;
 
     /**
-     * If non NULL, 'draw_horiz_band' is called by the libavcodec
-     * decoder to draw a horizontal band. It improves cache usage. Not
-     * all codecs can do that. You must check the codec capabilities
-     * beforehand.
-     * The function is also used by hardware acceleration APIs.
-     * It is called at least once during frame decoding to pass
-     * the data needed for hardware render.
-     * In that mode instead of pixel data, AVFrame points to
-     * a structure specific to the acceleration API. The application
-     * reads the structure and can change some fields to indicate progress
-     * or mark state.
+     * is this picture used as reference
+     * The values for this are the same as the MpegEncContext.picture_structure
+     * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
+     * Set to 4 for delayed, non-reference frames.
      * - encoding: unused
-     * - decoding: Set by user.
-     * @param height the height of the slice
-     * @param y the y position of the slice
-     * @param type 1->top field, 2->bottom field, 3->frame
-     * @param offset offset into the AVFrame.data from which the slice should be read
+     * - decoding: Set by libavcodec. (before get_buffer() call)).
      */
-    void (*draw_horiz_band)(struct AVCodecContext *s,
-                            const AVFrame *src, int offset[4],
-                            int y, int type, int height);
-
-    /* audio only */
-    int sample_rate; ///< samples per second
-    int channels;    ///< number of audio channels
+    int reference;
 
     /**
-     * audio sample format
-     * - encoding: Set by user.
+     * QP table
+     * - encoding: unused
      * - decoding: Set by libavcodec.
      */
-    enum SampleFormat sample_fmt;  ///< sample format, currently unused
-
-    /* The following data should not be initialized. */
+    int8_t *qscale_table;
     /**
-     * Samples per packet, initialized when calling 'init'.
+     * QP store stride
+     * - encoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int frame_size;
-    int frame_number;   ///< audio or video frame number
-    int real_pict_num;  ///< Returns the real picture number of previous encoded frame.
+    int qstride;
 
     /**
-     * Number of frames the decoded output will be delayed relative to
-     * the encoded input.
-     * - encoding: Set by libavcodec.
-     * - decoding: unused
+     *
      */
-    int delay;
+    int qscale_type;
 
-    /* - encoding parameters */
-    float qcompress;  ///< amount of qscale change between easy & hard scenes (0.0-1.0)
-    float qblur;      ///< amount of qscale smoothing over time (0.0-1.0)
+    /**
+     * mbskip_table[mb]>=1 if MB didn't change
+     * stride= mb_width = (width+15)>>4
+     * - encoding: unused
+     * - decoding: Set by libavcodec.
+     */
+    uint8_t *mbskip_table;
 
     /**
-     * minimum quantizer
+     * motion vector table
+     * @code
+     * example:
+     * int mv_sample_log2= 4 - motion_subsample_log2;
+     * int mb_width= (width+15)>>4;
+     * int mv_stride= (mb_width << mv_sample_log2) + 1;
+     * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];
+     * @endcode
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int qmin;
+    int16_t (*motion_val[2])[2];
 
     /**
-     * maximum quantizer
+     * macroblock type table
+     * mb_type_base + mb_width + 2
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int qmax;
+    uint32_t *mb_type;
 
     /**
-     * maximum quantizer difference between frames
-     * - encoding: Set by user.
-     * - decoding: unused
+     * DCT coefficients
+     * - encoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int max_qdiff;
+    short *dct_coeff;
 
     /**
-     * maximum number of B-frames between non-B-frames
-     * Note: The output will be delayed by max_b_frames+1 relative to the input.
+     * motion reference frame index
+     * the order in which these are stored can depend on the codec.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int max_b_frames;
+    int8_t *ref_index[2];
 
     /**
-     * qscale factor between IP and B-frames
-     * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
-     * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
-     * - encoding: Set by user.
-     * - decoding: unused
+     * for some private data of the user
+     * - encoding: unused
+     * - decoding: Set by user.
      */
-    float b_quant_factor;
+    void *opaque;
 
-    /** obsolete FIXME remove */
-    int rc_strategy;
-#define FF_RC_STRATEGY_XVID 1
+    /**
+     * error
+     * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.
+     * - decoding: unused
+     */
+    uint64_t error[AV_NUM_DATA_POINTERS];
 
-    int b_frame_strategy;
+    /**
+     * type of the buffer (to keep track of who has to deallocate data[*])
+     * - encoding: Set by the one who allocates it.
+     * - decoding: Set by the one who allocates it.
+     * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.
+     */
+    int type;
 
     /**
-     * hurry up amount
+     * When decoding, this signals how much the picture must be delayed.
+     * extra_delay = repeat_pict / (2*fps)
      * - encoding: unused
-     * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header
-     * @deprecated Deprecated in favor of skip_idct and skip_frame.
+     * - decoding: Set by libavcodec.
      */
-    int hurry_up;
-
-    struct AVCodec *codec;
-
-    void *priv_data;
-
-    int rtp_payload_size;   /* The size of the RTP payload: the coder will  */
-                            /* do its best to deliver a chunk with size     */
-                            /* below rtp_payload_size, the chunk will start */
-                            /* with a start code on some codecs like H.263. */
-                            /* This doesn't take account of any particular  */
-                            /* headers inside the transmitted RTP payload.  */
-
-
-    /* The RTP callback: This function is called    */
-    /* every time the encoder has a packet to send. */
-    /* It depends on the encoder if the data starts */
-    /* with a Start Code (it should). H.263 does.   */
-    /* mb_nb contains the number of macroblocks     */
-    /* encoded in the RTP payload.                  */
-    void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
-
-    /* statistics, used for 2-pass encoding */
-    int mv_bits;
-    int header_bits;
-    int i_tex_bits;
-    int p_tex_bits;
-    int i_count;
-    int p_count;
-    int skip_count;
-    int misc_bits;
+    int repeat_pict;
 
     /**
-     * number of bits used for the previously encoded frame
-     * - encoding: Set by libavcodec.
-     * - decoding: unused
+     * The content of the picture is interlaced.
+     * - encoding: Set by user.
+     * - decoding: Set by libavcodec. (default 0)
      */
-    int frame_bits;
+    int interlaced_frame;
 
     /**
-     * Private data of the user, can be used to carry app specific stuff.
+     * If the content is interlaced, is top field displayed first.
      * - encoding: Set by user.
-     * - decoding: Set by user.
+     * - decoding: Set by libavcodec.
      */
-    void *opaque;
-
-    char codec_name[32];
-    enum CodecType codec_type; /* see CODEC_TYPE_xxx */
-    enum CodecID codec_id; /* see CODEC_ID_xxx */
+    int top_field_first;
 
     /**
-     * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
-     * This is used to work around some encoder bugs.
-     * A demuxer should set this to what is stored in the field used to identify the codec.
-     * If there are multiple such fields in a container then the demuxer should choose the one
-     * which maximizes the information about the used codec.
-     * If the codec tag field in a container is larger then 32 bits then the demuxer should
-     * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
-     * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
-     * first.
-     * - encoding: Set by user, if not then the default based on codec_id will be used.
-     * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
+     * Tell user application that palette has changed from previous frame.
+     * - encoding: ??? (no palette-enabled encoder yet)
+     * - decoding: Set by libavcodec. (default 0).
      */
-    unsigned int codec_tag;
+    int palette_has_changed;
 
     /**
-     * Work around bugs in encoders which sometimes cannot be detected automatically.
-     * - encoding: Set by user
-     * - decoding: Set by user
+     * codec suggestion on buffer type if != 0
+     * - encoding: unused
+     * - decoding: Set by libavcodec. (before get_buffer() call)).
      */
-    int workaround_bugs;
-#define FF_BUG_AUTODETECT       1  ///< autodetection
-#define FF_BUG_OLD_MSMPEG4      2
-#define FF_BUG_XVID_ILACE       4
-#define FF_BUG_UMP4             8
-#define FF_BUG_NO_PADDING       16
-#define FF_BUG_AMV              32
-#define FF_BUG_AC_VLC           0  ///< Will be removed, libavcodec can now handle these non-compliant files by default.
-#define FF_BUG_QPEL_CHROMA      64
-#define FF_BUG_STD_QPEL         128
-#define FF_BUG_QPEL_CHROMA2     256
-#define FF_BUG_DIRECT_BLOCKSIZE 512
-#define FF_BUG_EDGE             1024
-#define FF_BUG_HPEL_CHROMA      2048
-#define FF_BUG_DC_CLIP          4096
-#define FF_BUG_MS               8192 ///< Work around various bugs in Microsoft's broken decoders.
-//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%.
+    int buffer_hints;
 
     /**
-     * luma single coefficient elimination threshold
+     * Pan scan.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int luma_elim_threshold;
+    AVPanScan *pan_scan;
 
     /**
-     * chroma single coeff elimination threshold
-     * - encoding: Set by user.
-     * - decoding: unused
+     * reordered opaque 64bit (generally an integer or a double precision float
+     * PTS but can be anything).
+     * The user sets AVCodecContext.reordered_opaque to represent the input at
+     * that time,
+     * the decoder reorders values as needed and sets AVFrame.reordered_opaque
+     * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
+     * @deprecated in favor of pkt_pts
+     * - encoding: unused
+     * - decoding: Read by user.
      */
-    int chroma_elim_threshold;
+    int64_t reordered_opaque;
 
     /**
-     * strictly follow the standard (MPEG4, ...).
-     * - encoding: Set by user.
-     * - decoding: Set by user.
-     * Setting this to STRICT or higher means the encoder and decoder will
-     * generally do stupid things. While setting it to inofficial or lower
-     * will mean the encoder might use things that are not supported by all
-     * spec compliant decoders. Decoders make no difference between normal,
-     * inofficial and experimental, that is they always try to decode things
-     * when they can unless they are explicitly asked to behave stupid
-     * (=strictly conform to the specs)
+     * hardware accelerator private data (FFmpeg-allocated)
+     * - encoding: unused
+     * - decoding: Set by libavcodec
      */
-    int strict_std_compliance;
-#define FF_COMPLIANCE_VERY_STRICT   2 ///< Strictly conform to a older more strict version of the spec or reference software.
-#define FF_COMPLIANCE_STRICT        1 ///< Strictly conform to all the things in the spec no matter what consequences.
-#define FF_COMPLIANCE_NORMAL        0
-#define FF_COMPLIANCE_INOFFICIAL   -1 ///< Allow inofficial extensions.
-#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
+    void *hwaccel_picture_private;
 
     /**
-     * qscale offset between IP and B-frames
-     * - encoding: Set by user.
-     * - decoding: unused
+     * the AVCodecContext which ff_thread_get_buffer() was last called on
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by libavcodec.
      */
-    float b_quant_offset;
+    struct AVCodecContext *owner;
+
+    /**
+     * used by multithreading to store frame-specific info
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by libavcodec.
+     */
+    void *thread_opaque;
 
     /**
-     * Error recognization; higher values will detect more errors but may
-     * misdetect some more or less valid parts as errors.
+     * log2 of the size of the block which a single vector in motion_val represents:
+     * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
      * - encoding: unused
-     * - decoding: Set by user.
+     * - decoding: Set by libavcodec.
      */
-    int error_recognition;
-#define FF_ER_CAREFUL         1
-#define FF_ER_COMPLIANT       2
-#define FF_ER_AGGRESSIVE      3
-#define FF_ER_VERY_AGGRESSIVE 4
+    uint8_t motion_subsample_log2;
 
     /**
-     * Called at the beginning of each frame to get a buffer for it.
-     * If pic.reference is set then the frame will be read later by libavcodec.
-     * avcodec_align_dimensions() should be used to find the required width and
-     * height, as they normally need to be rounded up to the next multiple of 16.
+     * Sample rate of the audio data.
+     *
      * - encoding: unused
-     * - decoding: Set by libavcodec., user can override.
+     * - decoding: read by user
      */
-    int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+    int sample_rate;
 
     /**
-     * Called to release buffers which were allocated with get_buffer.
-     * A released buffer can be reused in get_buffer().
-     * pic.data[*] must be set to NULL.
+     * Channel layout of the audio data.
+     *
      * - encoding: unused
-     * - decoding: Set by libavcodec., user can override.
+     * - decoding: read by user.
      */
-    void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
+    uint64_t channel_layout;
 
     /**
-     * Size of the frame reordering buffer in the decoder.
-     * For MPEG-2 it is 1 IPB or 0 low delay IP.
-     * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec.
+     * frame timestamp estimated using various heuristics, in stream time base
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_best_effort_timestamp(frame)
+     * - encoding: unused
+     * - decoding: set by libavcodec, read by user.
      */
-    int has_b_frames;
+    int64_t best_effort_timestamp;
 
     /**
-     * number of bytes per packet if constant and known or 0
-     * Used by some WAV based audio codecs.
+     * reordered pos from the last AVPacket that has been input into the decoder
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_pkt_pos(frame)
+     * - encoding: unused
+     * - decoding: Read by user.
      */
-    int block_align;
+    int64_t pkt_pos;
 
-    int parse_only; /* - decoding only: If true, only parsing is done
-                       (function avcodec_parse_frame()). The frame
-                       data is returned. Only MPEG codecs support this now. */
+    /**
+     * duration of the corresponding packet, expressed in
+     * AVStream->time_base units, 0 if unknown.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_pkt_duration(frame)
+     * - encoding: unused
+     * - decoding: Read by user.
+     */
+    int64_t pkt_duration;
 
     /**
-     * 0-> h263 quant 1-> mpeg quant
+     * metadata.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_metadata(frame)
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int mpeg_quant;
+    AVDictionary *metadata;
 
     /**
-     * pass1 encoding statistics output buffer
-     * - encoding: Set by libavcodec.
-     * - decoding: unused
+     * decode error flags of the frame, set to a combination of
+     * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there
+     * were errors during the decoding.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_decode_error_flags(frame)
+     * - encoding: unused
+     * - decoding: set by libavcodec, read by user.
      */
-    char *stats_out;
+    int decode_error_flags;
+#define FF_DECODE_ERROR_INVALID_BITSTREAM   1
+#define FF_DECODE_ERROR_MISSING_REFERENCE   2
 
     /**
-     * pass2 encoding statistics input buffer
-     * Concatenated stuff from stats_out of pass1 should be placed here.
-     * - encoding: Allocated/set/freed by user.
-     * - decoding: unused
+     * number of audio channels, only used for audio.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_channels(frame)
+     * - encoding: unused
+     * - decoding: Read by user.
      */
-    char *stats_in;
+    int64_t channels;
+} AVFrame;
+
+/**
+ * Accessors for some AVFrame fields.
+ * The position of these field in the structure is not part of the ABI,
+ * they should not be accessed directly outside libavcodec.
+ */
+int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame);
+void    av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val);
+int64_t av_frame_get_pkt_duration         (const AVFrame *frame);
+void    av_frame_set_pkt_duration         (AVFrame *frame, int64_t val);
+int64_t av_frame_get_pkt_pos              (const AVFrame *frame);
+void    av_frame_set_pkt_pos              (AVFrame *frame, int64_t val);
+int64_t av_frame_get_channel_layout       (const AVFrame *frame);
+void    av_frame_set_channel_layout       (AVFrame *frame, int64_t val);
+int     av_frame_get_channels             (const AVFrame *frame);
+void    av_frame_set_channels             (AVFrame *frame, int     val);
+int     av_frame_get_sample_rate          (const AVFrame *frame);
+void    av_frame_set_sample_rate          (AVFrame *frame, int     val);
+AVDictionary *av_frame_get_metadata       (const AVFrame *frame);
+void          av_frame_set_metadata       (AVFrame *frame, AVDictionary *val);
+int     av_frame_get_decode_error_flags   (const AVFrame *frame);
+void    av_frame_set_decode_error_flags   (AVFrame *frame, int     val);
+
+struct AVCodecInternal;
+
+enum AVFieldOrder {
+    AV_FIELD_UNKNOWN,
+    AV_FIELD_PROGRESSIVE,
+    AV_FIELD_TT,          //< Top coded_first, top displayed first
+    AV_FIELD_BB,          //< Bottom coded first, bottom displayed first
+    AV_FIELD_TB,          //< Top coded first, bottom displayed first
+    AV_FIELD_BT,          //< Bottom coded first, top displayed first
+};
 
+/**
+ * main external API structure.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user
+ * applications.
+ * sizeof(AVCodecContext) must not be used outside libav*.
+ */
+typedef struct AVCodecContext {
     /**
-     * ratecontrol qmin qmax limiting method
-     * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax.
-     * - encoding: Set by user.
-     * - decoding: unused
+     * information on struct for av_log
+     * - set by avcodec_alloc_context3
      */
-    float rc_qsquish;
+    const AVClass *av_class;
+    int log_level_offset;
 
-    float rc_qmod_amp;
-    int rc_qmod_freq;
+    enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+    const struct AVCodec  *codec;
+    char             codec_name[32];
+    enum AVCodecID     codec_id; /* see AV_CODEC_ID_xxx */
 
     /**
-     * ratecontrol override, see RcOverride
-     * - encoding: Allocated/set/freed by user.
-     * - decoding: unused
+     * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+     * This is used to work around some encoder bugs.
+     * A demuxer should set this to what is stored in the field used to identify the codec.
+     * If there are multiple such fields in a container then the demuxer should choose the one
+     * which maximizes the information about the used codec.
+     * If the codec tag field in a container is larger than 32 bits then the demuxer should
+     * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
+     * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
+     * first.
+     * - encoding: Set by user, if not then the default based on codec_id will be used.
+     * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
      */
-    RcOverride *rc_override;
-    int rc_override_count;
+    unsigned int codec_tag;
 
     /**
-     * rate control equation
-     * - encoding: Set by user
-     * - decoding: unused
+     * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+     * This is used to work around some encoder bugs.
+     * - encoding: unused
+     * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
      */
-    const char *rc_eq;
+    unsigned int stream_codec_tag;
 
+#if FF_API_SUB_ID
     /**
-     * maximum bitrate
-     * - encoding: Set by user.
-     * - decoding: unused
+     * @deprecated this field is unused
      */
-    int rc_max_rate;
+    attribute_deprecated int sub_id;
+#endif
+
+    void *priv_data;
 
     /**
-     * minimum bitrate
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Private context used for internal data.
+     *
+     * Unlike priv_data, this is not codec-specific. It is used in general
+     * libavcodec functions.
      */
-    int rc_min_rate;
+    struct AVCodecInternal *internal;
 
     /**
-     * decoder bitstream buffer size
+     * Private data of the user, can be used to carry app specific stuff.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by user.
      */
-    int rc_buffer_size;
-    float rc_buffer_aggressivity;
+    void *opaque;
 
     /**
-     * qscale factor between P and I-frames
-     * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
-     * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
-     * - encoding: Set by user.
-     * - decoding: unused
+     * the average bitrate
+     * - encoding: Set by user; unused for constant quantizer encoding.
+     * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream.
      */
-    float i_quant_factor;
+    int bit_rate;
 
     /**
-     * qscale offset between P and I-frames
-     * - encoding: Set by user.
+     * number of bits the bitstream is allowed to diverge from the reference.
+     *           the reference can be CBR (for CBR pass1) or VBR (for pass2)
+     * - encoding: Set by user; unused for constant quantizer encoding.
      * - decoding: unused
      */
-    float i_quant_offset;
+    int bit_rate_tolerance;
 
     /**
-     * initial complexity for pass1 ratecontrol
+     * Global quality for codecs which cannot change it per frame.
+     * This should be proportional to MPEG-1/2/4 qscale.
      * - encoding: Set by user.
      * - decoding: unused
      */
-    float rc_initial_cplx;
+    int global_quality;
 
     /**
-     * DCT algorithm, see FF_DCT_* below
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int dct_algo;
-#define FF_DCT_AUTO    0
-#define FF_DCT_FASTINT 1
-#define FF_DCT_INT     2
-#define FF_DCT_MMX     3
-#define FF_DCT_MLIB    4
-#define FF_DCT_ALTIVEC 5
-#define FF_DCT_FAAN    6
+    int compression_level;
+#define FF_COMPRESSION_DEFAULT -1
 
     /**
-     * luminance masking (0-> disabled)
+     * CODEC_FLAG_*.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by user.
      */
-    float lumi_masking;
+    int flags;
 
     /**
-     * temporary complexity masking (0-> disabled)
-     * - encoding: Set by user.
-     * - decoding: unused
-     */
-    float temporal_cplx_masking;
-
-    /**
-     * spatial complexity masking (0-> disabled)
+     * CODEC_FLAG2_*
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by user.
      */
-    float spatial_cplx_masking;
+    int flags2;
 
     /**
-     * p block masking (0-> disabled)
-     * - encoding: Set by user.
-     * - decoding: unused
+     * some codecs need / can use extradata like Huffman tables.
+     * mjpeg: Huffman tables
+     * rv10: additional flags
+     * mpeg4: global headers (they can be in the bitstream or here)
+     * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger
+     * than extradata_size to avoid prolems if it is read with the bitstream reader.
+     * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
+     * - encoding: Set/allocated/freed by libavcodec.
+     * - decoding: Set/allocated/freed by user.
      */
-    float p_masking;
+    uint8_t *extradata;
+    int extradata_size;
 
     /**
-     * darkness masking (0-> disabled)
-     * - encoding: Set by user.
-     * - decoding: unused
+     * This is the fundamental unit of time (in seconds) in terms
+     * of which frame timestamps are represented. For fixed-fps content,
+     * timebase should be 1/framerate and timestamp increments should be
+     * identically 1.
+     * - encoding: MUST be set by user.
+     * - decoding: Set by libavcodec.
      */
-    float dark_masking;
+    AVRational time_base;
 
     /**
-     * IDCT algorithm, see FF_IDCT_* below.
-     * - encoding: Set by user.
-     * - decoding: Set by user.
+     * For some codecs, the time base is closer to the field rate than the frame rate.
+     * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
+     * if no telecine is used ...
+     *
+     * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
      */
-    int idct_algo;
-#define FF_IDCT_AUTO          0
-#define FF_IDCT_INT           1
-#define FF_IDCT_SIMPLE        2
-#define FF_IDCT_SIMPLEMMX     3
-#define FF_IDCT_LIBMPEG2MMX   4
-#define FF_IDCT_PS2           5
-#define FF_IDCT_MLIB          6
-#define FF_IDCT_ARM           7
-#define FF_IDCT_ALTIVEC       8
-#define FF_IDCT_SH4           9
-#define FF_IDCT_SIMPLEARM     10
-#define FF_IDCT_H264          11
-#define FF_IDCT_VP3           12
-#define FF_IDCT_IPP           13
-#define FF_IDCT_XVIDMMX       14
-#define FF_IDCT_CAVS          15
-#define FF_IDCT_SIMPLEARMV5TE 16
-#define FF_IDCT_SIMPLEARMV6   17
-#define FF_IDCT_SIMPLEVIS     18
-#define FF_IDCT_WMV2          19
-#define FF_IDCT_FAAN          20
-#define FF_IDCT_EA            21
-#define FF_IDCT_SIMPLENEON    22
-#define FF_IDCT_SIMPLEALPHA   23
+    int ticks_per_frame;
 
     /**
-     * slice count
+     * Encoding: Number of frames delay there will be from the encoder input to
+     *           the decoder output. (we assume the decoder matches the spec)
+     * Decoding: Number of frames delay in addition to what a standard decoder
+     *           as specified in the spec would produce.
+     *
+     * Video:
+     *   Number of frames the decoded output will be delayed relative to the
+     *   encoded input.
+     *
+     * Audio:
+     *   For encoding, this is the number of "priming" samples added to the
+     *   beginning of the stream. The decoded output will be delayed by this
+     *   many samples relative to the input to the encoder. Note that this
+     *   field is purely informational and does not directly affect the pts
+     *   output by the encoder, which should always be based on the actual
+     *   presentation time, including any delay.
+     *   For decoding, this is the number of samples the decoder needs to
+     *   output before the decoder's output is valid. When seeking, you should
+     *   start decoding this many samples prior to your desired seek point.
+     *
      * - encoding: Set by libavcodec.
-     * - decoding: Set by user (or 0).
-     */
-    int slice_count;
-    /**
-     * slice offsets in the frame in bytes
-     * - encoding: Set/allocated by libavcodec.
-     * - decoding: Set/allocated by user (or NULL).
+     * - decoding: Set by libavcodec.
      */
-    int *slice_offset;
+    int delay;
 
-    /**
-     * error concealment flags
-     * - encoding: unused
-     * - decoding: Set by user.
-     */
-    int error_concealment;
-#define FF_EC_GUESS_MVS   1
-#define FF_EC_DEBLOCK     2
 
+    /* video only */
     /**
-     * dsp_mask could be add used to disable unwanted CPU features
-     * CPU features (i.e. MMX, SSE. ...)
-     *
-     * With the FORCE flag you may instead enable given CPU features.
-     * (Dangerous: Usable in case of misdetection, improper usage however will
-     * result into program crash.)
+     * picture width / height.
+     * - encoding: MUST be set by user.
+     * - decoding: Set by libavcodec.
+     * Note: For compatibility it is possible to set this instead of
+     * coded_width/height before decoding.
      */
-    unsigned dsp_mask;
-#define FF_MM_FORCE    0x80000000 /* Force usage of selected flags (OR) */
-    /* lower 16 bits - CPU features */
-#define FF_MM_MMX      0x0001 ///< standard MMX
-#define FF_MM_3DNOW    0x0004 ///< AMD 3DNOW
-#if LIBAVCODEC_VERSION_MAJOR < 53
-#define FF_MM_MMXEXT   0x0002 ///< SSE integer functions or AMD MMX ext
-#endif
-#define FF_MM_MMX2     0x0002 ///< SSE integer functions or AMD MMX ext
-#define FF_MM_SSE      0x0008 ///< SSE functions
-#define FF_MM_SSE2     0x0010 ///< PIV SSE2 functions
-#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt
-#define FF_MM_SSE3     0x0040 ///< Prescott SSE3 functions
-#define FF_MM_SSSE3    0x0080 ///< Conroe SSSE3 functions
-#define FF_MM_SSE4     0x0100 ///< Penryn SSE4.1 functions
-#define FF_MM_SSE42    0x0200 ///< Nehalem SSE4.2 functions
-#define FF_MM_IWMMXT   0x0100 ///< XScale IWMMXT
-#define FF_MM_ALTIVEC  0x0001 ///< standard AltiVec
+    int width, height;
 
     /**
-     * bits per sample/pixel from the demuxer (needed for huffyuv).
-     * - encoding: Set by libavcodec.
-     * - decoding: Set by user.
+     * Bitstream width / height, may be different from width/height if lowres enabled.
+     * - encoding: unused
+     * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
      */
-     int bits_per_coded_sample;
+    int coded_width, coded_height;
+
+#define FF_ASPECT_EXTENDED 15
 
     /**
-     * prediction method (needed for huffyuv)
+     * the number of pictures in a group of pictures, or 0 for intra_only
      * - encoding: Set by user.
      * - decoding: unused
      */
-     int prediction_method;
-#define FF_PRED_LEFT   0
-#define FF_PRED_PLANE  1
-#define FF_PRED_MEDIAN 2
+    int gop_size;
 
     /**
-     * sample aspect ratio (0 if unknown)
-     * That is the width of a pixel divided by the height of the pixel.
-     * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+     * Pixel format, see AV_PIX_FMT_xxx.
+     * May be set by the demuxer if known from headers.
+     * May be overridden by the decoder if it knows better.
      * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
+     * - decoding: Set by user if known, overridden by libavcodec if known
      */
-    AVRational sample_aspect_ratio;
+    enum AVPixelFormat pix_fmt;
 
     /**
-     * the picture in the bitstream
-     * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec.
+     * Motion estimation algorithm used for video coding.
+     * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex),
+     * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific]
+     * - encoding: MUST be set by user.
+     * - decoding: unused
      */
-    AVFrame *coded_frame;
+    int me_method;
 
     /**
-     * debug
-     * - encoding: Set by user.
+     * If non NULL, 'draw_horiz_band' is called by the libavcodec
+     * decoder to draw a horizontal band. It improves cache usage. Not
+     * all codecs can do that. You must check the codec capabilities
+     * beforehand.
+     * When multithreading is used, it may be called from multiple threads
+     * at the same time; threads might draw different parts of the same AVFrame,
+     * or multiple AVFrames, and there is no guarantee that slices will be drawn
+     * in order.
+     * The function is also used by hardware acceleration APIs.
+     * It is called at least once during frame decoding to pass
+     * the data needed for hardware render.
+     * In that mode instead of pixel data, AVFrame points to
+     * a structure specific to the acceleration API. The application
+     * reads the structure and can change some fields to indicate progress
+     * or mark state.
+     * - encoding: unused
      * - decoding: Set by user.
+     * @param height the height of the slice
+     * @param y the y position of the slice
+     * @param type 1->top field, 2->bottom field, 3->frame
+     * @param offset offset into the AVFrame.data from which the slice should be read
      */
-    int debug;
-#define FF_DEBUG_PICT_INFO   1
-#define FF_DEBUG_RC          2
-#define FF_DEBUG_BITSTREAM   4
-#define FF_DEBUG_MB_TYPE     8
-#define FF_DEBUG_QP          16
-#define FF_DEBUG_MV          32
-#define FF_DEBUG_DCT_COEFF   0x00000040
-#define FF_DEBUG_SKIP        0x00000080
-#define FF_DEBUG_STARTCODE   0x00000100
-#define FF_DEBUG_PTS         0x00000200
-#define FF_DEBUG_ER          0x00000400
-#define FF_DEBUG_MMCO        0x00000800
-#define FF_DEBUG_BUGS        0x00001000
-#define FF_DEBUG_VIS_QP      0x00002000
-#define FF_DEBUG_VIS_MB_TYPE 0x00004000
-#define FF_DEBUG_BUFFERS     0x00008000
+    void (*draw_horiz_band)(struct AVCodecContext *s,
+                            const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
+                            int y, int type, int height);
 
     /**
-     * debug
-     * - encoding: Set by user.
-     * - decoding: Set by user.
+     * callback to negotiate the pixelFormat
+     * @param fmt is the list of formats which are supported by the codec,
+     * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
+     * The first is always the native one.
+     * @return the chosen format
+     * - encoding: unused
+     * - decoding: Set by user, if not set the native format will be chosen.
      */
-    int debug_mv;
-#define FF_DEBUG_VIS_MV_P_FOR  0x00000001 //visualize forward predicted MVs of P frames
-#define FF_DEBUG_VIS_MV_B_FOR  0x00000002 //visualize forward predicted MVs of B frames
-#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+    enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
 
     /**
-     * error
-     * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR.
+     * maximum number of B-frames between non-B-frames
+     * Note: The output will be delayed by max_b_frames+1 relative to the input.
+     * - encoding: Set by user.
      * - decoding: unused
      */
-    uint64_t error[4];
+    int max_b_frames;
 
     /**
-     * minimum MB quantizer
-     * - encoding: unused
+     * qscale factor between IP and B-frames
+     * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
+     * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+     * - encoding: Set by user.
      * - decoding: unused
      */
-    int mb_qmin;
+    float b_quant_factor;
+
+    /** obsolete FIXME remove */
+    int rc_strategy;
+#define FF_RC_STRATEGY_XVID 1
+
+    int b_frame_strategy;
 
+#if FF_API_MPV_GLOBAL_OPTS
     /**
-     * maximum MB quantizer
-     * - encoding: unused
+     * luma single coefficient elimination threshold
+     * - encoding: Set by user.
      * - decoding: unused
      */
-    int mb_qmax;
+    attribute_deprecated int luma_elim_threshold;
 
     /**
-     * motion estimation comparison function
+     * chroma single coeff elimination threshold
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int me_cmp;
+    attribute_deprecated int chroma_elim_threshold;
+#endif
+
     /**
-     * subpixel motion estimation comparison function
+     * qscale offset between IP and B-frames
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int me_sub_cmp;
+    float b_quant_offset;
+
     /**
-     * macroblock comparison function (not supported yet)
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Size of the frame reordering buffer in the decoder.
+     * For MPEG-2 it is 1 IPB or 0 low delay IP.
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by libavcodec.
      */
-    int mb_cmp;
+    int has_b_frames;
+
     /**
-     * interlaced DCT comparison function
+     * 0-> h263 quant 1-> mpeg quant
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int ildct_cmp;
-#define FF_CMP_SAD    0
-#define FF_CMP_SSE    1
-#define FF_CMP_SATD   2
-#define FF_CMP_DCT    3
-#define FF_CMP_PSNR   4
-#define FF_CMP_BIT    5
-#define FF_CMP_RD     6
-#define FF_CMP_ZERO   7
-#define FF_CMP_VSAD   8
-#define FF_CMP_VSSE   9
-#define FF_CMP_NSSE   10
-#define FF_CMP_W53    11
-#define FF_CMP_W97    12
-#define FF_CMP_DCTMAX 13
-#define FF_CMP_DCT264 14
-#define FF_CMP_CHROMA 256
+    int mpeg_quant;
 
     /**
-     * ME diamond size & shape
+     * qscale factor between P and I-frames
+     * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
+     * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int dia_size;
+    float i_quant_factor;
 
     /**
-     * amount of previous MV predictors (2a+1 x 2a+1 square)
+     * qscale offset between P and I-frames
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int last_predictor_count;
+    float i_quant_offset;
 
     /**
-     * prepass for motion estimation
+     * luminance masking (0-> disabled)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    float lumi_masking;
+
+    /**
+     * temporary complexity masking (0-> disabled)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    float temporal_cplx_masking;
+
+    /**
+     * spatial complexity masking (0-> disabled)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    float spatial_cplx_masking;
+
+    /**
+     * p block masking (0-> disabled)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    float p_masking;
+
+    /**
+     * darkness masking (0-> disabled)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    float dark_masking;
+
+    /**
+     * slice count
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by user (or 0).
+     */
+    int slice_count;
+    /**
+     * prediction method (needed for huffyuv)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+     int prediction_method;
+#define FF_PRED_LEFT   0
+#define FF_PRED_PLANE  1
+#define FF_PRED_MEDIAN 2
+
+    /**
+     * slice offsets in the frame in bytes
+     * - encoding: Set/allocated by libavcodec.
+     * - decoding: Set/allocated by user (or NULL).
+     */
+    int *slice_offset;
+
+    /**
+     * sample aspect ratio (0 if unknown)
+     * That is the width of a pixel divided by the height of the pixel.
+     * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+     * - encoding: Set by user.
+     * - decoding: Set by libavcodec.
+     */
+    AVRational sample_aspect_ratio;
+
+    /**
+     * motion estimation comparison function
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int me_cmp;
+    /**
+     * subpixel motion estimation comparison function
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int me_sub_cmp;
+    /**
+     * macroblock comparison function (not supported yet)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int mb_cmp;
+    /**
+     * interlaced DCT comparison function
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int ildct_cmp;
+#define FF_CMP_SAD    0
+#define FF_CMP_SSE    1
+#define FF_CMP_SATD   2
+#define FF_CMP_DCT    3
+#define FF_CMP_PSNR   4
+#define FF_CMP_BIT    5
+#define FF_CMP_RD     6
+#define FF_CMP_ZERO   7
+#define FF_CMP_VSAD   8
+#define FF_CMP_VSSE   9
+#define FF_CMP_NSSE   10
+#define FF_CMP_W53    11
+#define FF_CMP_W97    12
+#define FF_CMP_DCTMAX 13
+#define FF_CMP_DCT264 14
+#define FF_CMP_CHROMA 256
+
+    /**
+     * ME diamond size & shape
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int dia_size;
+
+    /**
+     * amount of previous MV predictors (2a+1 x 2a+1 square)
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int last_predictor_count;
+
+    /**
+     * prepass for motion estimation
      * - encoding: Set by user.
      * - decoding: unused
      */
@@ -1750,17 +1936,6 @@ typedef struct AVCodecContext {
      */
     int me_subpel_quality;
 
-    /**
-     * callback to negotiate the pixelFormat
-     * @param fmt is the list of formats which are supported by the codec,
-     * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
-     * The first is always the native one.
-     * @return the chosen format
-     * - encoding: unused
-     * - decoding: Set by user, if not set the native format will be chosen.
-     */
-    enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt);
-
     /**
      * DTG active format information (additional aspect ratio
      * information only used in DVB MPEG-2 transport streams)
@@ -1802,65 +1977,14 @@ typedef struct AVCodecContext {
      */
     int inter_quant_bias;
 
+#if FF_API_COLOR_TABLE_ID
     /**
      * color table ID
      * - encoding: unused
      * - decoding: Which clrtable should be used for 8bit RGB images.
      *             Tables have to be stored somewhere. FIXME
      */
-    int color_table_id;
-
-    /**
-     * internal_buffer count
-     * Don't touch, used by libavcodec default_get_buffer().
-     */
-    int internal_buffer_count;
-
-    /**
-     * internal_buffers
-     * Don't touch, used by libavcodec default_get_buffer().
-     */
-    void *internal_buffer;
-
-#define FF_LAMBDA_SHIFT 7
-#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT)
-#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda
-#define FF_LAMBDA_MAX (256*128-1)
-
-#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove
-    /**
-     * Global quality for codecs which cannot change it per frame.
-     * This should be proportional to MPEG-1/2/4 qscale.
-     * - encoding: Set by user.
-     * - decoding: unused
-     */
-    int global_quality;
-
-#define FF_CODER_TYPE_VLC       0
-#define FF_CODER_TYPE_AC        1
-#define FF_CODER_TYPE_RAW       2
-#define FF_CODER_TYPE_RLE       3
-#define FF_CODER_TYPE_DEFLATE   4
-    /**
-     * coder type
-     * - encoding: Set by user.
-     * - decoding: unused
-     */
-    int coder_type;
-
-    /**
-     * context model
-     * - encoding: Set by user.
-     * - decoding: unused
-     */
-    int context_model;
-#if 0
-    /**
-     *
-     * - encoding: unused
-     * - decoding: Set by user.
-     */
-    uint8_t * (*realloc)(struct AVCodecContext *s, uint8_t *buf, int buf_size);
+    attribute_deprecated int color_table_id;
 #endif
 
     /**
@@ -1904,14 +2028,6 @@ typedef struct AVCodecContext {
      */
     uint16_t *inter_matrix;
 
-    /**
-     * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
-     * This is used to work around some encoder bugs.
-     * - encoding: unused
-     * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
-     */
-    unsigned int stream_codec_tag;
-
     /**
      * scene change detection threshold
      * 0 is default, larger means fewer detected scene changes.
@@ -1921,527 +2037,707 @@ typedef struct AVCodecContext {
     int scenechange_threshold;
 
     /**
-     * minimum Lagrange multipler
+     * noise reduction strength
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int lmin;
+    int noise_reduction;
 
+#if FF_API_INTER_THRESHOLD
     /**
-     * maximum Lagrange multipler
+     * @deprecated this field is unused
+     */
+    attribute_deprecated int inter_threshold;
+#endif
+
+#if FF_API_MPV_GLOBAL_OPTS
+    /**
+     * @deprecated use mpegvideo private options instead
+     */
+    attribute_deprecated int quantizer_noise_shaping;
+#endif
+
+    /**
+     * Motion estimation threshold below which no motion estimation is
+     * performed, but instead the user specified motion vectors are used.
+     *
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int lmax;
+    int me_threshold;
 
     /**
-     * palette control structure
-     * - encoding: ??? (no palette-enabled encoder yet)
-     * - decoding: Set by user.
+     * Macroblock threshold below which the user specified macroblock types will be used.
+     * - encoding: Set by user.
+     * - decoding: unused
      */
-    struct AVPaletteControl *palctrl;
+    int mb_threshold;
 
     /**
-     * noise reduction strength
+     * precision of the intra DC coefficient - 8
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int noise_reduction;
+    int intra_dc_precision;
 
     /**
-     * Called at the beginning of a frame to get cr buffer for it.
-     * Buffer type (size, hints) must be the same. libavcodec won't check it.
-     * libavcodec will pass previous buffer in pic, function should return
-     * same buffer or new buffer with old frame "painted" into it.
-     * If pic.data[0] == NULL must behave like get_buffer().
+     * Number of macroblock rows at the top which are skipped.
      * - encoding: unused
-     * - decoding: Set by libavcodec., user can override
+     * - decoding: Set by user.
      */
-    int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+    int skip_top;
 
     /**
-     * Number of bits which should be loaded into the rc buffer before decoding starts.
+     * Number of macroblock rows at the bottom which are skipped.
+     * - encoding: unused
+     * - decoding: Set by user.
+     */
+    int skip_bottom;
+
+    /**
+     * Border processing masking, raises the quantizer for mbs on the borders
+     * of the picture.
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int rc_initial_buffer_occupancy;
+    float border_masking;
 
     /**
-     *
+     * minimum MB lagrange multipler
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int inter_threshold;
+    int mb_lmin;
 
     /**
-     * CODEC_FLAG2_*
+     * maximum MB lagrange multipler
      * - encoding: Set by user.
-     * - decoding: Set by user.
+     * - decoding: unused
      */
-    int flags2;
+    int mb_lmax;
 
     /**
-     * Simulates errors in the bitstream to test error concealment.
+     *
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int error_rate;
+    int me_penalty_compensation;
 
     /**
-     * MP3 antialias algorithm, see FF_AA_* below.
-     * - encoding: unused
-     * - decoding: Set by user.
+     *
+     * - encoding: Set by user.
+     * - decoding: unused
      */
-    int antialias_algo;
-#define FF_AA_AUTO    0
-#define FF_AA_FASTINT 1 //not implemented yet
-#define FF_AA_INT     2
-#define FF_AA_FLOAT   3
+    int bidir_refine;
+
     /**
-     * quantizer noise shaping
+     *
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int quantizer_noise_shaping;
+    int brd_scale;
 
     /**
-     * thread count
-     * is used to decide how many independent tasks should be passed to execute()
+     * minimum GOP size
      * - encoding: Set by user.
-     * - decoding: Set by user.
+     * - decoding: unused
      */
-    int thread_count;
+    int keyint_min;
 
     /**
-     * The codec may call this to execute several independent things.
-     * It will return only after finishing all tasks.
-     * The user may replace this with some multithreaded implementation,
-     * the default implementation will execute the parts serially.
-     * @param count the number of things to execute
-     * - encoding: Set by libavcodec, user can override.
-     * - decoding: Set by libavcodec, user can override.
+     * number of reference frames
+     * - encoding: Set by user.
+     * - decoding: Set by lavc.
      */
-    int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
+    int refs;
 
     /**
-     * thread opaque
-     * Can be used by execute() to store some per AVCodecContext stuff.
-     * - encoding: set by execute()
-     * - decoding: set by execute()
+     * chroma qp offset from luma
+     * - encoding: Set by user.
+     * - decoding: unused
      */
-    void *thread_opaque;
+    int chromaoffset;
 
     /**
-     * Motion estimation threshold below which no motion estimation is
-     * performed, but instead the user specified motion vectors are used.
-     *
+     * Multiplied by qscale for each frame and added to scene_change_score.
      * - encoding: Set by user.
      * - decoding: unused
      */
-     int me_threshold;
+    int scenechange_factor;
 
     /**
-     * Macroblock threshold below which the user specified macroblock types will be used.
+     *
+     * Note: Value depends upon the compare function used for fullpel ME.
      * - encoding: Set by user.
      * - decoding: unused
      */
-     int mb_threshold;
+    int mv0_threshold;
 
     /**
-     * precision of the intra DC coefficient - 8
+     * Adjust sensitivity of b_frame_strategy 1.
      * - encoding: Set by user.
      * - decoding: unused
      */
-     int intra_dc_precision;
+    int b_sensitivity;
 
     /**
-     * noise vs. sse weight for the nsse comparsion function
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Chromaticity coordinates of the source primaries.
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
      */
-     int nsse_weight;
+    enum AVColorPrimaries color_primaries;
 
     /**
-     * Number of macroblock rows at the top which are skipped.
-     * - encoding: unused
-     * - decoding: Set by user.
+     * Color Transfer Characteristic.
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
      */
-     int skip_top;
+    enum AVColorTransferCharacteristic color_trc;
 
     /**
-     * Number of macroblock rows at the bottom which are skipped.
-     * - encoding: unused
-     * - decoding: Set by user.
+     * YUV colorspace type.
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
      */
-     int skip_bottom;
+    enum AVColorSpace colorspace;
 
     /**
-     * profile
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
+     * MPEG vs JPEG YUV range.
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
      */
-     int profile;
-#define FF_PROFILE_UNKNOWN -99
-#define FF_PROFILE_AAC_MAIN 0
-#define FF_PROFILE_AAC_LOW  1
-#define FF_PROFILE_AAC_SSR  2
-#define FF_PROFILE_AAC_LTP  3
+    enum AVColorRange color_range;
 
     /**
-     * level
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
+     * This defines the location of chroma samples.
+     * - encoding: Set by user
+     * - decoding: Set by libavcodec
      */
-     int level;
-#define FF_LEVEL_UNKNOWN -99
+    enum AVChromaLocation chroma_sample_location;
 
     /**
-     * low resolution decoding, 1-> 1/2 size, 2->1/4 size
-     * - encoding: unused
+     * Number of slices.
+     * Indicates number of picture subdivisions. Used for parallelized
+     * decoding.
+     * - encoding: Set by user
+     * - decoding: unused
+     */
+    int slices;
+
+    /** Field order
+     * - encoding: set by libavcodec
      * - decoding: Set by user.
      */
-     int lowres;
+    enum AVFieldOrder field_order;
+
+    /* audio only */
+    int sample_rate; ///< samples per second
+    int channels;    ///< number of audio channels
 
     /**
-     * Bitstream width / height, may be different from width/height if lowres
-     * or other things are used.
-     * - encoding: unused
-     * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
+     * audio sample format
+     * - encoding: Set by user.
+     * - decoding: Set by libavcodec.
      */
-    int coded_width, coded_height;
+    enum AVSampleFormat sample_fmt;  ///< sample format
 
+    /* The following data should not be initialized. */
     /**
-     * frame skip threshold
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Samples per packet, initialized when calling 'init'.
      */
-    int frame_skip_threshold;
+    int frame_size;
 
     /**
-     * frame skip factor
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Frame counter, set by libavcodec.
+     *
+     * - decoding: total number of frames returned from the decoder so far.
+     * - encoding: total number of frames passed to the encoder so far.
+     *
+     *   @note the counter is not incremented if encoding/decoding resulted in
+     *   an error.
      */
-    int frame_skip_factor;
+    int frame_number;
 
     /**
-     * frame skip exponent
-     * - encoding: Set by user.
-     * - decoding: unused
+     * number of bytes per packet if constant and known or 0
+     * Used by some WAV based audio codecs.
      */
-    int frame_skip_exp;
+    int block_align;
 
     /**
-     * frame skip comparison function
+     * Audio cutoff bandwidth (0 means "automatic")
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int frame_skip_cmp;
+    int cutoff;
 
+#if FF_API_REQUEST_CHANNELS
     /**
-     * Border processing masking, raises the quantizer for mbs on the borders
-     * of the picture.
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Decoder should decode to this many channels if it can (0 for default)
+     * - encoding: unused
+     * - decoding: Set by user.
+     * @deprecated Deprecated in favor of request_channel_layout.
      */
-    float border_masking;
+    int request_channels;
+#endif
 
     /**
-     * minimum MB lagrange multipler
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Audio channel layout.
+     * - encoding: set by user.
+     * - decoding: set by user, may be overwritten by libavcodec.
      */
-    int mb_lmin;
+    uint64_t channel_layout;
 
     /**
-     * maximum MB lagrange multipler
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Request decoder to use this channel layout if it can (0 for default)
+     * - encoding: unused
+     * - decoding: Set by user.
      */
-    int mb_lmax;
+    uint64_t request_channel_layout;
 
     /**
-     *
+     * Type of service that the audio stream conveys.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: Set by libavcodec.
      */
-    int me_penalty_compensation;
+    enum AVAudioServiceType audio_service_type;
 
     /**
-     *
-     * - encoding: unused
+     * desired sample format
+     * - encoding: Not used.
      * - decoding: Set by user.
+     * Decoder will decode to this format if it can.
      */
-    enum AVDiscard skip_loop_filter;
+    enum AVSampleFormat request_sample_fmt;
 
     /**
+     * Called at the beginning of each frame to get a buffer for it.
+     *
+     * The function will set AVFrame.data[], AVFrame.linesize[].
+     * AVFrame.extended_data[] must also be set, but it should be the same as
+     * AVFrame.data[] except for planar audio with more channels than can fit
+     * in AVFrame.data[]. In that case, AVFrame.data[] shall still contain as
+     * many data pointers as it can hold.
+     *
+     * if CODEC_CAP_DR1 is not set then get_buffer() must call
+     * avcodec_default_get_buffer() instead of providing buffers allocated by
+     * some other means.
+     *
+     * AVFrame.data[] should be 32- or 16-byte-aligned unless the CPU doesn't
+     * need it. avcodec_default_get_buffer() aligns the output buffer properly,
+     * but if get_buffer() is overridden then alignment considerations should
+     * be taken into account.
+     *
+     * @see avcodec_default_get_buffer()
+     *
+     * Video:
+     *
+     * If pic.reference is set then the frame will be read later by libavcodec.
+     * avcodec_align_dimensions2() should be used to find the required width and
+     * height, as they normally need to be rounded up to the next multiple of 16.
+     *
+     * If frame multithreading is used and thread_safe_callbacks is set,
+     * it may be called from a different thread, but not from more than one at
+     * once. Does not need to be reentrant.
+     *
+     * @see release_buffer(), reget_buffer()
+     * @see avcodec_align_dimensions2()
+     *
+     * Audio:
+     *
+     * Decoders request a buffer of a particular size by setting
+     * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
+     * however, utilize only part of the buffer by setting AVFrame.nb_samples
+     * to a smaller value in the output frame.
+     *
+     * Decoders cannot use the buffer after returning from
+     * avcodec_decode_audio4(), so they will not call release_buffer(), as it
+     * is assumed to be released immediately upon return.
+     *
+     * As a convenience, av_samples_get_buffer_size() and
+     * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
+     * functions to find the required data size and to fill data pointers and
+     * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+     * since all planes must be the same size.
+     *
+     * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
      *
      * - encoding: unused
-     * - decoding: Set by user.
+     * - decoding: Set by libavcodec, user can override.
      */
-    enum AVDiscard skip_idct;
+    int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
 
     /**
-     *
+     * Called to release buffers which were allocated with get_buffer.
+     * A released buffer can be reused in get_buffer().
+     * pic.data[*] must be set to NULL.
+     * May be called from a different thread if frame multithreading is used,
+     * but not by more than one thread at once, so does not need to be reentrant.
      * - encoding: unused
-     * - decoding: Set by user.
+     * - decoding: Set by libavcodec, user can override.
      */
-    enum AVDiscard skip_frame;
+    void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
 
     /**
-     *
-     * - encoding: Set by user.
-     * - decoding: unused
+     * Called at the beginning of a frame to get cr buffer for it.
+     * Buffer type (size, hints) must be the same. libavcodec won't check it.
+     * libavcodec will pass previous buffer in pic, function should return
+     * same buffer or new buffer with old frame "painted" into it.
+     * If pic.data[0] == NULL must behave like get_buffer().
+     * if CODEC_CAP_DR1 is not set then reget_buffer() must call
+     * avcodec_default_reget_buffer() instead of providing buffers allocated by
+     * some other means.
+     * - encoding: unused
+     * - decoding: Set by libavcodec, user can override.
      */
-    int bidir_refine;
+    int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+
+    /* - encoding parameters */
+    float qcompress;  ///< amount of qscale change between easy & hard scenes (0.0-1.0)
+    float qblur;      ///< amount of qscale smoothing over time (0.0-1.0)
 
     /**
-     *
+     * minimum quantizer
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int brd_scale;
+    int qmin;
 
     /**
-     * constant rate factor - quality-based VBR - values ~correspond to qps
+     * maximum quantizer
      * - encoding: Set by user.
      * - decoding: unused
      */
-    float crf;
+    int qmax;
 
     /**
-     * constant quantization parameter rate control method
+     * maximum quantizer difference between frames
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int cqp;
+    int max_qdiff;
 
     /**
-     * minimum GOP size
+     * ratecontrol qmin qmax limiting method
+     * 0-> clipping, 1-> use a nice continuous function to limit qscale wthin qmin/qmax.
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int keyint_min;
+    float rc_qsquish;
+
+    float rc_qmod_amp;
+    int rc_qmod_freq;
 
     /**
-     * number of reference frames
+     * decoder bitstream buffer size
      * - encoding: Set by user.
-     * - decoding: Set by lavc.
+     * - decoding: unused
      */
-    int refs;
+    int rc_buffer_size;
 
     /**
-     * chroma qp offset from luma
-     * - encoding: Set by user.
+     * ratecontrol override, see RcOverride
+     * - encoding: Allocated/set/freed by user.
      * - decoding: unused
      */
-    int chromaoffset;
+    int rc_override_count;
+    RcOverride *rc_override;
 
     /**
-     * Influences how often B-frames are used.
-     * - encoding: Set by user.
+     * rate control equation
+     * - encoding: Set by user
      * - decoding: unused
      */
-    int bframebias;
+    const char *rc_eq;
 
     /**
-     * trellis RD quantization
+     * maximum bitrate
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int trellis;
+    int rc_max_rate;
 
     /**
-     * Reduce fluctuations in qp (before curve compression).
+     * minimum bitrate
      * - encoding: Set by user.
      * - decoding: unused
      */
-    float complexityblur;
+    int rc_min_rate;
+
+    float rc_buffer_aggressivity;
 
     /**
-     * in-loop deblocking filter alphac0 parameter
-     * alpha is in the range -6...6
+     * initial complexity for pass1 ratecontrol
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int deblockalpha;
+    float rc_initial_cplx;
 
     /**
-     * in-loop deblocking filter beta parameter
-     * beta is in the range -6...6
+     * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: unused.
      */
-    int deblockbeta;
+    float rc_max_available_vbv_use;
 
     /**
-     * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4
+     * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow.
      * - encoding: Set by user.
-     * - decoding: unused
+     * - decoding: unused.
      */
-    int partitions;
-#define X264_PART_I4X4 0x001  /* Analyze i4x4 */
-#define X264_PART_I8X8 0x002  /* Analyze i8x8 (requires 8x8 transform) */
-#define X264_PART_P8X8 0x010  /* Analyze p16x8, p8x16 and p8x8 */
-#define X264_PART_P4X4 0x020  /* Analyze p8x4, p4x8, p4x4 */
-#define X264_PART_B8X8 0x100  /* Analyze b16x8, b8x16 and b8x8 */
+    float rc_min_vbv_overflow_use;
 
     /**
-     * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)
+     * Number of bits which should be loaded into the rc buffer before decoding starts.
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int directpred;
+    int rc_initial_buffer_occupancy;
 
+#define FF_CODER_TYPE_VLC       0
+#define FF_CODER_TYPE_AC        1
+#define FF_CODER_TYPE_RAW       2
+#define FF_CODER_TYPE_RLE       3
+#define FF_CODER_TYPE_DEFLATE   4
     /**
-     * Audio cutoff bandwidth (0 means "automatic")
+     * coder type
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int cutoff;
+    int coder_type;
 
     /**
-     * Multiplied by qscale for each frame and added to scene_change_score.
+     * context model
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int scenechange_factor;
+    int context_model;
 
     /**
-     *
-     * Note: Value depends upon the compare function used for fullpel ME.
+     * minimum Lagrange multipler
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int mv0_threshold;
+    int lmin;
 
     /**
-     * Adjusts sensitivity of b_frame_strategy 1.
+     * maximum Lagrange multipler
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int b_sensitivity;
+    int lmax;
 
     /**
+     * frame skip threshold
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int compression_level;
-#define FF_COMPRESSION_DEFAULT -1
+    int frame_skip_threshold;
 
     /**
-     * Sets whether to use LPC mode - used by FLAC encoder.
+     * frame skip factor
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int use_lpc;
+    int frame_skip_factor;
 
     /**
-     * LPC coefficient precision - used by FLAC encoder
+     * frame skip exponent
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int lpc_coeff_precision;
+    int frame_skip_exp;
 
     /**
+     * frame skip comparison function
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int min_prediction_order;
+    int frame_skip_cmp;
 
     /**
+     * trellis RD quantization
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int max_prediction_order;
+    int trellis;
 
     /**
-     * search method for selecting prediction order
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int prediction_order_method;
+    int min_prediction_order;
 
     /**
      * - encoding: Set by user.
      * - decoding: unused
      */
-    int min_partition_order;
+    int max_prediction_order;
 
     /**
-     * - encoding: Set by user.
+     * GOP timecode frame start number
+     * - encoding: Set by user, in non drop frame format
+     * - decoding: Set by libavcodec (timecode in the 25 bits format, -1 if unset)
+     */
+    int64_t timecode_frame_start;
+
+    /* The RTP callback: This function is called    */
+    /* every time the encoder has a packet to send. */
+    /* It depends on the encoder if the data starts */
+    /* with a Start Code (it should). H.263 does.   */
+    /* mb_nb contains the number of macroblocks     */
+    /* encoded in the RTP payload.                  */
+    void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
+
+    int rtp_payload_size;   /* The size of the RTP payload: the coder will  */
+                            /* do its best to deliver a chunk with size     */
+                            /* below rtp_payload_size, the chunk will start */
+                            /* with a start code on some codecs like H.263. */
+                            /* This doesn't take account of any particular  */
+                            /* headers inside the transmitted RTP payload.  */
+
+    /* statistics, used for 2-pass encoding */
+    int mv_bits;
+    int header_bits;
+    int i_tex_bits;
+    int p_tex_bits;
+    int i_count;
+    int p_count;
+    int skip_count;
+    int misc_bits;
+
+    /**
+     * number of bits used for the previously encoded frame
+     * - encoding: Set by libavcodec.
      * - decoding: unused
      */
-    int max_partition_order;
+    int frame_bits;
 
     /**
-     * GOP timecode frame start number, in non drop frame format
-     * - encoding: Set by user.
+     * pass1 encoding statistics output buffer
+     * - encoding: Set by libavcodec.
      * - decoding: unused
      */
-    int64_t timecode_frame_start;
+    char *stats_out;
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
     /**
-     * Decoder should decode to this many channels if it can (0 for default)
-     * - encoding: unused
-     * - decoding: Set by user.
-     * @deprecated Deprecated in favor of request_channel_layout.
+     * pass2 encoding statistics input buffer
+     * Concatenated stuff from stats_out of pass1 should be placed here.
+     * - encoding: Allocated/set/freed by user.
+     * - decoding: unused
      */
-    int request_channels;
-#endif
+    char *stats_in;
 
     /**
-     * Percentage of dynamic range compression to be applied by the decoder.
-     * The default value is 1.0, corresponding to full compression.
-     * - encoding: unused
+     * Work around bugs in encoders which sometimes cannot be detected automatically.
+     * - encoding: Set by user
+     * - decoding: Set by user
+     */
+    int workaround_bugs;
+#define FF_BUG_AUTODETECT       1  ///< autodetection
+#define FF_BUG_OLD_MSMPEG4      2
+#define FF_BUG_XVID_ILACE       4
+#define FF_BUG_UMP4             8
+#define FF_BUG_NO_PADDING       16
+#define FF_BUG_AMV              32
+#define FF_BUG_AC_VLC           0  ///< Will be removed, libavcodec can now handle these non-compliant files by default.
+#define FF_BUG_QPEL_CHROMA      64
+#define FF_BUG_STD_QPEL         128
+#define FF_BUG_QPEL_CHROMA2     256
+#define FF_BUG_DIRECT_BLOCKSIZE 512
+#define FF_BUG_EDGE             1024
+#define FF_BUG_HPEL_CHROMA      2048
+#define FF_BUG_DC_CLIP          4096
+#define FF_BUG_MS               8192 ///< Work around various bugs in Microsoft's broken decoders.
+#define FF_BUG_TRUNCATED       16384
+
+    /**
+     * strictly follow the standard (MPEG4, ...).
+     * - encoding: Set by user.
      * - decoding: Set by user.
+     * Setting this to STRICT or higher means the encoder and decoder will
+     * generally do stupid things, whereas setting it to unofficial or lower
+     * will mean the encoder might produce output that is not supported by all
+     * spec-compliant decoders. Decoders don't differentiate between normal,
+     * unofficial and experimental (that is, they always try to decode things
+     * when they can) unless they are explicitly asked to behave stupidly
+     * (=strictly conform to the specs)
      */
-    float drc_scale;
+    int strict_std_compliance;
+#define FF_COMPLIANCE_VERY_STRICT   2 ///< Strictly conform to an older more strict version of the spec or reference software.
+#define FF_COMPLIANCE_STRICT        1 ///< Strictly conform to all the things in the spec no matter what consequences.
+#define FF_COMPLIANCE_NORMAL        0
+#define FF_COMPLIANCE_UNOFFICIAL   -1 ///< Allow unofficial extensions
+#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
 
     /**
-     * opaque 64bit number (generally a PTS) that will be reordered and
-     * output in AVFrame.reordered_opaque
+     * error concealment flags
      * - encoding: unused
      * - decoding: Set by user.
      */
-    int64_t reordered_opaque;
+    int error_concealment;
+#define FF_EC_GUESS_MVS   1
+#define FF_EC_DEBLOCK     2
 
     /**
-     * Bits per sample/pixel of internal libavcodec pixel/sample format.
-     * This field is applicable only when sample_fmt is SAMPLE_FMT_S32.
-     * - encoding: set by user.
-     * - decoding: set by libavcodec.
+     * debug
+     * - encoding: Set by user.
+     * - decoding: Set by user.
      */
-    int bits_per_raw_sample;
+    int debug;
+#define FF_DEBUG_PICT_INFO   1
+#define FF_DEBUG_RC          2
+#define FF_DEBUG_BITSTREAM   4
+#define FF_DEBUG_MB_TYPE     8
+#define FF_DEBUG_QP          16
+#define FF_DEBUG_MV          32
+#define FF_DEBUG_DCT_COEFF   0x00000040
+#define FF_DEBUG_SKIP        0x00000080
+#define FF_DEBUG_STARTCODE   0x00000100
+#define FF_DEBUG_PTS         0x00000200
+#define FF_DEBUG_ER          0x00000400
+#define FF_DEBUG_MMCO        0x00000800
+#define FF_DEBUG_BUGS        0x00001000
+#define FF_DEBUG_VIS_QP      0x00002000
+#define FF_DEBUG_VIS_MB_TYPE 0x00004000
+#define FF_DEBUG_BUFFERS     0x00008000
+#define FF_DEBUG_THREADS     0x00010000
 
     /**
-     * Audio channel layout.
-     * - encoding: set by user.
-     * - decoding: set by libavcodec.
+     * debug
+     * - encoding: Set by user.
+     * - decoding: Set by user.
      */
-    int64_t channel_layout;
+    int debug_mv;
+#define FF_DEBUG_VIS_MV_P_FOR  0x00000001 //visualize forward predicted MVs of P frames
+#define FF_DEBUG_VIS_MV_B_FOR  0x00000002 //visualize forward predicted MVs of B frames
+#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
 
     /**
-     * Request decoder to use this channel layout if it can (0 for default)
+     * Error recognition; may misdetect some more or less valid parts as errors.
      * - encoding: unused
      * - decoding: Set by user.
      */
-    int64_t request_channel_layout;
+    int err_recognition;
+#define AV_EF_CRCCHECK  (1<<0)
+#define AV_EF_BITSTREAM (1<<1)
+#define AV_EF_BUFFER    (1<<2)
+#define AV_EF_EXPLODE   (1<<3)
+
+#define AV_EF_CAREFUL    (1<<16)
+#define AV_EF_COMPLIANT  (1<<17)
+#define AV_EF_AGGRESSIVE (1<<18)
 
-    /**
-     * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
-     * - encoding: Set by user.
-     * - decoding: unused.
-     */
-    float rc_max_available_vbv_use;
 
     /**
-     * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow.
-     * - encoding: Set by user.
-     * - decoding: unused.
+     * opaque 64bit number (generally a PTS) that will be reordered and
+     * output in AVFrame.reordered_opaque
+     * @deprecated in favor of pkt_pts
+     * - encoding: unused
+     * - decoding: Set by user.
      */
-    float rc_min_vbv_overflow_use;
+    int64_t reordered_opaque;
 
     /**
      * Hardware accelerator in use
@@ -2450,15 +2746,6 @@ typedef struct AVCodecContext {
      */
     struct AVHWAccel *hwaccel;
 
-    /**
-     * For some codecs, the time base is closer to the field rate than the frame rate.
-     * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
-     * if no telecine is used ...
-     *
-     * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
-     */
-    int ticks_per_frame;
-
     /**
      * Hardware accelerator context.
      * For some hardware accelerators, a global context needs to be
@@ -2472,80 +2759,451 @@ typedef struct AVCodecContext {
     void *hwaccel_context;
 
     /**
-     * Chromaticity coordinates of the source primaries.
-     * - encoding: Set by user
-     * - decoding: Set by libavcodec
+     * error
+     * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR.
+     * - decoding: unused
      */
-    enum AVColorPrimaries color_primaries;
+    uint64_t error[AV_NUM_DATA_POINTERS];
 
     /**
-     * Color Transfer Characteristic.
-     * - encoding: Set by user
-     * - decoding: Set by libavcodec
+     * DCT algorithm, see FF_DCT_* below
+     * - encoding: Set by user.
+     * - decoding: unused
      */
-    enum AVColorTransferCharacteristic color_trc;
+    int dct_algo;
+#define FF_DCT_AUTO    0
+#define FF_DCT_FASTINT 1
+#define FF_DCT_INT     2
+#define FF_DCT_MMX     3
+#define FF_DCT_ALTIVEC 5
+#define FF_DCT_FAAN    6
 
     /**
-     * YUV colorspace type.
-     * - encoding: Set by user
-     * - decoding: Set by libavcodec
+     * IDCT algorithm, see FF_IDCT_* below.
+     * - encoding: Set by user.
+     * - decoding: Set by user.
      */
-    enum AVColorSpace colorspace;
+    int idct_algo;
+#define FF_IDCT_AUTO          0
+#define FF_IDCT_INT           1
+#define FF_IDCT_SIMPLE        2
+#define FF_IDCT_SIMPLEMMX     3
+#define FF_IDCT_LIBMPEG2MMX   4
+#if FF_API_MMI
+#define FF_IDCT_MMI           5
+#endif
+#define FF_IDCT_ARM           7
+#define FF_IDCT_ALTIVEC       8
+#define FF_IDCT_SH4           9
+#define FF_IDCT_SIMPLEARM     10
+#define FF_IDCT_H264          11
+#define FF_IDCT_VP3           12
+#define FF_IDCT_IPP           13
+#define FF_IDCT_XVIDMMX       14
+#define FF_IDCT_CAVS          15
+#define FF_IDCT_SIMPLEARMV5TE 16
+#define FF_IDCT_SIMPLEARMV6   17
+#define FF_IDCT_SIMPLEVIS     18
+#define FF_IDCT_WMV2          19
+#define FF_IDCT_FAAN          20
+#define FF_IDCT_EA            21
+#define FF_IDCT_SIMPLENEON    22
+#define FF_IDCT_SIMPLEALPHA   23
+#define FF_IDCT_BINK          24
 
+#if FF_API_DSP_MASK
     /**
-     * MPEG vs JPEG YUV range.
-     * - encoding: Set by user
-     * - decoding: Set by libavcodec
+     * Unused.
+     * @deprecated use av_set_cpu_flags_mask() instead.
      */
-    enum AVColorRange color_range;
+    attribute_deprecated unsigned dsp_mask;
+#endif
 
     /**
-     * This defines the location of chroma samples.
-     * - encoding: Set by user
-     * - decoding: Set by libavcodec
+     * bits per sample/pixel from the demuxer (needed for huffyuv).
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by user.
      */
-     enum AVChromaLocation chroma_sample_location;
-} AVCodecContext;
+     int bits_per_coded_sample;
 
-/**
- * AVCodec.
- */
-typedef struct AVCodec {
     /**
-     * Name of the codec implementation.
-     * The name is globally unique among encoders and among decoders (but an
-     * encoder and a decoder can share the same name).
-     * This is the primary way to find a codec from the user perspective.
+     * Bits per sample/pixel of internal libavcodec pixel/sample format.
+     * - encoding: set by user.
+     * - decoding: set by libavcodec.
      */
-    const char *name;
-    enum CodecType type;
-    enum CodecID id;
-    int priv_data_size;
-    int (*init)(AVCodecContext *);
-    int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
-    int (*close)(AVCodecContext *);
-    int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
+    int bits_per_raw_sample;
+
     /**
-     * Codec capabilities.
-     * see CODEC_CAP_*
+     * low resolution decoding, 1-> 1/2 size, 2->1/4 size
+     * - encoding: unused
+     * - decoding: Set by user.
+     */
+     int lowres;
+
+    /**
+     * the picture in the bitstream
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by libavcodec.
+     */
+    AVFrame *coded_frame;
+
+    /**
+     * thread count
+     * is used to decide how many independent tasks should be passed to execute()
+     * - encoding: Set by user.
+     * - decoding: Set by user.
+     */
+    int thread_count;
+
+    /**
+     * Which multithreading methods to use.
+     * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread,
+     * so clients which cannot provide future frames should not use it.
+     *
+     * - encoding: Set by user, otherwise the default is used.
+     * - decoding: Set by user, otherwise the default is used.
+     */
+    int thread_type;
+#define FF_THREAD_FRAME   1 ///< Decode more than one frame at once
+#define FF_THREAD_SLICE   2 ///< Decode more than one part of a single frame at once
+
+    /**
+     * Which multithreading methods are in use by the codec.
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by libavcodec.
+     */
+    int active_thread_type;
+
+    /**
+     * Set by the client if its custom get_buffer() callback can be called
+     * synchronously from another thread, which allows faster multithreaded decoding.
+     * draw_horiz_band() will be called from other threads regardless of this setting.
+     * Ignored if the default get_buffer() is used.
+     * - encoding: Set by user.
+     * - decoding: Set by user.
+     */
+    int thread_safe_callbacks;
+
+    /**
+     * The codec may call this to execute several independent things.
+     * It will return only after finishing all tasks.
+     * The user may replace this with some multithreaded implementation,
+     * the default implementation will execute the parts serially.
+     * @param count the number of things to execute
+     * - encoding: Set by libavcodec, user can override.
+     * - decoding: Set by libavcodec, user can override.
+     */
+    int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
+
+    /**
+     * The codec may call this to execute several independent things.
+     * It will return only after finishing all tasks.
+     * The user may replace this with some multithreaded implementation,
+     * the default implementation will execute the parts serially.
+     * Also see avcodec_thread_init and e.g. the --enable-pthread configure option.
+     * @param c context passed also to func
+     * @param count the number of things to execute
+     * @param arg2 argument passed unchanged to func
+     * @param ret return values of executed functions, must have space for "count" values. May be NULL.
+     * @param func function that will be called count times, with jobnr from 0 to count-1.
+     *             threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no
+     *             two instances of func executing at the same time will have the same threadnr.
+     * @return always 0 currently, but code should handle a future improvement where when any call to func
+     *         returns < 0 no further calls to func may be done and < 0 is returned.
+     * - encoding: Set by libavcodec, user can override.
+     * - decoding: Set by libavcodec, user can override.
+     */
+    int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
+
+    /**
+     * thread opaque
+     * Can be used by execute() to store some per AVCodecContext stuff.
+     * - encoding: set by execute()
+     * - decoding: set by execute()
+     */
+    void *thread_opaque;
+
+    /**
+     * noise vs. sse weight for the nsse comparsion function
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+     int nsse_weight;
+
+    /**
+     * profile
+     * - encoding: Set by user.
+     * - decoding: Set by libavcodec.
+     */
+     int profile;
+#define FF_PROFILE_UNKNOWN -99
+#define FF_PROFILE_RESERVED -100
+
+#define FF_PROFILE_AAC_MAIN 0
+#define FF_PROFILE_AAC_LOW  1
+#define FF_PROFILE_AAC_SSR  2
+#define FF_PROFILE_AAC_LTP  3
+#define FF_PROFILE_AAC_HE   4
+#define FF_PROFILE_AAC_HE_V2 28
+#define FF_PROFILE_AAC_LD   22
+#define FF_PROFILE_AAC_ELD  38
+
+#define FF_PROFILE_DTS         20
+#define FF_PROFILE_DTS_ES      30
+#define FF_PROFILE_DTS_96_24   40
+#define FF_PROFILE_DTS_HD_HRA  50
+#define FF_PROFILE_DTS_HD_MA   60
+
+#define FF_PROFILE_MPEG2_422    0
+#define FF_PROFILE_MPEG2_HIGH   1
+#define FF_PROFILE_MPEG2_SS     2
+#define FF_PROFILE_MPEG2_SNR_SCALABLE  3
+#define FF_PROFILE_MPEG2_MAIN   4
+#define FF_PROFILE_MPEG2_SIMPLE 5
+
+#define FF_PROFILE_H264_CONSTRAINED  (1<<9)  // 8+1; constraint_set1_flag
+#define FF_PROFILE_H264_INTRA        (1<<11) // 8+3; constraint_set3_flag
+
+#define FF_PROFILE_H264_BASELINE             66
+#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
+#define FF_PROFILE_H264_MAIN                 77
+#define FF_PROFILE_H264_EXTENDED             88
+#define FF_PROFILE_H264_HIGH                 100
+#define FF_PROFILE_H264_HIGH_10              110
+#define FF_PROFILE_H264_HIGH_10_INTRA        (110|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_HIGH_422             122
+#define FF_PROFILE_H264_HIGH_422_INTRA       (122|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_HIGH_444             144
+#define FF_PROFILE_H264_HIGH_444_PREDICTIVE  244
+#define FF_PROFILE_H264_HIGH_444_INTRA       (244|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_CAVLC_444            44
+
+#define FF_PROFILE_VC1_SIMPLE   0
+#define FF_PROFILE_VC1_MAIN     1
+#define FF_PROFILE_VC1_COMPLEX  2
+#define FF_PROFILE_VC1_ADVANCED 3
+
+#define FF_PROFILE_MPEG4_SIMPLE                     0
+#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE            1
+#define FF_PROFILE_MPEG4_CORE                       2
+#define FF_PROFILE_MPEG4_MAIN                       3
+#define FF_PROFILE_MPEG4_N_BIT                      4
+#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE           5
+#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION      6
+#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE     7
+#define FF_PROFILE_MPEG4_HYBRID                     8
+#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME         9
+#define FF_PROFILE_MPEG4_CORE_SCALABLE             10
+#define FF_PROFILE_MPEG4_ADVANCED_CODING           11
+#define FF_PROFILE_MPEG4_ADVANCED_CORE             12
+#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
+#define FF_PROFILE_MPEG4_SIMPLE_STUDIO             14
+#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE           15
+
+    /**
+     * level
+     * - encoding: Set by user.
+     * - decoding: Set by libavcodec.
+     */
+     int level;
+#define FF_LEVEL_UNKNOWN -99
+
+    /**
+     *
+     * - encoding: unused
+     * - decoding: Set by user.
+     */
+    enum AVDiscard skip_loop_filter;
+
+    /**
+     *
+     * - encoding: unused
+     * - decoding: Set by user.
+     */
+    enum AVDiscard skip_idct;
+
+    /**
+     *
+     * - encoding: unused
+     * - decoding: Set by user.
+     */
+    enum AVDiscard skip_frame;
+
+    /**
+     * Header containing style information for text subtitles.
+     * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
+     * [Script Info] and [V4+ Styles] section, plus the [Events] line and
+     * the Format line following. It shouldn't include any Dialogue line.
+     * - encoding: Set/allocated/freed by user (before avcodec_open2())
+     * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
+     */
+    uint8_t *subtitle_header;
+    int subtitle_header_size;
+
+    /**
+     * Simulates errors in the bitstream to test error concealment.
+     * - encoding: Set by user.
+     * - decoding: unused
+     */
+    int error_rate;
+
+    /**
+     * Current packet as passed into the decoder, to avoid having
+     * to pass the packet into every function. Currently only valid
+     * inside lavc and get/release_buffer callbacks.
+     * - decoding: set by avcodec_decode_*, read by get_buffer() for setting pkt_pts
+     * - encoding: unused
+     */
+    AVPacket *pkt;
+
+    /**
+     * VBV delay coded in the last frame (in periods of a 27 MHz clock).
+     * Used for compliant TS muxing.
+     * - encoding: Set by libavcodec.
+     * - decoding: unused.
+     */
+    uint64_t vbv_delay;
+
+    /**
+     * Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
+     * Code outside libavcodec should access this field using:
+     * avcodec_set_pkt_timebase(avctx)
+     * - encoding unused.
+     * - decodimg set by user
+     */
+    AVRational pkt_timebase;
+
+    /**
+     * AVCodecDescriptor
+     * Code outside libavcodec should access this field using:
+     * avcodec_get_codec_descriptior(avctx)
+     * - encoding: unused.
+     * - decoding: set by libavcodec.
+     */
+    const AVCodecDescriptor *codec_descriptor;
+
+    /**
+     * Current statistics for PTS correction.
+     * - decoding: maintained and used by libavcodec, not intended to be used by user apps
+     * - encoding: unused
+     */
+    int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
+    int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
+    int64_t pts_correction_last_pts;       /// PTS of the last frame
+    int64_t pts_correction_last_dts;       /// DTS of the last frame
+} AVCodecContext;
+
+AVRational av_codec_get_pkt_timebase         (const AVCodecContext *avctx);
+void       av_codec_set_pkt_timebase         (AVCodecContext *avctx, AVRational val);
+
+const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx);
+void                     av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc);
+
+/**
+ * AVProfile.
+ */
+typedef struct AVProfile {
+    int profile;
+    const char *name; ///< short name for the profile
+} AVProfile;
+
+typedef struct AVCodecDefault AVCodecDefault;
+
+struct AVSubtitle;
+
+/**
+ * AVCodec.
+ */
+typedef struct AVCodec {
+    /**
+     * Name of the codec implementation.
+     * The name is globally unique among encoders and among decoders (but an
+     * encoder and a decoder can share the same name).
+     * This is the primary way to find a codec from the user perspective.
+     */
+    const char *name;
+    /**
+     * Descriptive name for the codec, meant to be more human readable than name.
+     * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
+     */
+    const char *long_name;
+    enum AVMediaType type;
+    enum AVCodecID id;
+    /**
+     * Codec capabilities.
+     * see CODEC_CAP_*
      */
     int capabilities;
+    const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
+    const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
+    const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
+    const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
+    const uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
+    uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoder
+    const AVClass *priv_class;              ///< AVClass for the private context
+    const AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
+
+    /*****************************************************************
+     * No fields below this line are part of the public API. They
+     * may not be used outside of libavcodec and can be changed and
+     * removed at will.
+     * New public fields should be added right above.
+     *****************************************************************
+     */
+    int priv_data_size;
     struct AVCodec *next;
+    /**
+     * @name Frame-level threading support functions
+     * @{
+     */
+    /**
+     * If defined, called on thread contexts when they are created.
+     * If the codec allocates writable tables in init(), re-allocate them here.
+     * priv_data will be set to a copy of the original.
+     */
+    int (*init_thread_copy)(AVCodecContext *);
+    /**
+     * Copy necessary context variables from a previous thread context to the current one.
+     * If not defined, the next thread will start automatically; otherwise, the codec
+     * must call ff_thread_finish_setup().
+     *
+     * dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
+     */
+    int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
+    /** @} */
+
+    /**
+     * Private codec-specific defaults.
+     */
+    const AVCodecDefault *defaults;
+
+    /**
+     * Initialize codec static data, called from avcodec_register().
+     */
+    void (*init_static_data)(struct AVCodec *codec);
+
+    int (*init)(AVCodecContext *);
+    int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
+                      const struct AVSubtitle *sub);
+    /**
+     * Encode data to an AVPacket.
+     *
+     * @param      avctx          codec context
+     * @param      avpkt          output AVPacket (may contain a user-provided buffer)
+     * @param[in]  frame          AVFrame containing the raw data to be encoded
+     * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
+     *                            non-empty packet was returned in avpkt.
+     * @return 0 on success, negative error code on failure
+     */
+    int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame,
+                   int *got_packet_ptr);
+    int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
+    int (*close)(AVCodecContext *);
     /**
      * Flush buffers.
      * Will be called when seeking
      */
     void (*flush)(AVCodecContext *);
-    const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
-    const enum PixelFormat *pix_fmts;       ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
-    /**
-     * Descriptive name for the codec, meant to be more human readable than \p name.
-     * You \e should use the NULL_IF_CONFIG_SMALL() macro to define it.
-     */
-    const char *long_name;
-    const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
-    const enum SampleFormat *sample_fmts;   ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
-    const int64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
 } AVCodec;
 
 /**
@@ -2562,23 +3220,23 @@ typedef struct AVHWAccel {
     /**
      * Type of codec implemented by the hardware accelerator.
      *
-     * See CODEC_TYPE_xxx
+     * See AVMEDIA_TYPE_xxx
      */
-    enum CodecType type;
+    enum AVMediaType type;
 
     /**
      * Codec implemented by the hardware accelerator.
      *
-     * See CODEC_ID_xxx
+     * See AV_CODEC_ID_xxx
      */
-    enum CodecID id;
+    enum AVCodecID id;
 
     /**
      * Supported pixel format.
      *
      * Only hardware accelerated formats are supported here.
      */
-    enum PixelFormat pix_fmt;
+    enum AVPixelFormat pix_fmt;
 
     /**
      * Hardware accelerated codec capabilities.
@@ -2594,7 +3252,7 @@ typedef struct AVHWAccel {
      * Meaningful frame information (codec specific) is guaranteed to
      * be parsed at this point. This function is mandatory.
      *
-     * Note that \p buf can be NULL along with \p buf_size set to 0.
+     * Note that buf can be NULL along with buf_size set to 0.
      * Otherwise, this means the whole frame is available at this point.
      *
      * @param avctx the codec context
@@ -2638,40 +3296,25 @@ typedef struct AVHWAccel {
     int priv_data_size;
 } AVHWAccel;
 
+/**
+ * @defgroup lavc_picture AVPicture
+ *
+ * Functions for working with AVPicture
+ * @{
+ */
+
 /**
  * four components are given, that's all.
  * the last component is alpha
  */
 typedef struct AVPicture {
-    uint8_t *data[4];
-    int linesize[4];       ///< number of bytes per line
+    uint8_t *data[AV_NUM_DATA_POINTERS];
+    int linesize[AV_NUM_DATA_POINTERS];     ///< number of bytes per line
 } AVPicture;
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
 /**
- * AVPaletteControl
- * This structure defines a method for communicating palette changes
- * between and demuxer and a decoder.
- *
- * @deprecated Use AVPacket to send palette changes instead.
- * This is totally broken.
+ * @}
  */
-#define AVPALETTE_SIZE 1024
-#define AVPALETTE_COUNT 256
-typedef struct AVPaletteControl {
-
-    /* Demuxer sets this to 1 to indicate the palette has changed;
-     * decoder resets to 0. */
-    int palette_changed;
-
-    /* 4-byte ARGB palette entries, stored in native byte order; note that
-     * the individual palette components should be on a 8-bit scale; if
-     * the palette data comes from an IBM VGA native format, the component
-     * data is probably 6 bits in size and needs to be scaled. */
-    unsigned int palette[AVPALETTE_COUNT];
-
-} AVPaletteControl attribute_deprecated;
-#endif
 
 enum AVSubtitleType {
     SUBTITLE_NONE,
@@ -2709,10 +3352,16 @@ typedef struct AVSubtitleRect {
 
     /**
      * 0 terminated ASS/SSA compatible event line.
-     * The pressentation of this is unaffected by the other values in this
+     * The presentation of this is unaffected by the other values in this
      * struct.
      */
     char *ass;
+
+    /**
+     * 1 indicates this subtitle is a forced subtitle.
+     * A forced subtitle should be displayed even when subtitles are hidden.
+     */
+    int forced;
 } AVSubtitleRect;
 
 typedef struct AVSubtitle {
@@ -2721,638 +3370,1343 @@ typedef struct AVSubtitle {
     uint32_t end_display_time; /* relative to packet pts, in ms */
     unsigned num_rects;
     AVSubtitleRect **rects;
+    int64_t pts;    ///< Same as packet pts, in AV_TIME_BASE
 } AVSubtitle;
 
-/* packet functions */
-
 /**
- * @deprecated use NULL instead
+ * If c is NULL, returns the first registered codec,
+ * if c is non-NULL, returns the next registered codec after c,
+ * or NULL if c is the last one.
  */
-attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt);
+AVCodec *av_codec_next(const AVCodec *c);
 
 /**
- * Default packet destructor.
+ * Return the LIBAVCODEC_VERSION_INT constant.
  */
-void av_destruct_packet(AVPacket *pkt);
+unsigned avcodec_version(void);
 
 /**
- * Initialize optional fields of a packet with default values.
- *
- * @param pkt packet
+ * Return the libavcodec build-time configuration.
  */
-void av_init_packet(AVPacket *pkt);
+const char *avcodec_configuration(void);
 
 /**
- * Allocate the payload of a packet and initialize its fields with
- * default values.
- *
- * @param pkt packet
- * @param size wanted payload size
- * @return 0 if OK, AVERROR_xxx otherwise
+ * Return the libavcodec license.
  */
-int av_new_packet(AVPacket *pkt, int size);
+const char *avcodec_license(void);
 
 /**
- * Reduce packet size, correctly zeroing padding
+ * Register the codec codec and initialize libavcodec.
  *
- * @param pkt packet
- * @param size new size
+ * @warning either this function or avcodec_register_all() must be called
+ * before any other libavcodec functions.
+ *
+ * @see avcodec_register_all()
  */
-void av_shrink_packet(AVPacket *pkt, int size);
+void avcodec_register(AVCodec *codec);
 
 /**
- * @warning This is a hack - the packet memory allocation stuff is broken. The
- * packet is allocated if it was not really allocated.
+ * Register all the codecs, parsers and bitstream filters which were enabled at
+ * configuration time. If you do not call this function you can select exactly
+ * which formats you want to support, by using the individual registration
+ * functions.
+ *
+ * @see avcodec_register
+ * @see av_register_codec_parser
+ * @see av_register_bitstream_filter
  */
-int av_dup_packet(AVPacket *pkt);
+void avcodec_register_all(void);
 
+
+#if FF_API_ALLOC_CONTEXT
 /**
- * Free a packet.
+ * Allocate an AVCodecContext and set its fields to default values.  The
+ * resulting struct can be deallocated by simply calling av_free().
  *
- * @param pkt packet to free
+ * @return An AVCodecContext filled with default values or NULL on failure.
+ * @see avcodec_get_context_defaults
+ *
+ * @deprecated use avcodec_alloc_context3()
  */
-void av_free_packet(AVPacket *pkt);
+attribute_deprecated
+AVCodecContext *avcodec_alloc_context(void);
 
-/* resample.c */
+/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
+ *  we WILL change its arguments and name a few times! */
+attribute_deprecated
+AVCodecContext *avcodec_alloc_context2(enum AVMediaType);
 
-struct ReSampleContext;
-struct AVResampleContext;
+/**
+ * Set the fields of the given AVCodecContext to default values.
+ *
+ * @param s The AVCodecContext of which the fields should be set to default values.
+ * @deprecated use avcodec_get_context_defaults3
+ */
+attribute_deprecated
+void avcodec_get_context_defaults(AVCodecContext *s);
 
-typedef struct ReSampleContext ReSampleContext;
+/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
+ *  we WILL change its arguments and name a few times! */
+attribute_deprecated
+void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType);
+#endif
+
+/**
+ * Allocate an AVCodecContext and set its fields to default values.  The
+ * resulting struct can be deallocated by calling avcodec_close() on it followed
+ * by av_free().
+ *
+ * @param codec if non-NULL, allocate private data and initialize defaults
+ *              for the given codec. It is illegal to then call avcodec_open2()
+ *              with a different codec.
+ *              If NULL, then the codec-specific defaults won't be initialized,
+ *              which may result in suboptimal default settings (this is
+ *              important mainly for encoders, e.g. libx264).
+ *
+ * @return An AVCodecContext filled with default values or NULL on failure.
+ * @see avcodec_get_context_defaults
+ */
+AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
+
+/**
+ * Set the fields of the given AVCodecContext to default values corresponding
+ * to the given codec (defaults may be codec-dependent).
+ *
+ * Do not call this function if a non-NULL codec has been passed
+ * to avcodec_alloc_context3() that allocated this AVCodecContext.
+ * If codec is non-NULL, it is illegal to call avcodec_open2() with a
+ * different codec on this AVCodecContext.
+ */
+int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec);
+
+/**
+ * Get the AVClass for AVCodecContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_class(void);
+
+/**
+ * Get the AVClass for AVFrame. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_frame_class(void);
+
+/**
+ * Get the AVClass for AVSubtitleRect. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_subtitle_rect_class(void);
+
+/**
+ * Copy the settings of the source AVCodecContext into the destination
+ * AVCodecContext. The resulting destination codec context will be
+ * unopened, i.e. you are required to call avcodec_open2() before you
+ * can use this AVCodecContext to decode/encode video/audio data.
+ *
+ * @param dest target codec context, should be initialized with
+ *             avcodec_alloc_context3(), but otherwise uninitialized
+ * @param src source codec context
+ * @return AVERROR() on error (e.g. memory allocation error), 0 on success
+ */
+int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
+
+/**
+ * Allocate an AVFrame and set its fields to default values.  The resulting
+ * struct must be freed using avcodec_free_frame().
+ *
+ * @return An AVFrame filled with default values or NULL on failure.
+ * @see avcodec_get_frame_defaults
+ */
+AVFrame *avcodec_alloc_frame(void);
+
+/**
+ * Set the fields of the given AVFrame to default values.
+ *
+ * @param frame The AVFrame of which the fields should be set to default values.
+ */
+void avcodec_get_frame_defaults(AVFrame *frame);
+
+/**
+ * Free the frame and any dynamically allocated objects in it,
+ * e.g. extended_data.
+ *
+ * @param frame frame to be freed. The pointer will be set to NULL.
+ *
+ * @warning this function does NOT free the data buffers themselves
+ * (it does not know how, since they might have been allocated with
+ *  a custom get_buffer()).
+ */
+void avcodec_free_frame(AVFrame **frame);
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
+#if FF_API_AVCODEC_OPEN
 /**
- * @deprecated Use av_audio_resample_init() instead.
+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated.
+ *
+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @code
+ * avcodec_register_all();
+ * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
+ * if (!codec)
+ *     exit(1);
+ *
+ * context = avcodec_alloc_context3(codec);
+ *
+ * if (avcodec_open(context, codec) < 0)
+ *     exit(1);
+ * @endcode
+ *
+ * @param avctx The context which will be set up to use the given codec.
+ * @param codec The codec to use within the context.
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close
+ *
+ * @deprecated use avcodec_open2
  */
-attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels,
-                                                          int output_rate, int input_rate);
+attribute_deprecated
+int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
 #endif
+
 /**
- *  Initializes audio resampling context
+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated with avcodec_alloc_context3().
  *
- * @param output_channels  number of output channels
- * @param input_channels   number of input channels
- * @param output_rate      output sample rate
- * @param input_rate       input sample rate
- * @param sample_fmt_out   requested output sample format
- * @param sample_fmt_in    input sample format
- * @param filter_length    length of each FIR filter in the filterbank relative to the cutoff freq
- * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
- * @param linear           If 1 then the used FIR filter will be linearly interpolated
-                           between the 2 closest, if 0 the closest will be used
- * @param cutoff           cutoff frequency, 1.0 corresponds to half the output sampling rate
- * @return allocated ReSampleContext, NULL if error occured
+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @code
+ * avcodec_register_all();
+ * av_dict_set(&opts, "b", "2.5M", 0);
+ * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
+ * if (!codec)
+ *     exit(1);
+ *
+ * context = avcodec_alloc_context3(codec);
+ *
+ * if (avcodec_open2(context, codec, opts) < 0)
+ *     exit(1);
+ * @endcode
+ *
+ * @param avctx The context to initialize.
+ * @param codec The codec to open this context for. If a non-NULL codec has been
+ *              previously passed to avcodec_alloc_context3() or
+ *              avcodec_get_context_defaults3() for this context, then this
+ *              parameter MUST be either NULL or equal to the previously passed
+ *              codec.
+ * @param options A dictionary filled with AVCodecContext and codec-private options.
+ *                On return this object will be filled with options that were not found.
+ *
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
+ *      av_dict_set(), av_opt_find().
  */
-ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
-                                        int output_rate, int input_rate,
-                                        enum SampleFormat sample_fmt_out,
-                                        enum SampleFormat sample_fmt_in,
-                                        int filter_length, int log2_phase_count,
-                                        int linear, double cutoff);
+int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
 
-int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
-void audio_resample_close(ReSampleContext *s);
+/**
+ * Close a given AVCodecContext and free all the data associated with it
+ * (but not the AVCodecContext itself).
+ *
+ * Calling this function on an AVCodecContext that hasn't been opened will free
+ * the codec-specific data allocated in avcodec_alloc_context3() /
+ * avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will
+ * do nothing.
+ */
+int avcodec_close(AVCodecContext *avctx);
 
+/**
+ * Free all allocated data in the given subtitle struct.
+ *
+ * @param sub AVSubtitle to free.
+ */
+void avsubtitle_free(AVSubtitle *sub);
 
 /**
- * Initializes an audio resampler.
- * Note, if either rate is not an integer then simply scale both rates up so they are.
- * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
- * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
- * @param linear If 1 then the used FIR filter will be linearly interpolated
-                 between the 2 closest, if 0 the closest will be used
- * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
+ * @}
  */
-struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
 
 /**
- * resamples.
- * @param src an array of unconsumed samples
- * @param consumed the number of samples of src which have been consumed are returned here
- * @param src_size the number of unconsumed samples available
- * @param dst_size the amount of space in samples available in dst
- * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context.
- * @return the number of samples written in dst or -1 if an error occurred
+ * @addtogroup lavc_packet
+ * @{
  */
-int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
 
+/**
+ * Default packet destructor.
+ */
+void av_destruct_packet(AVPacket *pkt);
 
 /**
- * Compensates samplerate/timestamp drift. The compensation is done by changing
- * the resampler parameters, so no audible clicks or similar distortions occur
- * @param compensation_distance distance in output samples over which the compensation should be performed
- * @param sample_delta number of output samples which should be output less
+ * Initialize optional fields of a packet with default values.
  *
- * example: av_resample_compensate(c, 10, 500)
- * here instead of 510 samples only 500 samples would be output
+ * Note, this does not touch the data and size members, which have to be
+ * initialized separately.
  *
- * note, due to rounding the actual compensation might be slightly different,
- * especially if the compensation_distance is large and the in_rate used during init is small
+ * @param pkt packet
  */
-void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
-void av_resample_close(struct AVResampleContext *c);
+void av_init_packet(AVPacket *pkt);
 
 /**
- * Allocate memory for a picture.  Call avpicture_free to free it.
+ * Allocate the payload of a packet and initialize its fields with
+ * default values.
  *
- * @param picture the picture to be filled in
- * @param pix_fmt the format of the picture
- * @param width the width of the picture
- * @param height the height of the picture
- * @return zero if successful, a negative value if not
+ * @param pkt packet
+ * @param size wanted payload size
+ * @return 0 if OK, AVERROR_xxx otherwise
  */
-int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height);
+int av_new_packet(AVPacket *pkt, int size);
 
 /**
- * Free a picture previously allocated by avpicture_alloc().
+ * Reduce packet size, correctly zeroing padding
  *
- * @param picture the AVPicture to be freed
+ * @param pkt packet
+ * @param size new size
  */
-void avpicture_free(AVPicture *picture);
+void av_shrink_packet(AVPacket *pkt, int size);
 
 /**
- * Fill in the AVPicture fields.
- * The fields of the given AVPicture are filled in by using the 'ptr' address
- * which points to the image data buffer. Depending on the specified picture
- * format, one or multiple image data pointers and line sizes will be set.
- * If a planar format is specified, several pointers will be set pointing to
- * the different picture planes and the line sizes of the different planes
- * will be stored in the lines_sizes array.
- * Call with ptr == NULL to get the required size for the ptr buffer.
+ * Increase packet size, correctly zeroing padding
  *
- * @param picture AVPicture whose fields are to be filled in
- * @param ptr Buffer which will contain or contains the actual image data
- * @param pix_fmt The format in which the picture data is stored.
- * @param width the width of the image in pixels
- * @param height the height of the image in pixels
- * @return size of the image data in bytes
+ * @param pkt packet
+ * @param grow_by number of bytes by which to increase the size of the packet
  */
-int avpicture_fill(AVPicture *picture, uint8_t *ptr,
-                   int pix_fmt, int width, int height);
-int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
-                     unsigned char *dest, int dest_size);
+int av_grow_packet(AVPacket *pkt, int grow_by);
 
 /**
- * Calculate the size in bytes that a picture of the given width and height
- * would occupy if stored in the given picture format.
- * Note that this returns the size of a compact representation as generated
- * by avpicture_layout, which can be smaller than the size required for e.g.
- * avpicture_fill.
- *
- * @param pix_fmt the given picture format
- * @param width the width of the image
- * @param height the height of the image
- * @return Image data size in bytes or -1 on error (e.g. too large dimensions).
- */
-int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height);
-void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift);
-const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt);
-void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
+ * @warning This is a hack - the packet memory allocation stuff is broken. The
+ * packet is allocated if it was not really allocated.
+ */
+int av_dup_packet(AVPacket *pkt);
 
 /**
- * Returns the pixel format corresponding to the name \p name.
+ * Copy packet, including contents
  *
- * If there is no pixel format with name \p name, then looks for a
- * pixel format with the name corresponding to the native endian
- * format of \p name.
- * For example in a little-endian system, first looks for "gray16",
- * then for "gray16le".
+ * @return 0 on success, negative AVERROR on fail
+ */
+int av_copy_packet(AVPacket *dst, AVPacket *src);
+
+/**
+ * Free a packet.
  *
- * Finally if no pixel format has been found, returns \c PIX_FMT_NONE.
+ * @param pkt packet to free
  */
-enum PixelFormat avcodec_get_pix_fmt(const char* name);
-unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p);
+void av_free_packet(AVPacket *pkt);
 
-#define FF_LOSS_RESOLUTION  0x0001 /**< loss due to resolution change */
-#define FF_LOSS_DEPTH       0x0002 /**< loss due to color depth change */
-#define FF_LOSS_COLORSPACE  0x0004 /**< loss due to color space conversion */
-#define FF_LOSS_ALPHA       0x0008 /**< loss of alpha bits */
-#define FF_LOSS_COLORQUANT  0x0010 /**< loss due to color quantization */
-#define FF_LOSS_CHROMA      0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */
+/**
+ * Allocate new information of a packet.
+ *
+ * @param pkt packet
+ * @param type side information type
+ * @param size side information size
+ * @return pointer to fresh allocated data or NULL otherwise
+ */
+uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+                                 int size);
 
 /**
- * Computes what kind of losses will occur when converting from one specific
- * pixel format to another.
- * When converting from one pixel format to another, information loss may occur.
- * For example, when converting from RGB24 to GRAY, the color information will
- * be lost. Similarly, other losses occur when converting from some formats to
- * other formats. These losses can involve loss of chroma, but also loss of
- * resolution, loss of color depth, loss due to the color space conversion, loss
- * of the alpha bits or loss due to color quantization.
- * avcodec_get_fix_fmt_loss() informs you about the various types of losses
- * which will occur when converting from one pixel format to another.
+ * Shrink the already allocated side data buffer
  *
- * @param[in] dst_pix_fmt destination pixel format
- * @param[in] src_pix_fmt source pixel format
- * @param[in] has_alpha Whether the source pixel format alpha channel is used.
- * @return Combination of flags informing you what kind of losses will occur.
+ * @param pkt packet
+ * @param type side information type
+ * @param size new side information size
+ * @return 0 on success, < 0 on failure
  */
-int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
-                             int has_alpha);
+int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+                               int size);
 
 /**
- * Finds the best pixel format to convert to given a certain source pixel
- * format.  When converting from one pixel format to another, information loss
- * may occur.  For example, when converting from RGB24 to GRAY, the color
- * information will be lost. Similarly, other losses occur when converting from
- * some formats to other formats. avcodec_find_best_pix_fmt() searches which of
- * the given pixel formats should be used to suffer the least amount of loss.
- * The pixel formats from which it chooses one, are determined by the
- * \p pix_fmt_mask parameter.
+ * Get side information from packet.
  *
- * @code
- * src_pix_fmt = PIX_FMT_YUV420P;
- * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24);
- * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss);
- * @endcode
+ * @param pkt packet
+ * @param type desired side information type
+ * @param size pointer for side information size to store (optional)
+ * @return pointer to data if present or NULL otherwise
+ */
+uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+                                 int *size);
+
+int av_packet_merge_side_data(AVPacket *pkt);
+
+int av_packet_split_side_data(AVPacket *pkt);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup lavc_decoding
+ * @{
+ */
+
+/**
+ * Find a registered decoder with a matching codec ID.
  *
- * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from
- * @param[in] src_pix_fmt source pixel format
- * @param[in] has_alpha Whether the source pixel format alpha channel is used.
- * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
- * @return The best pixel format to convert to or -1 if none was found.
+ * @param id AVCodecID of the requested decoder
+ * @return A decoder if one was found, NULL otherwise.
  */
-enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
-                              int has_alpha, int *loss_ptr);
+AVCodec *avcodec_find_decoder(enum AVCodecID id);
+
+/**
+ * Find a registered decoder with the specified name.
+ *
+ * @param name name of the requested decoder
+ * @return A decoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_decoder_by_name(const char *name);
+
+int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
+void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+
+/**
+ * Return the amount of padding in pixels which the get_buffer callback must
+ * provide around the edge of the image for codecs which do not have the
+ * CODEC_FLAG_EMU_EDGE flag.
+ *
+ * @return Required padding in pixels.
+ */
+unsigned avcodec_get_edge_width(void);
+
+/**
+ * Modify width and height values so that they will result in a memory
+ * buffer that is acceptable for the codec if you do not use any horizontal
+ * padding.
+ *
+ * May only be used if a codec with CODEC_CAP_DR1 has been opened.
+ * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased
+ * according to avcodec_get_edge_width() before.
+ */
+void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
+
+/**
+ * Modify width and height values so that they will result in a memory
+ * buffer that is acceptable for the codec if you also ensure that all
+ * line sizes are a multiple of the respective linesize_align[i].
+ *
+ * May only be used if a codec with CODEC_CAP_DR1 has been opened.
+ * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased
+ * according to avcodec_get_edge_width() before.
+ */
+void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
+                               int linesize_align[AV_NUM_DATA_POINTERS]);
+
+#if FF_API_OLD_DECODE_AUDIO
+/**
+ * Wrapper function which calls avcodec_decode_audio4.
+ *
+ * @deprecated Use avcodec_decode_audio4 instead.
+ *
+ * Decode the audio frame of size avpkt->size from avpkt->data into samples.
+ * Some decoders may support multiple frames in a single AVPacket, such
+ * decoders would then just decode the first frame. In this case,
+ * avcodec_decode_audio3 has to be called again with an AVPacket that contains
+ * the remaining data in order to decode the second frame etc.
+ * If no frame
+ * could be outputted, frame_size_ptr is zero. Otherwise, it is the
+ * decompressed frame size in bytes.
+ *
+ * @warning You must set frame_size_ptr to the allocated size of the
+ * output buffer before calling avcodec_decode_audio3().
+ *
+ * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
+ * the actual read bytes because some optimized bitstream readers read 32 or 64
+ * bits at once and could read over the end.
+ *
+ * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that
+ * no overreading happens for damaged MPEG streams.
+ *
+ * @warning You must not provide a custom get_buffer() when using
+ * avcodec_decode_audio3().  Doing so will override it with
+ * avcodec_default_get_buffer.  Use avcodec_decode_audio4() instead,
+ * which does allow the application to provide a custom get_buffer().
+ *
+ * @note You might have to align the input buffer avpkt->data and output buffer
+ * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
+ * necessary at all, on others it won't work at all if not aligned and on others
+ * it will work but it will have an impact on performance.
+ *
+ * In practice, avpkt->data should have 4 byte alignment at minimum and
+ * samples should be 16 byte aligned unless the CPU doesn't need it
+ * (AltiVec and SSE do).
+ *
+ * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
+ * between input and output, these need to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to return the remaining frames.
+ *
+ * @param avctx the codec context
+ * @param[out] samples the output buffer, sample type in avctx->sample_fmt
+ *                     If the sample format is planar, each channel plane will
+ *                     be the same size, with no padding between channels.
+ * @param[in,out] frame_size_ptr the output buffer size in bytes
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ *            You can create such packet with av_init_packet() and by then setting
+ *            data and size, some decoders might in addition need other fields.
+ *            All decoders are designed to use the least fields possible though.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame data was decompressed (used) from the input AVPacket.
+ */
+attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
+                         int *frame_size_ptr,
+                         AVPacket *avpkt);
+#endif
+
+/**
+ * Decode the audio frame of size avpkt->size from avpkt->data into frame.
+ *
+ * Some decoders may support multiple frames in a single AVPacket. Such
+ * decoders would then just decode the first frame. In this case,
+ * avcodec_decode_audio4 has to be called again with an AVPacket containing
+ * the remaining data in order to decode the second frame, etc...
+ * Even if no frames are returned, the packet needs to be fed to the decoder
+ * with remaining data until it is completely consumed or an error occurs.
+ *
+ * @warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE
+ *          larger than the actual read bytes because some optimized bitstream
+ *          readers read 32 or 64 bits at once and could read over the end.
+ *
+ * @note You might have to align the input buffer. The alignment requirements
+ *       depend on the CPU and the decoder.
+ *
+ * @param      avctx the codec context
+ * @param[out] frame The AVFrame in which to store decoded audio samples.
+ *                   Decoders request a buffer of a particular size by setting
+ *                   AVFrame.nb_samples prior to calling get_buffer(). The
+ *                   decoder may, however, only utilize part of the buffer by
+ *                   setting AVFrame.nb_samples to a smaller value in the
+ *                   output frame.
+ * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is
+ *                           non-zero.
+ * @param[in]  avpkt The input AVPacket containing the input buffer.
+ *                   At least avpkt->data and avpkt->size should be set. Some
+ *                   decoders might also require additional fields to be set.
+ * @return A negative error code is returned if an error occurred during
+ *         decoding, otherwise the number of bytes consumed from the input
+ *         AVPacket is returned.
+ */
+int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
+                          int *got_frame_ptr, const AVPacket *avpkt);
+
+/**
+ * Decode the video frame of size avpkt->size from avpkt->data into picture.
+ * Some decoders may support multiple frames in a single AVPacket, such
+ * decoders would then just decode the first frame.
+ *
+ * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
+ * the actual read bytes because some optimized bitstream readers read 32 or 64
+ * bits at once and could read over the end.
+ *
+ * @warning The end of the input buffer buf should be set to 0 to ensure that
+ * no overreading happens for damaged MPEG streams.
+ *
+ * @note You might have to align the input buffer avpkt->data.
+ * The alignment requirements depend on the CPU: on some CPUs it isn't
+ * necessary at all, on others it won't work at all if not aligned and on others
+ * it will work but it will have an impact on performance.
+ *
+ * In practice, avpkt->data should have 4 byte alignment at minimum.
+ *
+ * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
+ * between input and output, these need to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to return the remaining frames.
+ *
+ * @param avctx the codec context
+ * @param[out] picture The AVFrame in which the decoded video frame will be stored.
+ *             Use avcodec_alloc_frame to get an AVFrame, the codec will
+ *             allocate memory for the actual bitmap.
+ *             with default get/release_buffer(), the decoder frees/reuses the bitmap as it sees fit.
+ *             with overridden get/release_buffer() (needs CODEC_CAP_DR1) the user decides into what buffer the decoder
+ *                   decodes and the decoder tells the user once it does not need the data anymore,
+ *                   the user app can at this point free/reuse/keep the memory as it sees fit.
+ *
+ * @param[in] avpkt The input AVpacket containing the input buffer.
+ *            You can create such packet with av_init_packet() and by then setting
+ *            data and size, some decoders might in addition need other fields like
+ *            flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least
+ *            fields possible.
+ * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame could be decompressed.
+ */
+int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
+                         int *got_picture_ptr,
+                         const AVPacket *avpkt);
+
+/**
+ * Decode a subtitle message.
+ * Return a negative value on error, otherwise return the number of bytes used.
+ * If no subtitle could be decompressed, got_sub_ptr is zero.
+ * Otherwise, the subtitle is stored in *sub.
+ * Note that CODEC_CAP_DR1 is not available for subtitle codecs. This is for
+ * simplicity, because the performance difference is expect to be negligible
+ * and reusing a get_buffer written for video codecs would probably perform badly
+ * due to a potentially very different allocation pattern.
+ *
+ * @param avctx the codec context
+ * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored, must be
+                   freed with avsubtitle_free if *got_sub_ptr is set.
+ * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero.
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ */
+int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
+                            int *got_sub_ptr,
+                            AVPacket *avpkt);
+
+/**
+ * @defgroup lavc_parsing Frame parsing
+ * @{
+ */
+
+typedef struct AVCodecParserContext {
+    void *priv_data;
+    struct AVCodecParser *parser;
+    int64_t frame_offset; /* offset of the current frame */
+    int64_t cur_offset; /* current offset
+                           (incremented by each av_parser_parse()) */
+    int64_t next_frame_offset; /* offset of the next frame */
+    /* video info */
+    int pict_type; /* XXX: Put it back in AVCodecContext. */
+    /**
+     * This field is used for proper frame duration computation in lavf.
+     * It signals, how much longer the frame duration of the current frame
+     * is compared to normal frame duration.
+     *
+     * frame_duration = (1 + repeat_pict) * time_base
+     *
+     * It is used by codecs like H.264 to display telecined material.
+     */
+    int repeat_pict; /* XXX: Put it back in AVCodecContext. */
+    int64_t pts;     /* pts of the current frame */
+    int64_t dts;     /* dts of the current frame */
+
+    /* private data */
+    int64_t last_pts;
+    int64_t last_dts;
+    int fetch_timestamp;
+
+#define AV_PARSER_PTS_NB 4
+    int cur_frame_start_index;
+    int64_t cur_frame_offset[AV_PARSER_PTS_NB];
+    int64_t cur_frame_pts[AV_PARSER_PTS_NB];
+    int64_t cur_frame_dts[AV_PARSER_PTS_NB];
+
+    int flags;
+#define PARSER_FLAG_COMPLETE_FRAMES           0x0001
+#define PARSER_FLAG_ONCE                      0x0002
+/// Set if the parser has a valid file offset
+#define PARSER_FLAG_FETCHED_OFFSET            0x0004
+#define PARSER_FLAG_USE_CODEC_TS              0x1000
+
+    int64_t offset;      ///< byte offset from starting packet start
+    int64_t cur_frame_end[AV_PARSER_PTS_NB];
+
+    /**
+     * Set by parser to 1 for key frames and 0 for non-key frames.
+     * It is initialized to -1, so if the parser doesn't set this flag,
+     * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames
+     * will be used.
+     */
+    int key_frame;
+
+    /**
+     * Time difference in stream time base units from the pts of this
+     * packet to the point at which the output from the decoder has converged
+     * independent from the availability of previous frames. That is, the
+     * frames are virtually identical no matter if decoding started from
+     * the very first frame or from this keyframe.
+     * Is AV_NOPTS_VALUE if unknown.
+     * This field is not the display duration of the current frame.
+     * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
+     * set.
+     *
+     * The purpose of this field is to allow seeking in streams that have no
+     * keyframes in the conventional sense. It corresponds to the
+     * recovery point SEI in H.264 and match_time_delta in NUT. It is also
+     * essential for some types of subtitle streams to ensure that all
+     * subtitles are correctly displayed after seeking.
+     */
+    int64_t convergence_duration;
+
+    // Timestamp generation support:
+    /**
+     * Synchronization point for start of timestamp generation.
+     *
+     * Set to >0 for sync point, 0 for no sync point and <0 for undefined
+     * (default).
+     *
+     * For example, this corresponds to presence of H.264 buffering period
+     * SEI message.
+     */
+    int dts_sync_point;
+
+    /**
+     * Offset of the current timestamp against last timestamp sync point in
+     * units of AVCodecContext.time_base.
+     *
+     * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
+     * contain a valid timestamp offset.
+     *
+     * Note that the timestamp of sync point has usually a nonzero
+     * dts_ref_dts_delta, which refers to the previous sync point. Offset of
+     * the next frame after timestamp sync point will be usually 1.
+     *
+     * For example, this corresponds to H.264 cpb_removal_delay.
+     */
+    int dts_ref_dts_delta;
+
+    /**
+     * Presentation delay of current frame in units of AVCodecContext.time_base.
+     *
+     * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
+     * contain valid non-negative timestamp delta (presentation time of a frame
+     * must not lie in the past).
+     *
+     * This delay represents the difference between decoding and presentation
+     * time of the frame.
+     *
+     * For example, this corresponds to H.264 dpb_output_delay.
+     */
+    int pts_dts_delta;
+
+    /**
+     * Position of the packet in file.
+     *
+     * Analogous to cur_frame_pts/dts
+     */
+    int64_t cur_frame_pos[AV_PARSER_PTS_NB];
+
+    /**
+     * Byte position of currently parsed frame in stream.
+     */
+    int64_t pos;
+
+    /**
+     * Previous frame byte position.
+     */
+    int64_t last_pos;
+
+    /**
+     * Duration of the current frame.
+     * For audio, this is in units of 1 / AVCodecContext.sample_rate.
+     * For all other types, this is in units of AVCodecContext.time_base.
+     */
+    int duration;
+} AVCodecParserContext;
+
+typedef struct AVCodecParser {
+    int codec_ids[5]; /* several codec IDs are permitted */
+    int priv_data_size;
+    int (*parser_init)(AVCodecParserContext *s);
+    int (*parser_parse)(AVCodecParserContext *s,
+                        AVCodecContext *avctx,
+                        const uint8_t **poutbuf, int *poutbuf_size,
+                        const uint8_t *buf, int buf_size);
+    void (*parser_close)(AVCodecParserContext *s);
+    int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
+    struct AVCodecParser *next;
+} AVCodecParser;
+
+AVCodecParser *av_parser_next(AVCodecParser *c);
+
+void av_register_codec_parser(AVCodecParser *parser);
+AVCodecParserContext *av_parser_init(int codec_id);
+
+/**
+ * Parse a packet.
+ *
+ * @param s             parser context.
+ * @param avctx         codec context.
+ * @param poutbuf       set to pointer to parsed buffer or NULL if not yet finished.
+ * @param poutbuf_size  set to size of parsed buffer or zero if not yet finished.
+ * @param buf           input buffer.
+ * @param buf_size      input length, to signal EOF, this should be 0 (so that the last frame can be output).
+ * @param pts           input presentation timestamp.
+ * @param dts           input decoding timestamp.
+ * @param pos           input byte position in stream.
+ * @return the number of bytes of the input bitstream used.
+ *
+ * Example:
+ * @code
+ *   while(in_len){
+ *       len = av_parser_parse2(myparser, AVCodecContext, &data, &size,
+ *                                        in_data, in_len,
+ *                                        pts, dts, pos);
+ *       in_data += len;
+ *       in_len  -= len;
+ *
+ *       if(size)
+ *          decode_frame(data, size);
+ *   }
+ * @endcode
+ */
+int av_parser_parse2(AVCodecParserContext *s,
+                     AVCodecContext *avctx,
+                     uint8_t **poutbuf, int *poutbuf_size,
+                     const uint8_t *buf, int buf_size,
+                     int64_t pts, int64_t dts,
+                     int64_t pos);
+
+int av_parser_change(AVCodecParserContext *s,
+                     AVCodecContext *avctx,
+                     uint8_t **poutbuf, int *poutbuf_size,
+                     const uint8_t *buf, int buf_size, int keyframe);
+void av_parser_close(AVCodecParserContext *s);
+
+/**
+ * @}
+ * @}
+ */
+
+/**
+ * @addtogroup lavc_encoding
+ * @{
+ */
+
+/**
+ * Find a registered encoder with a matching codec ID.
+ *
+ * @param id AVCodecID of the requested encoder
+ * @return An encoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_encoder(enum AVCodecID id);
+
+/**
+ * Find a registered encoder with the specified name.
+ *
+ * @param name name of the requested encoder
+ * @return An encoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_encoder_by_name(const char *name);
+
+#if FF_API_OLD_ENCODE_AUDIO
+/**
+ * Encode an audio frame from samples into buf.
+ *
+ * @deprecated Use avcodec_encode_audio2 instead.
+ *
+ * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large.
+ * However, for codecs with avctx->frame_size equal to 0 (e.g. PCM) the user
+ * will know how much space is needed because it depends on the value passed
+ * in buf_size as described below. In that case a lower value can be used.
+ *
+ * @param avctx the codec context
+ * @param[out] buf the output buffer
+ * @param[in] buf_size the output buffer size
+ * @param[in] samples the input buffer containing the samples
+ * The number of samples read from this buffer is frame_size*channels,
+ * both of which are defined in avctx.
+ * For codecs which have avctx->frame_size equal to 0 (e.g. PCM) the number of
+ * samples read from samples is equal to:
+ * buf_size * 8 / (avctx->channels * av_get_bits_per_sample(avctx->codec_id))
+ * This also implies that av_get_bits_per_sample() must not return 0 for these
+ * codecs.
+ * @return On error a negative value is returned, on success zero or the number
+ * of bytes used to encode the data read from the input buffer.
+ */
+int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
+                                              uint8_t *buf, int buf_size,
+                                              const short *samples);
+#endif
+
+/**
+ * Encode a frame of audio.
+ *
+ * Takes input samples from frame and writes the next output packet, if
+ * available, to avpkt. The output packet does not necessarily contain data for
+ * the most recent frame, as encoders can delay, split, and combine input frames
+ * internally as needed.
+ *
+ * @param avctx     codec context
+ * @param avpkt     output AVPacket.
+ *                  The user can supply an output buffer by setting
+ *                  avpkt->data and avpkt->size prior to calling the
+ *                  function, but if the size of the user-provided data is not
+ *                  large enough, encoding will fail. If avpkt->data and
+ *                  avpkt->size are set, avpkt->destruct must also be set. All
+ *                  other AVPacket fields will be reset by the encoder using
+ *                  av_init_packet(). If avpkt->data is NULL, the encoder will
+ *                  allocate it. The encoder will set avpkt->size to the size
+ *                  of the output packet.
+ *
+ *                  If this function fails or produces no output, avpkt will be
+ *                  freed using av_free_packet() (i.e. avpkt->destruct will be
+ *                  called to free the user supplied buffer).
+ * @param[in] frame AVFrame containing the raw audio data to be encoded.
+ *                  May be NULL when flushing an encoder that has the
+ *                  CODEC_CAP_DELAY capability set.
+ *                  If CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
+ *                  can have any number of samples.
+ *                  If it is not set, frame->nb_samples must be equal to
+ *                  avctx->frame_size for all frames except the last.
+ *                  The final frame may be smaller than avctx->frame_size.
+ * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
+ *                            output packet is non-empty, and to 0 if it is
+ *                            empty. If the function returns an error, the
+ *                            packet can be assumed to be invalid, and the
+ *                            value of got_packet_ptr is undefined and should
+ *                            not be used.
+ * @return          0 on success, negative error code on failure
+ */
+int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt,
+                          const AVFrame *frame, int *got_packet_ptr);
+
+#if FF_API_OLD_ENCODE_VIDEO
+/**
+ * @deprecated use avcodec_encode_video2() instead.
+ *
+ * Encode a video frame from pict into buf.
+ * The input picture should be
+ * stored using a specific format, namely avctx.pix_fmt.
+ *
+ * @param avctx the codec context
+ * @param[out] buf the output buffer for the bitstream of encoded frame
+ * @param[in] buf_size the size of the output buffer in bytes
+ * @param[in] pict the input picture to encode
+ * @return On error a negative value is returned, on success zero or the number
+ * of bytes used from the output buffer.
+ */
+attribute_deprecated
+int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+                         const AVFrame *pict);
+#endif
+
+/**
+ * Encode a frame of video.
+ *
+ * Takes input raw video data from frame and writes the next output packet, if
+ * available, to avpkt. The output packet does not necessarily contain data for
+ * the most recent frame, as encoders can delay and reorder input frames
+ * internally as needed.
+ *
+ * @param avctx     codec context
+ * @param avpkt     output AVPacket.
+ *                  The user can supply an output buffer by setting
+ *                  avpkt->data and avpkt->size prior to calling the
+ *                  function, but if the size of the user-provided data is not
+ *                  large enough, encoding will fail. All other AVPacket fields
+ *                  will be reset by the encoder using av_init_packet(). If
+ *                  avpkt->data is NULL, the encoder will allocate it.
+ *                  The encoder will set avpkt->size to the size of the
+ *                  output packet. The returned data (if any) belongs to the
+ *                  caller, he is responsible for freeing it.
+ *
+ *                  If this function fails or produces no output, avpkt will be
+ *                  freed using av_free_packet() (i.e. avpkt->destruct will be
+ *                  called to free the user supplied buffer).
+ * @param[in] frame AVFrame containing the raw video data to be encoded.
+ *                  May be NULL when flushing an encoder that has the
+ *                  CODEC_CAP_DELAY capability set.
+ * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
+ *                            output packet is non-empty, and to 0 if it is
+ *                            empty. If the function returns an error, the
+ *                            packet can be assumed to be invalid, and the
+ *                            value of got_packet_ptr is undefined and should
+ *                            not be used.
+ * @return          0 on success, negative error code on failure
+ */
+int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
+                          const AVFrame *frame, int *got_packet_ptr);
+
+int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+                            const AVSubtitle *sub);
+
+
+/**
+ * @}
+ */
+
+#if FF_API_AVCODEC_RESAMPLE
+/**
+ * @defgroup lavc_resample Audio resampling
+ * @ingroup libavc
+ * @deprecated use libswresample instead
+ *
+ * @{
+ */
+struct ReSampleContext;
+struct AVResampleContext;
+
+typedef struct ReSampleContext ReSampleContext;
+
+/**
+ *  Initialize audio resampling context.
+ *
+ * @param output_channels  number of output channels
+ * @param input_channels   number of input channels
+ * @param output_rate      output sample rate
+ * @param input_rate       input sample rate
+ * @param sample_fmt_out   requested output sample format
+ * @param sample_fmt_in    input sample format
+ * @param filter_length    length of each FIR filter in the filterbank relative to the cutoff frequency
+ * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
+ * @param linear           if 1 then the used FIR filter will be linearly interpolated
+                           between the 2 closest, if 0 the closest will be used
+ * @param cutoff           cutoff frequency, 1.0 corresponds to half the output sampling rate
+ * @return allocated ReSampleContext, NULL if error occurred
+ */
+attribute_deprecated
+ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
+                                        int output_rate, int input_rate,
+                                        enum AVSampleFormat sample_fmt_out,
+                                        enum AVSampleFormat sample_fmt_in,
+                                        int filter_length, int log2_phase_count,
+                                        int linear, double cutoff);
 
+attribute_deprecated
+int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
 
 /**
- * Print in buf the string corresponding to the pixel format with
- * number pix_fmt, or an header if pix_fmt is negative.
+ * Free resample context.
  *
- * @param[in] buf the buffer where to write the string
- * @param[in] buf_size the size of buf
- * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or
- * a negative value to print the corresponding header.
- * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1.
+ * @param s a non-NULL pointer to a resample context previously
+ *          created with av_audio_resample_init()
  */
-void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt);
+attribute_deprecated
+void audio_resample_close(ReSampleContext *s);
 
-#define FF_ALPHA_TRANSP       0x0001 /* image has some totally transparent pixels */
-#define FF_ALPHA_SEMI_TRANSP  0x0002 /* image has some transparent pixels */
 
 /**
- * Tell if an image really has transparent alpha values.
- * @return ored mask of FF_ALPHA_xxx constants
+ * Initialize an audio resampler.
+ * Note, if either rate is not an integer then simply scale both rates up so they are.
+ * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
+ * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
+ * @param linear If 1 then the used FIR filter will be linearly interpolated
+                 between the 2 closest, if 0 the closest will be used
+ * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
  */
-int img_get_alpha_info(const AVPicture *src,
-                       enum PixelFormat pix_fmt, int width, int height);
-
-/* deinterlace a picture */
-/* deinterlace - if not supported return -1 */
-int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
-                          enum PixelFormat pix_fmt, int width, int height);
-
-/* external high level API */
+attribute_deprecated
+struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
 
 /**
- * If c is NULL, returns the first registered codec,
- * if c is non-NULL, returns the next registered codec after c,
- * or NULL if c is the last one.
+ * Resample an array of samples using a previously configured context.
+ * @param src an array of unconsumed samples
+ * @param consumed the number of samples of src which have been consumed are returned here
+ * @param src_size the number of unconsumed samples available
+ * @param dst_size the amount of space in samples available in dst
+ * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context.
+ * @return the number of samples written in dst or -1 if an error occurred
  */
-AVCodec *av_codec_next(AVCodec *c);
+attribute_deprecated
+int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
 
-/**
- * Returns the LIBAVCODEC_VERSION_INT constant.
- */
-unsigned avcodec_version(void);
 
 /**
- * Initializes libavcodec.
+ * Compensate samplerate/timestamp drift. The compensation is done by changing
+ * the resampler parameters, so no audible clicks or similar distortions occur
+ * @param compensation_distance distance in output samples over which the compensation should be performed
+ * @param sample_delta number of output samples which should be output less
+ *
+ * example: av_resample_compensate(c, 10, 500)
+ * here instead of 510 samples only 500 samples would be output
  *
- * @warning This function \e must be called before any other libavcodec
- * function.
+ * note, due to rounding the actual compensation might be slightly different,
+ * especially if the compensation_distance is large and the in_rate used during init is small
  */
-void avcodec_init(void);
+attribute_deprecated
+void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
+attribute_deprecated
+void av_resample_close(struct AVResampleContext *c);
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
 /**
- * @deprecated Deprecated in favor of avcodec_register().
+ * @}
  */
-attribute_deprecated void register_avcodec(AVCodec *codec);
 #endif
 
 /**
- * Register the codec \p codec and initialize libavcodec.
- *
- * @see avcodec_init()
+ * @addtogroup lavc_picture
+ * @{
  */
-void avcodec_register(AVCodec *codec);
 
 /**
- * Finds a registered encoder with a matching codec ID.
+ * Allocate memory for a picture.  Call avpicture_free() to free it.
  *
- * @param id CodecID of the requested encoder
- * @return An encoder if one was found, NULL otherwise.
+ * @see avpicture_fill()
+ *
+ * @param picture the picture to be filled in
+ * @param pix_fmt the format of the picture
+ * @param width the width of the picture
+ * @param height the height of the picture
+ * @return zero if successful, a negative value if not
  */
-AVCodec *avcodec_find_encoder(enum CodecID id);
+int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
- * Finds a registered encoder with the specified name.
+ * Free a picture previously allocated by avpicture_alloc().
+ * The data buffer used by the AVPicture is freed, but the AVPicture structure
+ * itself is not.
  *
- * @param name name of the requested encoder
- * @return An encoder if one was found, NULL otherwise.
+ * @param picture the AVPicture to be freed
  */
-AVCodec *avcodec_find_encoder_by_name(const char *name);
+void avpicture_free(AVPicture *picture);
 
 /**
- * Finds a registered decoder with a matching codec ID.
+ * Fill in the AVPicture fields, always assume a linesize alignment of
+ * 1.
  *
- * @param id CodecID of the requested decoder
- * @return A decoder if one was found, NULL otherwise.
+ * @see av_image_fill_arrays()
  */
-AVCodec *avcodec_find_decoder(enum CodecID id);
+int avpicture_fill(AVPicture *picture, uint8_t *ptr,
+                   enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
- * Finds a registered decoder with the specified name.
+ * Copy pixel data from an AVPicture into a buffer, always assume a
+ * linesize alignment of 1.
  *
- * @param name name of the requested decoder
- * @return A decoder if one was found, NULL otherwise.
+ * @see av_image_copy_to_buffer()
  */
-AVCodec *avcodec_find_decoder_by_name(const char *name);
-void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
+int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
+                     int width, int height,
+                     unsigned char *dest, int dest_size);
 
 /**
- * Sets the fields of the given AVCodecContext to default values.
+ * Calculate the size in bytes that a picture of the given width and height
+ * would occupy if stored in the given picture format.
+ * Always assume a linesize alignment of 1.
  *
- * @param s The AVCodecContext of which the fields should be set to default values.
+ * @see av_image_get_buffer_size().
  */
-void avcodec_get_context_defaults(AVCodecContext *s);
+int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
 
-/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
- *  we WILL change its arguments and name a few times! */
-void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType);
+/**
+ *  deinterlace - if not supported return -1
+ */
+int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
+                          enum AVPixelFormat pix_fmt, int width, int height);
+/**
+ * Copy image src to dst. Wraps av_image_copy().
+ */
+void av_picture_copy(AVPicture *dst, const AVPicture *src,
+                     enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
- * Allocates an AVCodecContext and sets its fields to default values.  The
- * resulting struct can be deallocated by simply calling av_free().
- *
- * @return An AVCodecContext filled with default values or NULL on failure.
- * @see avcodec_get_context_defaults
+ * Crop image top and left side.
  */
-AVCodecContext *avcodec_alloc_context(void);
+int av_picture_crop(AVPicture *dst, const AVPicture *src,
+                    enum AVPixelFormat pix_fmt, int top_band, int left_band);
 
-/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
- *  we WILL change its arguments and name a few times! */
-AVCodecContext *avcodec_alloc_context2(enum CodecType);
+/**
+ * Pad image.
+ */
+int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt,
+            int padtop, int padbottom, int padleft, int padright, int *color);
 
 /**
- * Sets the fields of the given AVFrame to default values.
- *
- * @param pic The AVFrame of which the fields should be set to default values.
+ * @}
  */
-void avcodec_get_frame_defaults(AVFrame *pic);
 
 /**
- * Allocates an AVFrame and sets its fields to default values.  The resulting
- * struct can be deallocated by simply calling av_free().
+ * @defgroup lavc_misc Utility functions
+ * @ingroup libavc
  *
- * @return An AVFrame filled with default values or NULL on failure.
- * @see avcodec_get_frame_defaults
+ * Miscellaneous utility functions related to both encoding and decoding
+ * (or neither).
+ * @{
  */
-AVFrame *avcodec_alloc_frame(void);
-
-int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
-void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
-int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
-void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
 
 /**
- * Checks if the given dimension of a picture is valid, meaning that all
- * bytes of the picture can be addressed with a signed int.
+ * @defgroup lavc_misc_pixfmt Pixel formats
  *
- * @param[in] w Width of the picture.
- * @param[in] h Height of the picture.
- * @return Zero if valid, a negative value if invalid.
+ * Functions for working with pixel formats.
+ * @{
  */
-int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h);
-enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt);
 
-int avcodec_thread_init(AVCodecContext *s, int thread_count);
-void avcodec_thread_free(AVCodecContext *s);
-int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
-int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
-//FIXME func typedef
+void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift);
 
 /**
- * Initializes the AVCodecContext to use the given AVCodec. Prior to using this
- * function the context has to be allocated.
- *
- * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
- * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
- * retrieving a codec.
- *
- * @warning This function is not thread safe!
- *
- * @code
- * avcodec_register_all();
- * codec = avcodec_find_decoder(CODEC_ID_H264);
- * if (!codec)
- *     exit(1);
- *
- * context = avcodec_alloc_context();
- *
- * if (avcodec_open(context, codec) < 0)
- *     exit(1);
- * @endcode
- *
- * @param avctx The context which will be set up to use the given codec.
- * @param codec The codec to use within the context.
- * @return zero on success, a negative value on error
- * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder
+ * Return a value representing the fourCC code associated to the
+ * pixel format pix_fmt, or 0 if no associated fourCC code can be
+ * found.
  */
-int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
+unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt);
+
+#define FF_LOSS_RESOLUTION  0x0001 /**< loss due to resolution change */
+#define FF_LOSS_DEPTH       0x0002 /**< loss due to color depth change */
+#define FF_LOSS_COLORSPACE  0x0004 /**< loss due to color space conversion */
+#define FF_LOSS_ALPHA       0x0008 /**< loss of alpha bits */
+#define FF_LOSS_COLORQUANT  0x0010 /**< loss due to color quantization */
+#define FF_LOSS_CHROMA      0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
 /**
- * Decodes an audio frame from \p buf into \p samples.
- * Wrapper function which calls avcodec_decode_audio3.
+ * Compute what kind of losses will occur when converting from one specific
+ * pixel format to another.
+ * When converting from one pixel format to another, information loss may occur.
+ * For example, when converting from RGB24 to GRAY, the color information will
+ * be lost. Similarly, other losses occur when converting from some formats to
+ * other formats. These losses can involve loss of chroma, but also loss of
+ * resolution, loss of color depth, loss due to the color space conversion, loss
+ * of the alpha bits or loss due to color quantization.
+ * avcodec_get_fix_fmt_loss() informs you about the various types of losses
+ * which will occur when converting from one pixel format to another.
  *
- * @deprecated Use avcodec_decode_audio3 instead.
- * @param avctx the codec context
- * @param[out] samples the output buffer
- * @param[in,out] frame_size_ptr the output buffer size in bytes
- * @param[in] buf the input buffer
- * @param[in] buf_size the input buffer size in bytes
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame could be decompressed.
+ * @param[in] dst_pix_fmt destination pixel format
+ * @param[in] src_pix_fmt source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @return Combination of flags informing you what kind of losses will occur
+ * (maximum loss for an invalid dst_pix_fmt).
  */
-attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
-                         int *frame_size_ptr,
-                         const uint8_t *buf, int buf_size);
-#endif
+int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt,
+                             int has_alpha);
 
+#if FF_API_FIND_BEST_PIX_FMT
 /**
- * Decodes the audio frame of size avpkt->size from avpkt->data into samples.
- * Some decoders may support multiple frames in a single AVPacket, such
- * decoders would then just decode the first frame.
- * If no frame
- * could be decompressed, \p frame_size_ptr is zero. Otherwise, it is the
- * decompressed frame size in \e bytes.
- *
- * @warning You \e must set \p frame_size_ptr to the allocated size of the
- * output buffer before calling avcodec_decode_audio3().
+ * @deprecated use avcodec_find_best_pix_fmt_of_2() instead.
  *
- * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than
- * the actual read bytes because some optimized bitstream readers read 32 or 64
- * bits at once and could read over the end.
+ * Find the best pixel format to convert to given a certain source pixel
+ * format.  When converting from one pixel format to another, information loss
+ * may occur.  For example, when converting from RGB24 to GRAY, the color
+ * information will be lost. Similarly, other losses occur when converting from
+ * some formats to other formats. avcodec_find_best_pix_fmt() searches which of
+ * the given pixel formats should be used to suffer the least amount of loss.
+ * The pixel formats from which it chooses one, are determined by the
+ * pix_fmt_mask parameter.
  *
- * @warning The end of the input buffer \p avpkt->data should be set to 0 to ensure that
- * no overreading happens for damaged MPEG streams.
+ * Note, only the first 64 pixel formats will fit in pix_fmt_mask.
  *
- * @note You might have to align the input buffer \p avpkt->data and output buffer \p
- * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
- * necessary at all, on others it won't work at all if not aligned and on others
- * it will work but it will have an impact on performance. In practice, the
- * bitstream should have 4 byte alignment at minimum and all sample data should
- * be 16 byte aligned unless the CPU doesn't need it (AltiVec and SSE do). If
- * the linesize is not a multiple of 16 then there's no sense in aligning the
- * start of the buffer to 16.
+ * @code
+ * src_pix_fmt = AV_PIX_FMT_YUV420P;
+ * pix_fmt_mask = (1 << AV_PIX_FMT_YUV422P) | (1 << AV_PIX_FMT_RGB24);
+ * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss);
+ * @endcode
  *
- * @param avctx the codec context
- * @param[out] samples the output buffer
- * @param[in,out] frame_size_ptr the output buffer size in bytes
- * @param[in] avpkt The input AVPacket containing the input buffer.
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame could be decompressed.
+ * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from
+ * @param[in] src_pix_fmt source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
+ * @return The best pixel format to convert to or -1 if none was found.
  */
-int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
-                         int *frame_size_ptr,
-                         AVPacket *avpkt);
+attribute_deprecated
+enum AVPixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum AVPixelFormat src_pix_fmt,
+                              int has_alpha, int *loss_ptr);
+#endif /* FF_API_FIND_BEST_PIX_FMT */
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
 /**
- * Decodes a video frame from \p buf into \p picture.
- * Wrapper function which calls avcodec_decode_video2.
+ * Find the best pixel format to convert to given a certain source pixel
+ * format.  When converting from one pixel format to another, information loss
+ * may occur.  For example, when converting from RGB24 to GRAY, the color
+ * information will be lost. Similarly, other losses occur when converting from
+ * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of
+ * the given pixel formats should be used to suffer the least amount of loss.
+ * The pixel formats from which it chooses one, are determined by the
+ * pix_fmt_list parameter.
  *
- * @deprecated Use avcodec_decode_video2 instead.
- * @param avctx the codec context
- * @param[out] picture The AVFrame in which the decoded video frame will be stored.
- * @param[in] buf the input buffer
- * @param[in] buf_size the size of the input buffer in bytes
- * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame could be decompressed.
+ *
+ * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to choose from
+ * @param[in] src_pix_fmt source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
+ * @return The best pixel format to convert to or -1 if none was found.
  */
-attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
-                         int *got_picture_ptr,
-                         const uint8_t *buf, int buf_size);
-#endif
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list,
+                                            enum AVPixelFormat src_pix_fmt,
+                                            int has_alpha, int *loss_ptr);
 
 /**
- * Decodes the video frame of size avpkt->size from avpkt->data into picture.
- * Some decoders may support multiple frames in a single AVPacket, such
- * decoders would then just decode the first frame.
- *
- * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than
- * the actual read bytes because some optimized bitstream readers read 32 or 64
- * bits at once and could read over the end.
- *
- * @warning The end of the input buffer \p buf should be set to 0 to ensure that
- * no overreading happens for damaged MPEG streams.
+ * Find the best pixel format to convert to given a certain source pixel
+ * format and a selection of two destination pixel formats. When converting from
+ * one pixel format to another, information loss may occur.  For example, when converting
+ * from RGB24 to GRAY, the color information will be lost. Similarly, other losses occur when
+ * converting from some formats to other formats. avcodec_find_best_pix_fmt_of_2() selects which of
+ * the given pixel formats should be used to suffer the least amount of loss.
  *
- * @note You might have to align the input buffer \p avpkt->data and output buffer \p
- * samples. The alignment requirements depend on the CPU: on some CPUs it isn't
- * necessary at all, on others it won't work at all if not aligned and on others
- * it will work but it will have an impact on performance. In practice, the
- * bitstream should have 4 byte alignment at minimum and all sample data should
- * be 16 byte aligned unless the CPU doesn't need it (AltiVec and SSE do). If
- * the linesize is not a multiple of 16 then there's no sense in aligning the
- * start of the buffer to 16.
+ * If one of the destination formats is AV_PIX_FMT_NONE the other pixel format (if valid) will be
+ * returned.
  *
- * @note Some codecs have a delay between input and output, these need to be
- * feeded with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames.
+ * @code
+ * src_pix_fmt = AV_PIX_FMT_YUV420P;
+ * dst_pix_fmt1= AV_PIX_FMT_RGB24;
+ * dst_pix_fmt2= AV_PIX_FMT_GRAY8;
+ * dst_pix_fmt3= AV_PIX_FMT_RGB8;
+ * loss= FF_LOSS_CHROMA; // don't care about chroma loss, so chroma loss will be ignored.
+ * dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, alpha, &loss);
+ * dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt, dst_pix_fmt3, src_pix_fmt, alpha, &loss);
+ * @endcode
  *
- * @param avctx the codec context
- * @param[out] picture The AVFrame in which the decoded video frame will be stored.
- * @param[in] avpkt The input AVpacket containing the input buffer.
- * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame could be decompressed.
+ * @param[in] dst_pix_fmt1 One of the two destination pixel formats to choose from
+ * @param[in] dst_pix_fmt2 The other of the two destination pixel formats to choose from
+ * @param[in] src_pix_fmt Source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @param[in, out] loss_ptr Combination of loss flags. In: selects which of the losses to ignore, i.e.
+ *                               NULL or value of zero means we care about all losses. Out: the loss
+ *                               that occurs when converting from src to selected dst pixel format.
+ * @return The best pixel format to convert to or -1 if none was found.
  */
-int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
-                         int *got_picture_ptr,
-                         AVPacket *avpkt);
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
+                                            enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
 
-#if LIBAVCODEC_VERSION_MAJOR < 53
-/* Decode a subtitle message. Return -1 if error, otherwise return the
- * number of bytes used. If no subtitle could be decompressed,
- * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */
-attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub,
-                            int *got_sub_ptr,
-                            const uint8_t *buf, int buf_size);
+attribute_deprecated
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
+                                              enum AVPixelFormat src_pix_fmt,
+                                              int has_alpha, int *loss_ptr);
+#else
+enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
+                                            enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
 #endif
 
+
+enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
+
 /**
- * Decodes a subtitle message.
- * Returns a negative value on error, otherwise returns the number of bytes used.
- * If no subtitle could be decompressed, \p got_sub_ptr is zero.
- * Otherwise, the subtitle is stored in \p *sub.
- *
- * @param avctx the codec context
- * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored.
- * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero.
- * @param[in] avpkt The input AVPacket containing the input buffer.
+ * @}
  */
-int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
-                            int *got_sub_ptr,
-                            AVPacket *avpkt);
-int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata,
-                        int *data_size_ptr,
-                        uint8_t *buf, int buf_size);
+
+void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
 
 /**
- * Encodes an audio frame from \p samples into \p buf.
+ * Put a string representing the codec tag codec_tag in buf.
  *
- * @note The output buffer should be at least \c FF_MIN_BUFFER_SIZE bytes large.
- * However, for PCM audio the user will know how much space is needed
- * because it depends on the value passed in \p buf_size as described
- * below. In that case a lower value can be used.
- *
- * @param avctx the codec context
- * @param[out] buf the output buffer
- * @param[in] buf_size the output buffer size
- * @param[in] samples the input buffer containing the samples
- * The number of samples read from this buffer is frame_size*channels,
- * both of which are defined in \p avctx.
- * For PCM audio the number of samples read from \p samples is equal to
- * \p buf_size * input_sample_size / output_sample_size.
- * @return On error a negative value is returned, on success zero or the number
- * of bytes used to encode the data read from the input buffer.
+ * @param buf_size size in bytes of buf
+ * @return the length of the string that would have been generated if
+ * enough space had been available, excluding the trailing null
  */
-int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size,
-                         const short *samples);
+size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag);
 
-/**
- * Encodes a video frame from \p pict into \p buf.
- * The input picture should be
- * stored using a specific format, namely \c avctx.pix_fmt.
- *
- * @param avctx the codec context
- * @param[out] buf the output buffer for the bitstream of encoded frame
- * @param[in] buf_size the size of the output buffer in bytes
- * @param[in] pict the input picture to encode
- * @return On error a negative value is returned, on success zero or the number
- * of bytes used from the output buffer.
+void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
+
+/**
+ * Return a name for the specified profile, if available.
+ *
+ * @param codec the codec that is searched for the given profile
+ * @param profile the profile value for which a name is requested
+ * @return A name for the profile if found, NULL otherwise.
  */
-int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
-                         const AVFrame *pict);
-int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
-                            const AVSubtitle *sub);
+const char *av_get_profile_name(const AVCodec *codec, int profile);
 
-int avcodec_close(AVCodecContext *avctx);
+int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
+int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
+//FIXME func typedef
 
 /**
- * Register all the codecs, parsers and bitstream filters which were enabled at
- * configuration time. If you do not call this function you can select exactly
- * which formats you want to support, by using the individual registration
- * functions.
+ * Fill audio frame data and linesize.
+ * AVFrame extended_data channel pointers are allocated if necessary for
+ * planar audio.
  *
- * @see avcodec_register
- * @see av_register_codec_parser
- * @see av_register_bitstream_filter
+ * @param frame       the AVFrame
+ *                    frame->nb_samples must be set prior to calling the
+ *                    function. This function fills in frame->data,
+ *                    frame->extended_data, frame->linesize[0].
+ * @param nb_channels channel count
+ * @param sample_fmt  sample format
+ * @param buf         buffer to use for frame data
+ * @param buf_size    size of buffer
+ * @param align       plane size sample alignment (0 = default)
+ * @return            0 on success, negative error code on failure
  */
-void avcodec_register_all(void);
+int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
+                             enum AVSampleFormat sample_fmt, const uint8_t *buf,
+                             int buf_size, int align);
 
 /**
  * Flush buffers, should be called when seeking or when switching to a different stream.
@@ -3361,223 +4715,41 @@ void avcodec_flush_buffers(AVCodecContext *avctx);
 
 void avcodec_default_free_buffers(AVCodecContext *s);
 
-/* misc useful functions */
-
 /**
- * Returns a single letter to describe the given picture type \p pict_type.
+ * Return codec bits per sample.
  *
- * @param[in] pict_type the picture type
- * @return A single character representing the picture type.
+ * @param[in] codec_id the codec
+ * @return Number of bits per sample or zero if unknown for the given codec.
  */
-char av_get_pict_type_char(int pict_type);
+int av_get_bits_per_sample(enum AVCodecID codec_id);
 
 /**
- * Returns codec bits per sample.
- *
- * @param[in] codec_id the codec
- * @return Number of bits per sample or zero if unknown for the given codec.
+ * Return the PCM codec associated with a sample format.
+ * @param be  endianness, 0 for little, 1 for big,
+ *            -1 (or anything else) for native
+ * @return  AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE
  */
-int av_get_bits_per_sample(enum CodecID codec_id);
+enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be);
 
 /**
- * Returns sample format bits per sample.
+ * Return codec bits per sample.
+ * Only return non-zero if the bits per sample is exactly correct, not an
+ * approximation.
  *
- * @param[in] sample_fmt the sample format
- * @return Number of bits per sample or zero if unknown for the given sample format.
+ * @param[in] codec_id the codec
+ * @return Number of bits per sample or zero if unknown for the given codec.
  */
-int av_get_bits_per_sample_format(enum SampleFormat sample_fmt);
-
-/* frame parsing */
-typedef struct AVCodecParserContext {
-    void *priv_data;
-    struct AVCodecParser *parser;
-    int64_t frame_offset; /* offset of the current frame */
-    int64_t cur_offset; /* current offset
-                           (incremented by each av_parser_parse()) */
-    int64_t next_frame_offset; /* offset of the next frame */
-    /* video info */
-    int pict_type; /* XXX: Put it back in AVCodecContext. */
-    /**
-     * This field is used for proper frame duration computation in lavf.
-     * It signals, how much longer the frame duration of the current frame
-     * is compared to normal frame duration.
-     *
-     * frame_duration = (1 + repeat_pict) * time_base
-     *
-     * It is used by codecs like H.264 to display telecined material.
-     */
-    int repeat_pict; /* XXX: Put it back in AVCodecContext. */
-    int64_t pts;     /* pts of the current frame */
-    int64_t dts;     /* dts of the current frame */
-
-    /* private data */
-    int64_t last_pts;
-    int64_t last_dts;
-    int fetch_timestamp;
-
-#define AV_PARSER_PTS_NB 4
-    int cur_frame_start_index;
-    int64_t cur_frame_offset[AV_PARSER_PTS_NB];
-    int64_t cur_frame_pts[AV_PARSER_PTS_NB];
-    int64_t cur_frame_dts[AV_PARSER_PTS_NB];
-
-    int flags;
-#define PARSER_FLAG_COMPLETE_FRAMES           0x0001
-
-    int64_t offset;      ///< byte offset from starting packet start
-    int64_t cur_frame_end[AV_PARSER_PTS_NB];
-
-    /*!
-     * Set by parser to 1 for key frames and 0 for non-key frames.
-     * It is initialized to -1, so if the parser doesn't set this flag,
-     * old-style fallback using FF_I_TYPE picture type as key frames
-     * will be used.
-     */
-    int key_frame;
-
-    /**
-     * Time difference in stream time base units from the pts of this
-     * packet to the point at which the output from the decoder has converged
-     * independent from the availability of previous frames. That is, the
-     * frames are virtually identical no matter if decoding started from
-     * the very first frame or from this keyframe.
-     * Is AV_NOPTS_VALUE if unknown.
-     * This field is not the display duration of the current frame.
-     *
-     * The purpose of this field is to allow seeking in streams that have no
-     * keyframes in the conventional sense. It corresponds to the
-     * recovery point SEI in H.264 and match_time_delta in NUT. It is also
-     * essential for some types of subtitle streams to ensure that all
-     * subtitles are correctly displayed after seeking.
-     */
-    int64_t convergence_duration;
-
-    // Timestamp generation support:
-    /**
-     * Synchronization point for start of timestamp generation.
-     *
-     * Set to >0 for sync point, 0 for no sync point and <0 for undefined
-     * (default).
-     *
-     * For example, this corresponds to presence of H.264 buffering period
-     * SEI message.
-     */
-    int dts_sync_point;
-
-    /**
-     * Offset of the current timestamp against last timestamp sync point in
-     * units of AVCodecContext.time_base.
-     *
-     * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
-     * contain a valid timestamp offset.
-     *
-     * Note that the timestamp of sync point has usually a nonzero
-     * dts_ref_dts_delta, which refers to the previous sync point. Offset of
-     * the next frame after timestamp sync point will be usually 1.
-     *
-     * For example, this corresponds to H.264 cpb_removal_delay.
-     */
-    int dts_ref_dts_delta;
-
-    /**
-     * Presentation delay of current frame in units of AVCodecContext.time_base.
-     *
-     * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
-     * contain valid non-negative timestamp delta (presentation time of a frame
-     * must not lie in the past).
-     *
-     * This delay represents the difference between decoding and presentation
-     * time of the frame.
-     *
-     * For example, this corresponds to H.264 dpb_output_delay.
-     */
-    int pts_dts_delta;
-
-    /**
-     * Position of the packet in file.
-     *
-     * Analogous to cur_frame_pts/dts
-     */
-    int64_t cur_frame_pos[AV_PARSER_PTS_NB];
-
-    /**
-     * Byte position of currently parsed frame in stream.
-     */
-    int64_t pos;
-
-    /**
-     * Previous frame byte position.
-     */
-    int64_t last_pos;
-} AVCodecParserContext;
-
-typedef struct AVCodecParser {
-    int codec_ids[5]; /* several codec IDs are permitted */
-    int priv_data_size;
-    int (*parser_init)(AVCodecParserContext *s);
-    int (*parser_parse)(AVCodecParserContext *s,
-                        AVCodecContext *avctx,
-                        const uint8_t **poutbuf, int *poutbuf_size,
-                        const uint8_t *buf, int buf_size);
-    void (*parser_close)(AVCodecParserContext *s);
-    int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
-    struct AVCodecParser *next;
-} AVCodecParser;
-
-AVCodecParser *av_parser_next(AVCodecParser *c);
-
-void av_register_codec_parser(AVCodecParser *parser);
-AVCodecParserContext *av_parser_init(int codec_id);
-
-#if LIBAVCODEC_VERSION_MAJOR < 53
-attribute_deprecated
-int av_parser_parse(AVCodecParserContext *s,
-                    AVCodecContext *avctx,
-                    uint8_t **poutbuf, int *poutbuf_size,
-                    const uint8_t *buf, int buf_size,
-                    int64_t pts, int64_t dts);
-#endif
+int av_get_exact_bits_per_sample(enum AVCodecID codec_id);
 
 /**
- * Parse a packet.
- *
- * @param s             parser context.
- * @param avctx         codec context.
- * @param poutbuf       set to pointer to parsed buffer or NULL if not yet finished.
- * @param poutbuf_size  set to size of parsed buffer or zero if not yet finished.
- * @param buf           input buffer.
- * @param buf_size      input length, to signal EOF, this should be 0 (so that the last frame can be output).
- * @param pts           input presentation timestamp.
- * @param dts           input decoding timestamp.
- * @param pos           input byte position in stream.
- * @return the number of bytes of the input bitstream used.
- *
- * Example:
- * @code
- *   while(in_len){
- *       len = av_parser_parse2(myparser, AVCodecContext, &data, &size,
- *                                        in_data, in_len,
- *                                        pts, dts, pos);
- *       in_data += len;
- *       in_len  -= len;
+ * Return audio frame duration.
  *
- *       if(size)
- *          decode_frame(data, size);
- *   }
- * @endcode
+ * @param avctx        codec context
+ * @param frame_bytes  size of the frame, or 0 if unknown
+ * @return             frame duration, in samples, if known. 0 if not able to
+ *                     determine.
  */
-int av_parser_parse2(AVCodecParserContext *s,
-                     AVCodecContext *avctx,
-                     uint8_t **poutbuf, int *poutbuf_size,
-                     const uint8_t *buf, int buf_size,
-                     int64_t pts, int64_t dts,
-                     int64_t pos);
-
-int av_parser_change(AVCodecParserContext *s,
-                     AVCodecContext *avctx,
-                     uint8_t **poutbuf, int *poutbuf_size,
-                     const uint8_t *buf, int buf_size, int keyframe);
-void av_parser_close(AVCodecParserContext *s);
+int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes);
 
 
 typedef struct AVBitStreamFilterContext {
@@ -3612,15 +4784,14 @@ AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f);
 /* memory */
 
 /**
- * Reallocates the given block if it is not large enough, otherwise it
- * does nothing.
+ * Reallocate the given block if it is not large enough, otherwise do nothing.
  *
  * @see av_realloc
  */
-void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size);
+void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size);
 
 /**
- * Allocates a buffer, reusing the given one if large enough.
+ * Allocate a buffer, reusing the given one if large enough.
  *
  * Contrary to av_fast_realloc the current buffer contents might not be
  * preserved and on error the old buffer is freed, thus no special
@@ -3631,74 +4802,58 @@ void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size);
  * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and
  *                 *size 0 if an error occurred.
  */
-void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size);
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size);
 
 /**
- * Copy image 'src' to 'dst'.
+ * Same behaviour av_fast_malloc but the buffer has additional
+ * FF_INPUT_PADDING_SIZE at the end which will will always be 0.
+ *
+ * In addition the whole buffer will initially and after resizes
+ * be 0-initialized so that no uninitialized data will ever appear.
  */
-void av_picture_copy(AVPicture *dst, const AVPicture *src,
-                     enum PixelFormat pix_fmt, int width, int height);
+void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size);
 
 /**
- * Crop image top and left side.
+ * Same behaviour av_fast_padded_malloc except that buffer will always
+ * be 0-initialized after call.
  */
-int av_picture_crop(AVPicture *dst, const AVPicture *src,
-                    enum PixelFormat pix_fmt, int top_band, int left_band);
+void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size);
 
 /**
- * Pad image.
+ * Encode extradata length to a buffer. Used by xiph codecs.
+ *
+ * @param s buffer to write to; must be at least (v/255+1) bytes long
+ * @param v size of extradata in bytes
+ * @return number of bytes written to the buffer.
  */
-int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum PixelFormat pix_fmt,
-            int padtop, int padbottom, int padleft, int padright, int *color);
-
 unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
 
 /**
- * Parses \p str and put in \p width_ptr and \p height_ptr the detected values.
- *
- * @return 0 in case of a successful parsing, a negative value otherwise
- * @param[in] str the string to parse: it has to be a string in the format
- * <width>x<height> or a valid video frame size abbreviation.
- * @param[in,out] width_ptr pointer to the variable which will contain the detected
- * frame width value
- * @param[in,out] height_ptr pointer to the variable which will contain the detected
- * frame height value
+ * Log a generic warning message about a missing feature. This function is
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
+ * only, and would normally not be used by applications.
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] feature string containing the name of the missing feature
+ * @param[in] want_sample indicates if samples are wanted which exhibit this feature.
+ * If want_sample is non-zero, additional verbage will be added to the log
+ * message which tells the user how to report samples to the development
+ * mailing list.
  */
-int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str);
+void av_log_missing_feature(void *avc, const char *feature, int want_sample);
 
 /**
- * Parses \p str and put in \p frame_rate the detected values.
- *
- * @return 0 in case of a successful parsing, a negative value otherwise
- * @param[in] str the string to parse: it has to be a string in the format
- * <frame_rate_num>/<frame_rate_den>, a float number or a valid video rate abbreviation
- * @param[in,out] frame_rate pointer to the AVRational which will contain the detected
- * frame rate
+ * Log a generic warning message asking for a sample. This function is
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
+ * only, and would normally not be used by applications.
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] msg string containing an optional message, or NULL if no message
  */
-int av_parse_video_frame_rate(AVRational *frame_rate, const char *str);
-
-/* error handling */
-#if EINVAL > 0
-#define AVERROR(e) (-(e)) /**< Returns a negative error code from a POSIX error code, to return from library functions. */
-#define AVUNERROR(e) (-(e)) /**< Returns a POSIX error code from a library function error return value. */
-#else
-/* Some platforms have E* and errno already negated. */
-#define AVERROR(e) (e)
-#define AVUNERROR(e) (e)
-#endif
-#define AVERROR_UNKNOWN     AVERROR(EINVAL)  /**< unknown error */
-#define AVERROR_IO          AVERROR(EIO)     /**< I/O error */
-#define AVERROR_NUMEXPECTED AVERROR(EDOM)    /**< Number syntax expected in filename. */
-#define AVERROR_INVALIDDATA AVERROR(EINVAL)  /**< invalid data found */
-#define AVERROR_NOMEM       AVERROR(ENOMEM)  /**< not enough memory */
-#define AVERROR_NOFMT       AVERROR(EILSEQ)  /**< unknown format */
-#define AVERROR_NOTSUPP     AVERROR(ENOSYS)  /**< Operation not supported. */
-#define AVERROR_NOENT       AVERROR(ENOENT)  /**< No such file or directory. */
-#define AVERROR_EOF         AVERROR(EPIPE)   /**< End of file. */
-#define AVERROR_PATCHWELCOME    -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */
+void av_log_ask_for_sample(void *avc, const char *msg, ...) av_printf_format(2, 3);
 
 /**
- * Registers the hardware accelerator \p hwaccel.
+ * Register the hardware accelerator hwaccel.
  */
 void av_register_hwaccel(AVHWAccel *hwaccel);
 
@@ -3709,4 +4864,81 @@ void av_register_hwaccel(AVHWAccel *hwaccel);
  */
 AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel);
 
+
+/**
+ * Lock operation used by lockmgr
+ */
+enum AVLockOp {
+  AV_LOCK_CREATE,  ///< Create a mutex
+  AV_LOCK_OBTAIN,  ///< Lock the mutex
+  AV_LOCK_RELEASE, ///< Unlock the mutex
+  AV_LOCK_DESTROY, ///< Free mutex resources
+};
+
+/**
+ * Register a user provided lock manager supporting the operations
+ * specified by AVLockOp. mutex points to a (void *) where the
+ * lockmgr should store/get a pointer to a user allocated mutex. It's
+ * NULL upon AV_LOCK_CREATE and != NULL for all other ops.
+ *
+ * @param cb User defined callback. Note: FFmpeg may invoke calls to this
+ *           callback during the call to av_lockmgr_register().
+ *           Thus, the application must be prepared to handle that.
+ *           If cb is set to NULL the lockmgr will be unregistered.
+ *           Also note that during unregistration the previously registered
+ *           lockmgr callback may also be invoked.
+ */
+int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
+
+/**
+ * Get the type of the given codec.
+ */
+enum AVMediaType avcodec_get_type(enum AVCodecID codec_id);
+
+/**
+ * Get the name of a codec.
+ * @return  a static string identifying the codec; never NULL
+ */
+const char *avcodec_get_name(enum AVCodecID id);
+
+/**
+ * @return a positive value if s is open (i.e. avcodec_open2() was called on it
+ * with no corresponding avcodec_close()), 0 otherwise.
+ */
+int avcodec_is_open(AVCodecContext *s);
+
+/**
+ * @return a non-zero number if codec is an encoder, zero otherwise
+ */
+int av_codec_is_encoder(const AVCodec *codec);
+
+/**
+ * @return a non-zero number if codec is a decoder, zero otherwise
+ */
+int av_codec_is_decoder(const AVCodec *codec);
+
+/**
+ * @return descriptor for given codec ID or NULL if no descriptor exists.
+ */
+const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id);
+
+/**
+ * Iterate over all codec descriptors known to libavcodec.
+ *
+ * @param prev previous descriptor. NULL to get the first descriptor.
+ *
+ * @return next descriptor or NULL after the last descriptor
+ */
+const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev);
+
+/**
+ * @return codec descriptor with the given name or NULL if no such descriptor
+ *         exists.
+ */
+const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
+
+/**
+ * @}
+ */
+
 #endif /* AVCODEC_AVCODEC_H */
diff --git a/extra_lib/include/libavcodec/avfft.h b/extra_lib/include/libavcodec/avfft.h
new file mode 100644 (file)
index 0000000..2d20a45
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AVFFT_H
+#define AVCODEC_AVFFT_H
+
+/**
+ * @file
+ * @ingroup lavc_fft
+ * FFT functions
+ */
+
+/**
+ * @defgroup lavc_fft FFT functions
+ * @ingroup lavc_misc
+ *
+ * @{
+ */
+
+typedef float FFTSample;
+
+typedef struct FFTComplex {
+    FFTSample re, im;
+} FFTComplex;
+
+typedef struct FFTContext FFTContext;
+
+/**
+ * Set up a complex FFT.
+ * @param nbits           log2 of the length of the input array
+ * @param inverse         if 0 perform the forward transform, if 1 perform the inverse
+ */
+FFTContext *av_fft_init(int nbits, int inverse);
+
+/**
+ * Do the permutation needed BEFORE calling ff_fft_calc().
+ */
+void av_fft_permute(FFTContext *s, FFTComplex *z);
+
+/**
+ * Do a complex FFT with the parameters defined in av_fft_init(). The
+ * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
+ */
+void av_fft_calc(FFTContext *s, FFTComplex *z);
+
+void av_fft_end(FFTContext *s);
+
+FFTContext *av_mdct_init(int nbits, int inverse, double scale);
+void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_mdct_end(FFTContext *s);
+
+/* Real Discrete Fourier Transform */
+
+enum RDFTransformType {
+    DFT_R2C,
+    IDFT_C2R,
+    IDFT_R2C,
+    DFT_C2R,
+};
+
+typedef struct RDFTContext RDFTContext;
+
+/**
+ * Set up a real FFT.
+ * @param nbits           log2 of the length of the input array
+ * @param trans           the type of transform
+ */
+RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
+void av_rdft_calc(RDFTContext *s, FFTSample *data);
+void av_rdft_end(RDFTContext *s);
+
+/* Discrete Cosine Transform */
+
+typedef struct DCTContext DCTContext;
+
+enum DCTTransformType {
+    DCT_II = 0,
+    DCT_III,
+    DCT_I,
+    DST_I,
+};
+
+/**
+ * Set up DCT.
+ * @param nbits           size of the input array:
+ *                        (1 << nbits)     for DCT-II, DCT-III and DST-I
+ *                        (1 << nbits) + 1 for DCT-I
+ *
+ * @note the first element of the input of DST-I is ignored
+ */
+DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
+void av_dct_calc(DCTContext *s, FFTSample *data);
+void av_dct_end (DCTContext *s);
+
+/**
+ * @}
+ */
+
+#endif /* AVCODEC_AVFFT_H */
diff --git a/extra_lib/include/libavcodec/dxva2.h b/extra_lib/include/libavcodec/dxva2.h
new file mode 100644 (file)
index 0000000..7d27ca5
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * DXVA2 HW acceleration
+ *
+ * copyright (c) 2009 Laurent Aimar
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DXVA_H
+#define AVCODEC_DXVA_H
+
+/**
+ * @file
+ * @ingroup lavc_codec_hwaccel_dxva2
+ * Public libavcodec DXVA2 header.
+ */
+
+#include <stdint.h>
+
+#include <d3d9.h>
+#include <dxva2api.h>
+
+/**
+ * @defgroup lavc_codec_hwaccel_dxva2 DXVA2
+ * @ingroup lavc_codec_hwaccel
+ *
+ * @{
+ */
+
+#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
+
+/**
+ * This structure is used to provides the necessary configurations and data
+ * to the DXVA2 FFmpeg HWAccel implementation.
+ *
+ * The application must make it available as AVCodecContext.hwaccel_context.
+ */
+struct dxva_context {
+    /**
+     * DXVA2 decoder object
+     */
+    IDirectXVideoDecoder *decoder;
+
+    /**
+     * DXVA2 configuration used to create the decoder
+     */
+    const DXVA2_ConfigPictureDecode *cfg;
+
+    /**
+     * The number of surface in the surface array
+     */
+    unsigned surface_count;
+
+    /**
+     * The array of Direct3D surfaces used to create the decoder
+     */
+    LPDIRECT3DSURFACE9 *surface;
+
+    /**
+     * A bit field configuring the workarounds needed for using the decoder
+     */
+    uint64_t workaround;
+
+    /**
+     * Private to the FFmpeg AVHWAccel implementation
+     */
+    unsigned report_id;
+};
+
+/**
+ * @}
+ */
+
+#endif /* AVCODEC_DXVA_H */
diff --git a/extra_lib/include/libavcodec/old_codec_ids.h b/extra_lib/include/libavcodec/old_codec_ids.h
new file mode 100644 (file)
index 0000000..ded4cc7
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_OLD_CODEC_IDS_H
+#define AVCODEC_OLD_CODEC_IDS_H
+
+#include "libavutil/common.h"
+
+/*
+ * This header exists to prevent new codec IDs from being accidentally added to
+ * the deprecated list.
+ * Do not include it directly. It will be removed on next major bump
+ *
+ * Do not add new items to this list. Use the AVCodecID enum instead.
+ */
+
+    CODEC_ID_NONE = AV_CODEC_ID_NONE,
+
+    /* video codecs */
+    CODEC_ID_MPEG1VIDEO,
+    CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+    CODEC_ID_MPEG2VIDEO_XVMC,
+    CODEC_ID_H261,
+    CODEC_ID_H263,
+    CODEC_ID_RV10,
+    CODEC_ID_RV20,
+    CODEC_ID_MJPEG,
+    CODEC_ID_MJPEGB,
+    CODEC_ID_LJPEG,
+    CODEC_ID_SP5X,
+    CODEC_ID_JPEGLS,
+    CODEC_ID_MPEG4,
+    CODEC_ID_RAWVIDEO,
+    CODEC_ID_MSMPEG4V1,
+    CODEC_ID_MSMPEG4V2,
+    CODEC_ID_MSMPEG4V3,
+    CODEC_ID_WMV1,
+    CODEC_ID_WMV2,
+    CODEC_ID_H263P,
+    CODEC_ID_H263I,
+    CODEC_ID_FLV1,
+    CODEC_ID_SVQ1,
+    CODEC_ID_SVQ3,
+    CODEC_ID_DVVIDEO,
+    CODEC_ID_HUFFYUV,
+    CODEC_ID_CYUV,
+    CODEC_ID_H264,
+    CODEC_ID_INDEO3,
+    CODEC_ID_VP3,
+    CODEC_ID_THEORA,
+    CODEC_ID_ASV1,
+    CODEC_ID_ASV2,
+    CODEC_ID_FFV1,
+    CODEC_ID_4XM,
+    CODEC_ID_VCR1,
+    CODEC_ID_CLJR,
+    CODEC_ID_MDEC,
+    CODEC_ID_ROQ,
+    CODEC_ID_INTERPLAY_VIDEO,
+    CODEC_ID_XAN_WC3,
+    CODEC_ID_XAN_WC4,
+    CODEC_ID_RPZA,
+    CODEC_ID_CINEPAK,
+    CODEC_ID_WS_VQA,
+    CODEC_ID_MSRLE,
+    CODEC_ID_MSVIDEO1,
+    CODEC_ID_IDCIN,
+    CODEC_ID_8BPS,
+    CODEC_ID_SMC,
+    CODEC_ID_FLIC,
+    CODEC_ID_TRUEMOTION1,
+    CODEC_ID_VMDVIDEO,
+    CODEC_ID_MSZH,
+    CODEC_ID_ZLIB,
+    CODEC_ID_QTRLE,
+    CODEC_ID_SNOW,
+    CODEC_ID_TSCC,
+    CODEC_ID_ULTI,
+    CODEC_ID_QDRAW,
+    CODEC_ID_VIXL,
+    CODEC_ID_QPEG,
+    CODEC_ID_PNG,
+    CODEC_ID_PPM,
+    CODEC_ID_PBM,
+    CODEC_ID_PGM,
+    CODEC_ID_PGMYUV,
+    CODEC_ID_PAM,
+    CODEC_ID_FFVHUFF,
+    CODEC_ID_RV30,
+    CODEC_ID_RV40,
+    CODEC_ID_VC1,
+    CODEC_ID_WMV3,
+    CODEC_ID_LOCO,
+    CODEC_ID_WNV1,
+    CODEC_ID_AASC,
+    CODEC_ID_INDEO2,
+    CODEC_ID_FRAPS,
+    CODEC_ID_TRUEMOTION2,
+    CODEC_ID_BMP,
+    CODEC_ID_CSCD,
+    CODEC_ID_MMVIDEO,
+    CODEC_ID_ZMBV,
+    CODEC_ID_AVS,
+    CODEC_ID_SMACKVIDEO,
+    CODEC_ID_NUV,
+    CODEC_ID_KMVC,
+    CODEC_ID_FLASHSV,
+    CODEC_ID_CAVS,
+    CODEC_ID_JPEG2000,
+    CODEC_ID_VMNC,
+    CODEC_ID_VP5,
+    CODEC_ID_VP6,
+    CODEC_ID_VP6F,
+    CODEC_ID_TARGA,
+    CODEC_ID_DSICINVIDEO,
+    CODEC_ID_TIERTEXSEQVIDEO,
+    CODEC_ID_TIFF,
+    CODEC_ID_GIF,
+    CODEC_ID_DXA,
+    CODEC_ID_DNXHD,
+    CODEC_ID_THP,
+    CODEC_ID_SGI,
+    CODEC_ID_C93,
+    CODEC_ID_BETHSOFTVID,
+    CODEC_ID_PTX,
+    CODEC_ID_TXD,
+    CODEC_ID_VP6A,
+    CODEC_ID_AMV,
+    CODEC_ID_VB,
+    CODEC_ID_PCX,
+    CODEC_ID_SUNRAST,
+    CODEC_ID_INDEO4,
+    CODEC_ID_INDEO5,
+    CODEC_ID_MIMIC,
+    CODEC_ID_RL2,
+    CODEC_ID_ESCAPE124,
+    CODEC_ID_DIRAC,
+    CODEC_ID_BFI,
+    CODEC_ID_CMV,
+    CODEC_ID_MOTIONPIXELS,
+    CODEC_ID_TGV,
+    CODEC_ID_TGQ,
+    CODEC_ID_TQI,
+    CODEC_ID_AURA,
+    CODEC_ID_AURA2,
+    CODEC_ID_V210X,
+    CODEC_ID_TMV,
+    CODEC_ID_V210,
+    CODEC_ID_DPX,
+    CODEC_ID_MAD,
+    CODEC_ID_FRWU,
+    CODEC_ID_FLASHSV2,
+    CODEC_ID_CDGRAPHICS,
+    CODEC_ID_R210,
+    CODEC_ID_ANM,
+    CODEC_ID_BINKVIDEO,
+    CODEC_ID_IFF_ILBM,
+    CODEC_ID_IFF_BYTERUN1,
+    CODEC_ID_KGV1,
+    CODEC_ID_YOP,
+    CODEC_ID_VP8,
+    CODEC_ID_PICTOR,
+    CODEC_ID_ANSI,
+    CODEC_ID_A64_MULTI,
+    CODEC_ID_A64_MULTI5,
+    CODEC_ID_R10K,
+    CODEC_ID_MXPEG,
+    CODEC_ID_LAGARITH,
+    CODEC_ID_PRORES,
+    CODEC_ID_JV,
+    CODEC_ID_DFA,
+    CODEC_ID_WMV3IMAGE,
+    CODEC_ID_VC1IMAGE,
+    CODEC_ID_UTVIDEO,
+    CODEC_ID_BMV_VIDEO,
+    CODEC_ID_VBLE,
+    CODEC_ID_DXTORY,
+    CODEC_ID_V410,
+    CODEC_ID_XWD,
+    CODEC_ID_CDXL,
+    CODEC_ID_XBM,
+    CODEC_ID_ZEROCODEC,
+    CODEC_ID_MSS1,
+    CODEC_ID_MSA1,
+    CODEC_ID_TSCC2,
+    CODEC_ID_MTS2,
+    CODEC_ID_CLLC,
+    CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
+    CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'),
+    CODEC_ID_EXR        = MKBETAG('0','E','X','R'),
+    CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
+
+    CODEC_ID_G2M        = MKBETAG( 0 ,'G','2','M'),
+    CODEC_ID_AVUI       = MKBETAG('A','V','U','I'),
+    CODEC_ID_AYUV       = MKBETAG('A','Y','U','V'),
+    CODEC_ID_V308       = MKBETAG('V','3','0','8'),
+    CODEC_ID_V408       = MKBETAG('V','4','0','8'),
+    CODEC_ID_YUV4       = MKBETAG('Y','U','V','4'),
+    CODEC_ID_SANM       = MKBETAG('S','A','N','M'),
+    CODEC_ID_PAF_VIDEO  = MKBETAG('P','A','F','V'),
+
+    /* various PCM "codecs" */
+    CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
+    CODEC_ID_PCM_S16LE = 0x10000,
+    CODEC_ID_PCM_S16BE,
+    CODEC_ID_PCM_U16LE,
+    CODEC_ID_PCM_U16BE,
+    CODEC_ID_PCM_S8,
+    CODEC_ID_PCM_U8,
+    CODEC_ID_PCM_MULAW,
+    CODEC_ID_PCM_ALAW,
+    CODEC_ID_PCM_S32LE,
+    CODEC_ID_PCM_S32BE,
+    CODEC_ID_PCM_U32LE,
+    CODEC_ID_PCM_U32BE,
+    CODEC_ID_PCM_S24LE,
+    CODEC_ID_PCM_S24BE,
+    CODEC_ID_PCM_U24LE,
+    CODEC_ID_PCM_U24BE,
+    CODEC_ID_PCM_S24DAUD,
+    CODEC_ID_PCM_ZORK,
+    CODEC_ID_PCM_S16LE_PLANAR,
+    CODEC_ID_PCM_DVD,
+    CODEC_ID_PCM_F32BE,
+    CODEC_ID_PCM_F32LE,
+    CODEC_ID_PCM_F64BE,
+    CODEC_ID_PCM_F64LE,
+    CODEC_ID_PCM_BLURAY,
+    CODEC_ID_PCM_LXF,
+    CODEC_ID_S302M,
+    CODEC_ID_PCM_S8_PLANAR,
+
+    /* various ADPCM codecs */
+    CODEC_ID_ADPCM_IMA_QT = 0x11000,
+    CODEC_ID_ADPCM_IMA_WAV,
+    CODEC_ID_ADPCM_IMA_DK3,
+    CODEC_ID_ADPCM_IMA_DK4,
+    CODEC_ID_ADPCM_IMA_WS,
+    CODEC_ID_ADPCM_IMA_SMJPEG,
+    CODEC_ID_ADPCM_MS,
+    CODEC_ID_ADPCM_4XM,
+    CODEC_ID_ADPCM_XA,
+    CODEC_ID_ADPCM_ADX,
+    CODEC_ID_ADPCM_EA,
+    CODEC_ID_ADPCM_G726,
+    CODEC_ID_ADPCM_CT,
+    CODEC_ID_ADPCM_SWF,
+    CODEC_ID_ADPCM_YAMAHA,
+    CODEC_ID_ADPCM_SBPRO_4,
+    CODEC_ID_ADPCM_SBPRO_3,
+    CODEC_ID_ADPCM_SBPRO_2,
+    CODEC_ID_ADPCM_THP,
+    CODEC_ID_ADPCM_IMA_AMV,
+    CODEC_ID_ADPCM_EA_R1,
+    CODEC_ID_ADPCM_EA_R3,
+    CODEC_ID_ADPCM_EA_R2,
+    CODEC_ID_ADPCM_IMA_EA_SEAD,
+    CODEC_ID_ADPCM_IMA_EA_EACS,
+    CODEC_ID_ADPCM_EA_XAS,
+    CODEC_ID_ADPCM_EA_MAXIS_XA,
+    CODEC_ID_ADPCM_IMA_ISS,
+    CODEC_ID_ADPCM_G722,
+    CODEC_ID_ADPCM_IMA_APC,
+    CODEC_ID_VIMA       = MKBETAG('V','I','M','A'),
+
+    /* AMR */
+    CODEC_ID_AMR_NB = 0x12000,
+    CODEC_ID_AMR_WB,
+
+    /* RealAudio codecs*/
+    CODEC_ID_RA_144 = 0x13000,
+    CODEC_ID_RA_288,
+
+    /* various DPCM codecs */
+    CODEC_ID_ROQ_DPCM = 0x14000,
+    CODEC_ID_INTERPLAY_DPCM,
+    CODEC_ID_XAN_DPCM,
+    CODEC_ID_SOL_DPCM,
+
+    /* audio codecs */
+    CODEC_ID_MP2 = 0x15000,
+    CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
+    CODEC_ID_AAC,
+    CODEC_ID_AC3,
+    CODEC_ID_DTS,
+    CODEC_ID_VORBIS,
+    CODEC_ID_DVAUDIO,
+    CODEC_ID_WMAV1,
+    CODEC_ID_WMAV2,
+    CODEC_ID_MACE3,
+    CODEC_ID_MACE6,
+    CODEC_ID_VMDAUDIO,
+    CODEC_ID_FLAC,
+    CODEC_ID_MP3ADU,
+    CODEC_ID_MP3ON4,
+    CODEC_ID_SHORTEN,
+    CODEC_ID_ALAC,
+    CODEC_ID_WESTWOOD_SND1,
+    CODEC_ID_GSM, ///< as in Berlin toast format
+    CODEC_ID_QDM2,
+    CODEC_ID_COOK,
+    CODEC_ID_TRUESPEECH,
+    CODEC_ID_TTA,
+    CODEC_ID_SMACKAUDIO,
+    CODEC_ID_QCELP,
+    CODEC_ID_WAVPACK,
+    CODEC_ID_DSICINAUDIO,
+    CODEC_ID_IMC,
+    CODEC_ID_MUSEPACK7,
+    CODEC_ID_MLP,
+    CODEC_ID_GSM_MS, /* as found in WAV */
+    CODEC_ID_ATRAC3,
+    CODEC_ID_VOXWARE,
+    CODEC_ID_APE,
+    CODEC_ID_NELLYMOSER,
+    CODEC_ID_MUSEPACK8,
+    CODEC_ID_SPEEX,
+    CODEC_ID_WMAVOICE,
+    CODEC_ID_WMAPRO,
+    CODEC_ID_WMALOSSLESS,
+    CODEC_ID_ATRAC3P,
+    CODEC_ID_EAC3,
+    CODEC_ID_SIPR,
+    CODEC_ID_MP1,
+    CODEC_ID_TWINVQ,
+    CODEC_ID_TRUEHD,
+    CODEC_ID_MP4ALS,
+    CODEC_ID_ATRAC1,
+    CODEC_ID_BINKAUDIO_RDFT,
+    CODEC_ID_BINKAUDIO_DCT,
+    CODEC_ID_AAC_LATM,
+    CODEC_ID_QDMC,
+    CODEC_ID_CELT,
+    CODEC_ID_G723_1,
+    CODEC_ID_G729,
+    CODEC_ID_8SVX_EXP,
+    CODEC_ID_8SVX_FIB,
+    CODEC_ID_BMV_AUDIO,
+    CODEC_ID_RALF,
+    CODEC_ID_IAC,
+    CODEC_ID_ILBC,
+    CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
+    CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
+    CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
+    CODEC_ID_SONIC_LS    = MKBETAG('S','O','N','L'),
+    CODEC_ID_PAF_AUDIO   = MKBETAG('P','A','F','A'),
+    CODEC_ID_OPUS        = MKBETAG('O','P','U','S'),
+
+    /* subtitle codecs */
+    CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
+    CODEC_ID_DVD_SUBTITLE = 0x17000,
+    CODEC_ID_DVB_SUBTITLE,
+    CODEC_ID_TEXT,  ///< raw UTF-8 text
+    CODEC_ID_XSUB,
+    CODEC_ID_SSA,
+    CODEC_ID_MOV_TEXT,
+    CODEC_ID_HDMV_PGS_SUBTITLE,
+    CODEC_ID_DVB_TELETEXT,
+    CODEC_ID_SRT,
+    CODEC_ID_MICRODVD   = MKBETAG('m','D','V','D'),
+    CODEC_ID_EIA_608    = MKBETAG('c','6','0','8'),
+    CODEC_ID_JACOSUB    = MKBETAG('J','S','U','B'),
+    CODEC_ID_SAMI       = MKBETAG('S','A','M','I'),
+    CODEC_ID_REALTEXT   = MKBETAG('R','T','X','T'),
+    CODEC_ID_SUBVIEWER  = MKBETAG('S','u','b','V'),
+
+    /* other specific kind of codecs (generally used for attachments) */
+    CODEC_ID_FIRST_UNKNOWN = 0x18000,           ///< A dummy ID pointing at the start of various fake codecs.
+    CODEC_ID_TTF = 0x18000,
+    CODEC_ID_BINTEXT    = MKBETAG('B','T','X','T'),
+    CODEC_ID_XBIN       = MKBETAG('X','B','I','N'),
+    CODEC_ID_IDF        = MKBETAG( 0 ,'I','D','F'),
+    CODEC_ID_OTF        = MKBETAG( 0 ,'O','T','F'),
+
+    CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
+
+    CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
+                                * stream (only used by libavformat) */
+    CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
+                                * stream (only used by libavformat) */
+    CODEC_ID_FFMETADATA = 0x21000,   ///< Dummy codec for streams containing only metadata information.
+
+#endif /* AVCODEC_OLD_CODEC_IDS_H */
diff --git a/extra_lib/include/libavcodec/vaapi.h b/extra_lib/include/libavcodec/vaapi.h
new file mode 100644 (file)
index 0000000..815a27e
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Video Acceleration API (shared data between FFmpeg and the video player)
+ * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
+ *
+ * Copyright (C) 2008-2009 Splitted-Desktop Systems
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VAAPI_H
+#define AVCODEC_VAAPI_H
+
+/**
+ * @file
+ * @ingroup lavc_codec_hwaccel_vaapi
+ * Public libavcodec VA API header.
+ */
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding
+ * @ingroup lavc_codec_hwaccel
+ * @{
+ */
+
+/**
+ * This structure is used to share data between the FFmpeg library and
+ * the client video application.
+ * This shall be zero-allocated and available as
+ * AVCodecContext.hwaccel_context. All user members can be set once
+ * during initialization or through each AVCodecContext.get_buffer()
+ * function call. In any case, they must be valid prior to calling
+ * decoding functions.
+ */
+struct vaapi_context {
+    /**
+     * Window system dependent data
+     *
+     * - encoding: unused
+     * - decoding: Set by user
+     */
+    void *display;
+
+    /**
+     * Configuration ID
+     *
+     * - encoding: unused
+     * - decoding: Set by user
+     */
+    uint32_t config_id;
+
+    /**
+     * Context ID (video decode pipeline)
+     *
+     * - encoding: unused
+     * - decoding: Set by user
+     */
+    uint32_t context_id;
+
+    /**
+     * VAPictureParameterBuffer ID
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    uint32_t pic_param_buf_id;
+
+    /**
+     * VAIQMatrixBuffer ID
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    uint32_t iq_matrix_buf_id;
+
+    /**
+     * VABitPlaneBuffer ID (for VC-1 decoding)
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    uint32_t bitplane_buf_id;
+
+    /**
+     * Slice parameter/data buffer IDs
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    uint32_t *slice_buf_ids;
+
+    /**
+     * Number of effective slice buffer IDs to send to the HW
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    unsigned int n_slice_buf_ids;
+
+    /**
+     * Size of pre-allocated slice_buf_ids
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    unsigned int slice_buf_ids_alloc;
+
+    /**
+     * Pointer to VASliceParameterBuffers
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    void *slice_params;
+
+    /**
+     * Size of a VASliceParameterBuffer element
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    unsigned int slice_param_size;
+
+    /**
+     * Size of pre-allocated slice_params
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    unsigned int slice_params_alloc;
+
+    /**
+     * Number of slices currently filled in
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    unsigned int slice_count;
+
+    /**
+     * Pointer to slice data buffer base
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    const uint8_t *slice_data;
+
+    /**
+     * Current size of slice data
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec
+     */
+    uint32_t slice_data_size;
+};
+
+/* @} */
+
+#endif /* AVCODEC_VAAPI_H */
diff --git a/extra_lib/include/libavcodec/vda.h b/extra_lib/include/libavcodec/vda.h
new file mode 100644 (file)
index 0000000..ccbf375
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * VDA HW acceleration
+ *
+ * copyright (c) 2011 Sebastien Zwickert
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VDA_H
+#define AVCODEC_VDA_H
+
+/**
+ * @file
+ * @ingroup lavc_codec_hwaccel_vda
+ * Public libavcodec VDA header.
+ */
+
+#include "libavcodec/version.h"
+
+#if FF_API_VDA_ASYNC
+#include <pthread.h>
+#endif
+
+#include <stdint.h>
+
+// emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes
+// http://openradar.appspot.com/8026390
+#undef __GNUC_STDC_INLINE__
+
+#define Picture QuickdrawPicture
+#include <VideoDecodeAcceleration/VDADecoder.h>
+#undef Picture
+
+/**
+ * @defgroup lavc_codec_hwaccel_vda VDA
+ * @ingroup lavc_codec_hwaccel
+ *
+ * @{
+ */
+
+#if FF_API_VDA_ASYNC
+/**
+ * This structure is used to store decoded frame information and data.
+ *
+ * @deprecated Use synchronous decoding mode.
+ */
+typedef struct {
+    /**
+     * The PTS of the frame.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    int64_t             pts;
+
+    /**
+     * The CoreVideo buffer that contains the decoded data.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    CVPixelBufferRef    cv_buffer;
+
+    /**
+     * A pointer to the next frame.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    struct vda_frame    *next_frame;
+} vda_frame;
+#endif
+
+/**
+ * This structure is used to provide the necessary configurations and data
+ * to the VDA FFmpeg HWAccel implementation.
+ *
+ * The application must make it available as AVCodecContext.hwaccel_context.
+ */
+struct vda_context {
+    /**
+     * VDA decoder object.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    VDADecoder          decoder;
+
+    /**
+     * The Core Video pixel buffer that contains the current image data.
+     *
+     * encoding: unused
+     * decoding: Set by libavcodec. Unset by user.
+     */
+    CVPixelBufferRef    cv_buffer;
+
+    /**
+     * Use the hardware decoder in synchronous mode.
+     *
+     * encoding: unused
+     * decoding: Set by user.
+     */
+    int                 use_sync_decoding;
+
+#if FF_API_VDA_ASYNC
+    /**
+     * VDA frames queue ordered by presentation timestamp.
+     *
+     * @deprecated Use synchronous decoding mode.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    vda_frame           *queue;
+
+    /**
+     * Mutex for locking queue operations.
+     *
+     * @deprecated Use synchronous decoding mode.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    pthread_mutex_t     queue_mutex;
+#endif
+
+    /**
+     * The frame width.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by user.
+     */
+    int                 width;
+
+    /**
+     * The frame height.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by user.
+     */
+    int                 height;
+
+    /**
+     * The frame format.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by user.
+     */
+    int                 format;
+
+    /**
+     * The pixel format for output image buffers.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by user.
+     */
+    OSType              cv_pix_fmt_type;
+
+    /**
+     * The current bitstream buffer.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    uint8_t             *priv_bitstream;
+
+    /**
+     * The current size of the bitstream.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    int                 priv_bitstream_size;
+
+    /**
+     * The reference size used for fast reallocation.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
+     */
+    int                 priv_allocated_size;
+};
+
+/** Create the video decoder. */
+int ff_vda_create_decoder(struct vda_context *vda_ctx,
+                          uint8_t *extradata,
+                          int extradata_size);
+
+/** Destroy the video decoder. */
+int ff_vda_destroy_decoder(struct vda_context *vda_ctx);
+
+#if FF_API_VDA_ASYNC
+/**
+ * Return the top frame of the queue.
+ *
+ * @deprecated Use synchronous decoding mode.
+ */
+vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx);
+
+/**
+ * Release the given frame.
+ *
+ * @deprecated Use synchronous decoding mode.
+ */
+void ff_vda_release_vda_frame(vda_frame *frame);
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* AVCODEC_VDA_H */
diff --git a/extra_lib/include/libavcodec/vdpau.h b/extra_lib/include/libavcodec/vdpau.h
new file mode 100644 (file)
index 0000000..23394b5
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * The Video Decode and Presentation API for UNIX (VDPAU) is used for
+ * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1.
+ *
+ * Copyright (C) 2008 NVIDIA
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VDPAU_H
+#define AVCODEC_VDPAU_H
+
+/**
+ * @file
+ * @ingroup lavc_codec_hwaccel_vdpau
+ * Public libavcodec VDPAU header.
+ */
+
+
+/**
+ * @defgroup lavc_codec_hwaccel_vdpau VDPAU Decoder and Renderer
+ * @ingroup lavc_codec_hwaccel
+ *
+ * VDPAU hardware acceleration has two modules
+ * - VDPAU decoding
+ * - VDPAU presentation
+ *
+ * The VDPAU decoding module parses all headers using FFmpeg
+ * parsing mechanisms and uses VDPAU for the actual decoding.
+ *
+ * As per the current implementation, the actual decoding
+ * and rendering (API calls) are done as part of the VDPAU
+ * presentation (vo_vdpau.c) module.
+ *
+ * @{
+ */
+
+#include <vdpau/vdpau.h>
+#include <vdpau/vdpau_x11.h>
+
+/** @brief The videoSurface is used for rendering. */
+#define FF_VDPAU_STATE_USED_FOR_RENDER 1
+
+/**
+ * @brief The videoSurface is needed for reference/prediction.
+ * The codec manipulates this.
+ */
+#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2
+
+/**
+ * @brief This structure is used as a callback between the FFmpeg
+ * decoder (vd_) and presentation (vo_) module.
+ * This is used for defining a video frame containing surface,
+ * picture parameter, bitstream information etc which are passed
+ * between the FFmpeg decoder and its clients.
+ */
+struct vdpau_render_state {
+    VdpVideoSurface surface; ///< Used as rendered surface, never changed.
+
+    int state; ///< Holds FF_VDPAU_STATE_* values.
+
+    /** Describe size/location of the compressed video data.
+        Set to 0 when freeing bitstream_buffers. */
+    int bitstream_buffers_allocated;
+    int bitstream_buffers_used;
+    /** The user is responsible for freeing this buffer using av_freep(). */
+    VdpBitstreamBuffer *bitstream_buffers;
+
+    /** picture parameter information for all supported codecs */
+    union VdpPictureInfo {
+        VdpPictureInfoH264        h264;
+        VdpPictureInfoMPEG1Or2    mpeg;
+        VdpPictureInfoVC1          vc1;
+        VdpPictureInfoMPEG4Part2 mpeg4;
+    } info;
+};
+
+/* @}*/
+
+#endif /* AVCODEC_VDPAU_H */
diff --git a/extra_lib/include/libavcodec/version.h b/extra_lib/include/libavcodec/version.h
new file mode 100644 (file)
index 0000000..b2d5c1b
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VERSION_H
+#define AVCODEC_VERSION_H
+
+/**
+ * @file
+ * @ingroup libavc
+ * Libavcodec version macros.
+ */
+
+#include "libavutil/avutil.h"
+
+#define LIBAVCODEC_VERSION_MAJOR 54
+#define LIBAVCODEC_VERSION_MINOR 67
+#define LIBAVCODEC_VERSION_MICRO 100
+
+#define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
+                                               LIBAVCODEC_VERSION_MINOR, \
+                                               LIBAVCODEC_VERSION_MICRO)
+#define LIBAVCODEC_VERSION      AV_VERSION(LIBAVCODEC_VERSION_MAJOR,    \
+                                           LIBAVCODEC_VERSION_MINOR,    \
+                                           LIBAVCODEC_VERSION_MICRO)
+#define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
+
+#define LIBAVCODEC_IDENT        "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
+
+/**
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ */
+
+#ifndef FF_API_REQUEST_CHANNELS
+#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_ALLOC_CONTEXT
+#define FF_API_ALLOC_CONTEXT    (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_AVCODEC_OPEN
+#define FF_API_AVCODEC_OPEN     (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_OLD_DECODE_AUDIO
+#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_OLD_TIMECODE
+#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+
+#ifndef FF_API_OLD_ENCODE_AUDIO
+#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_OLD_ENCODE_VIDEO
+#define FF_API_OLD_ENCODE_VIDEO (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_MPV_GLOBAL_OPTS
+#define FF_API_MPV_GLOBAL_OPTS  (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_COLOR_TABLE_ID
+#define FF_API_COLOR_TABLE_ID   (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_INTER_THRESHOLD
+#define FF_API_INTER_THRESHOLD  (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_SUB_ID
+#define FF_API_SUB_ID           (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_DSP_MASK
+#define FF_API_DSP_MASK         (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_FIND_BEST_PIX_FMT
+#define FF_API_FIND_BEST_PIX_FMT (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_CODEC_ID
+#define FF_API_CODEC_ID          (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_VDA_ASYNC
+#define FF_API_VDA_ASYNC         (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_AVCODEC_RESAMPLE
+#define FF_API_AVCODEC_RESAMPLE  (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_LIBMPEG2
+#define FF_API_LIBMPEG2          (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_MMI
+#define FF_API_MMI               (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+
+#endif /* AVCODEC_VERSION_H */
diff --git a/extra_lib/include/libavcodec/xvmc.h b/extra_lib/include/libavcodec/xvmc.h
new file mode 100644 (file)
index 0000000..b2bf518
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2003 Ivan Kalvachev
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_XVMC_H
+#define AVCODEC_XVMC_H
+
+/**
+ * @file
+ * @ingroup lavc_codec_hwaccel_xvmc
+ * Public libavcodec XvMC header.
+ */
+
+#include <X11/extensions/XvMC.h>
+
+#include "avcodec.h"
+
+/**
+ * @defgroup lavc_codec_hwaccel_xvmc XvMC
+ * @ingroup lavc_codec_hwaccel
+ *
+ * @{
+ */
+
+#define AV_XVMC_ID                    0x1DC711C0  /**< special value to ensure that regular pixel routines haven't corrupted the struct
+                                                       the number is 1337 speak for the letters IDCT MCo (motion compensation) */
+
+struct xvmc_pix_fmt {
+    /** The field contains the special constant value AV_XVMC_ID.
+        It is used as a test that the application correctly uses the API,
+        and that there is no corruption caused by pixel routines.
+        - application - set during initialization
+        - libavcodec  - unchanged
+    */
+    int             xvmc_id;
+
+    /** Pointer to the block array allocated by XvMCCreateBlocks().
+        The array has to be freed by XvMCDestroyBlocks().
+        Each group of 64 values represents one data block of differential
+        pixel information (in MoCo mode) or coefficients for IDCT.
+        - application - set the pointer during initialization
+        - libavcodec  - fills coefficients/pixel data into the array
+    */
+    short*          data_blocks;
+
+    /** Pointer to the macroblock description array allocated by
+        XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks().
+        - application - set the pointer during initialization
+        - libavcodec  - fills description data into the array
+    */
+    XvMCMacroBlock* mv_blocks;
+
+    /** Number of macroblock descriptions that can be stored in the mv_blocks
+        array.
+        - application - set during initialization
+        - libavcodec  - unchanged
+    */
+    int             allocated_mv_blocks;
+
+    /** Number of blocks that can be stored at once in the data_blocks array.
+        - application - set during initialization
+        - libavcodec  - unchanged
+    */
+    int             allocated_data_blocks;
+
+    /** Indicate that the hardware would interpret data_blocks as IDCT
+        coefficients and perform IDCT on them.
+        - application - set during initialization
+        - libavcodec  - unchanged
+    */
+    int             idct;
+
+    /** In MoCo mode it indicates that intra macroblocks are assumed to be in
+        unsigned format; same as the XVMC_INTRA_UNSIGNED flag.
+        - application - set during initialization
+        - libavcodec  - unchanged
+    */
+    int             unsigned_intra;
+
+    /** Pointer to the surface allocated by XvMCCreateSurface().
+        It has to be freed by XvMCDestroySurface() on application exit.
+        It identifies the frame and its state on the video hardware.
+        - application - set during initialization
+        - libavcodec  - unchanged
+    */
+    XvMCSurface*    p_surface;
+
+/** Set by the decoder before calling ff_draw_horiz_band(),
+    needed by the XvMCRenderSurface function. */
+//@{
+    /** Pointer to the surface used as past reference
+        - application - unchanged
+        - libavcodec  - set
+    */
+    XvMCSurface*    p_past_surface;
+
+    /** Pointer to the surface used as future reference
+        - application - unchanged
+        - libavcodec  - set
+    */
+    XvMCSurface*    p_future_surface;
+
+    /** top/bottom field or frame
+        - application - unchanged
+        - libavcodec  - set
+    */
+    unsigned int    picture_structure;
+
+    /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence
+        - application - unchanged
+        - libavcodec  - set
+    */
+    unsigned int    flags;
+//}@
+
+    /** Number of macroblock descriptions in the mv_blocks array
+        that have already been passed to the hardware.
+        - application - zeroes it on get_buffer().
+                        A successful ff_draw_horiz_band() may increment it
+                        with filled_mb_block_num or zero both.
+        - libavcodec  - unchanged
+    */
+    int             start_mv_blocks_num;
+
+    /** Number of new macroblock descriptions in the mv_blocks array (after
+        start_mv_blocks_num) that are filled by libavcodec and have to be
+        passed to the hardware.
+        - application - zeroes it on get_buffer() or after successful
+                        ff_draw_horiz_band().
+        - libavcodec  - increment with one of each stored MB
+    */
+    int             filled_mv_blocks_num;
+
+    /** Number of the next free data block; one data block consists of
+        64 short values in the data_blocks array.
+        All blocks before this one have already been claimed by placing their
+        position into the corresponding block description structure field,
+        that are part of the mv_blocks array.
+        - application - zeroes it on get_buffer().
+                        A successful ff_draw_horiz_band() may zero it together
+                        with start_mb_blocks_num.
+        - libavcodec  - each decoded macroblock increases it by the number
+                        of coded blocks it contains.
+    */
+    int             next_free_data_block_num;
+};
+
+/**
+ * @}
+ */
+
+#endif /* AVCODEC_XVMC_H */
index 5c4ddd93d0f827934bb83324b48bdc8bdab0bb60..ba2977144bd27bb1e4c1f751d79e4125245f3f9e 100644 (file)
 #ifndef AVFORMAT_AVFORMAT_H
 #define AVFORMAT_AVFORMAT_H
 
-#define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 33
-#define LIBAVFORMAT_VERSION_MICRO  0
-
-#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
-                                               LIBAVFORMAT_VERSION_MINOR, \
-                                               LIBAVFORMAT_VERSION_MICRO)
-#define LIBAVFORMAT_VERSION     AV_VERSION(LIBAVFORMAT_VERSION_MAJOR,   \
-                                           LIBAVFORMAT_VERSION_MINOR,   \
-                                           LIBAVFORMAT_VERSION_MICRO)
-#define LIBAVFORMAT_BUILD       LIBAVFORMAT_VERSION_INT
-
-#define LIBAVFORMAT_IDENT       "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
+/**
+ * @file
+ * @ingroup libavf
+ * Main libavformat public API header
+ */
 
 /**
- * Returns the LIBAVFORMAT_VERSION_INT constant.
+ * @defgroup libavf I/O and Muxing/Demuxing Library
+ * @{
+ *
+ * Libavformat (lavf) is a library for dealing with various media container
+ * formats. Its main two purposes are demuxing - i.e. splitting a media file
+ * into component streams, and the reverse process of muxing - writing supplied
+ * data in a specified container format. It also has an @ref lavf_io
+ * "I/O module" which supports a number of protocols for accessing the data (e.g.
+ * file, tcp, http and others). Before using lavf, you need to call
+ * av_register_all() to register all compiled muxers, demuxers and protocols.
+ * Unless you are absolutely sure you won't use libavformat's network
+ * capabilities, you should also call avformat_network_init().
+ *
+ * A supported input format is described by an AVInputFormat struct, conversely
+ * an output format is described by AVOutputFormat. You can iterate over all
+ * registered input/output formats using the av_iformat_next() /
+ * av_oformat_next() functions. The protocols layer is not part of the public
+ * API, so you can only get the names of supported protocols with the
+ * avio_enum_protocols() function.
+ *
+ * Main lavf structure used for both muxing and demuxing is AVFormatContext,
+ * which exports all information about the file being read or written. As with
+ * most Libavformat structures, its size is not part of public ABI, so it cannot be
+ * allocated on stack or directly with av_malloc(). To create an
+ * AVFormatContext, use avformat_alloc_context() (some functions, like
+ * avformat_open_input() might do that for you).
+ *
+ * Most importantly an AVFormatContext contains:
+ * @li the @ref AVFormatContext.iformat "input" or @ref AVFormatContext.oformat
+ * "output" format. It is either autodetected or set by user for input;
+ * always set by user for output.
+ * @li an @ref AVFormatContext.streams "array" of AVStreams, which describe all
+ * elementary streams stored in the file. AVStreams are typically referred to
+ * using their index in this array.
+ * @li an @ref AVFormatContext.pb "I/O context". It is either opened by lavf or
+ * set by user for input, always set by user for output (unless you are dealing
+ * with an AVFMT_NOFILE format).
+ *
+ * @section lavf_options Passing options to (de)muxers
+ * Lavf allows to configure muxers and demuxers using the @ref avoptions
+ * mechanism. Generic (format-independent) libavformat options are provided by
+ * AVFormatContext, they can be examined from a user program by calling
+ * av_opt_next() / av_opt_find() on an allocated AVFormatContext (or its AVClass
+ * from avformat_get_class()). Private (format-specific) options are provided by
+ * AVFormatContext.priv_data if and only if AVInputFormat.priv_class /
+ * AVOutputFormat.priv_class of the corresponding format struct is non-NULL.
+ * Further options may be provided by the @ref AVFormatContext.pb "I/O context",
+ * if its AVClass is non-NULL, and the protocols layer. See the discussion on
+ * nesting in @ref avoptions documentation to learn how to access those.
+ *
+ * @defgroup lavf_decoding Demuxing
+ * @{
+ * Demuxers read a media file and split it into chunks of data (@em packets). A
+ * @ref AVPacket "packet" contains one or more encoded frames which belongs to a
+ * single elementary stream. In the lavf API this process is represented by the
+ * avformat_open_input() function for opening a file, av_read_frame() for
+ * reading a single packet and finally avformat_close_input(), which does the
+ * cleanup.
+ *
+ * @section lavf_decoding_open Opening a media file
+ * The minimum information required to open a file is its URL or filename, which
+ * is passed to avformat_open_input(), as in the following code:
+ * @code
+ * const char    *url = "in.mp3";
+ * AVFormatContext *s = NULL;
+ * int ret = avformat_open_input(&s, url, NULL, NULL);
+ * if (ret < 0)
+ *     abort();
+ * @endcode
+ * The above code attempts to allocate an AVFormatContext, open the
+ * specified file (autodetecting the format) and read the header, exporting the
+ * information stored there into s. Some formats do not have a header or do not
+ * store enough information there, so it is recommended that you call the
+ * avformat_find_stream_info() function which tries to read and decode a few
+ * frames to find missing information.
+ *
+ * In some cases you might want to preallocate an AVFormatContext yourself with
+ * avformat_alloc_context() and do some tweaking on it before passing it to
+ * avformat_open_input(). One such case is when you want to use custom functions
+ * for reading input data instead of lavf internal I/O layer.
+ * To do that, create your own AVIOContext with avio_alloc_context(), passing
+ * your reading callbacks to it. Then set the @em pb field of your
+ * AVFormatContext to newly created AVIOContext.
+ *
+ * Since the format of the opened file is in general not known until after
+ * avformat_open_input() has returned, it is not possible to set demuxer private
+ * options on a preallocated context. Instead, the options should be passed to
+ * avformat_open_input() wrapped in an AVDictionary:
+ * @code
+ * AVDictionary *options = NULL;
+ * av_dict_set(&options, "video_size", "640x480", 0);
+ * av_dict_set(&options, "pixel_format", "rgb24", 0);
+ *
+ * if (avformat_open_input(&s, url, NULL, &options) < 0)
+ *     abort();
+ * av_dict_free(&options);
+ * @endcode
+ * This code passes the private options 'video_size' and 'pixel_format' to the
+ * demuxer. They would be necessary for e.g. the rawvideo demuxer, since it
+ * cannot know how to interpret raw video data otherwise. If the format turns
+ * out to be something different than raw video, those options will not be
+ * recognized by the demuxer and therefore will not be applied. Such unrecognized
+ * options are then returned in the options dictionary (recognized options are
+ * consumed). The calling program can handle such unrecognized options as it
+ * wishes, e.g.
+ * @code
+ * AVDictionaryEntry *e;
+ * if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
+ *     fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key);
+ *     abort();
+ * }
+ * @endcode
+ *
+ * After you have finished reading the file, you must close it with
+ * avformat_close_input(). It will free everything associated with the file.
+ *
+ * @section lavf_decoding_read Reading from an opened file
+ * Reading data from an opened AVFormatContext is done by repeatedly calling
+ * av_read_frame() on it. Each call, if successful, will return an AVPacket
+ * containing encoded data for one AVStream, identified by
+ * AVPacket.stream_index. This packet may be passed straight into the libavcodec
+ * decoding functions avcodec_decode_video2(), avcodec_decode_audio4() or
+ * avcodec_decode_subtitle2() if the caller wishes to decode the data.
+ *
+ * AVPacket.pts, AVPacket.dts and AVPacket.duration timing information will be
+ * set if known. They may also be unset (i.e. AV_NOPTS_VALUE for
+ * pts/dts, 0 for duration) if the stream does not provide them. The timing
+ * information will be in AVStream.time_base units, i.e. it has to be
+ * multiplied by the timebase to convert them to seconds.
+ *
+ * The packet data belongs to the demuxer and is invalid after the next call to
+ * av_read_frame(). The user must free the packet with av_free_packet() before
+ * calling av_read_frame() again or closing the file.
+ *
+ * @section lavf_decoding_seek Seeking
+ * @}
+ *
+ * @defgroup lavf_encoding Muxing
+ * @{
+ * @}
+ *
+ * @defgroup lavf_io I/O Read/Write
+ * @{
+ * @}
+ *
+ * @defgroup lavf_codec Demuxers
+ * @{
+ * @defgroup lavf_codec_native Native Demuxers
+ * @{
+ * @}
+ * @defgroup lavf_codec_wrappers External library wrappers
+ * @{
+ * @}
+ * @}
+ * @defgroup lavf_protos I/O Protocols
+ * @{
+ * @}
+ * @defgroup lavf_internal Internal
+ * @{
+ * @}
+ * @}
+ *
  */
-unsigned avformat_version(void);
 
 #include <time.h>
 #include <stdio.h>  /* FILE */
 #include "libavcodec/avcodec.h"
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
 
 #include "avio.h"
+#include "libavformat/version.h"
+
+#if FF_API_AV_GETTIME
+#include "libavutil/time.h"
+#endif
 
 struct AVFormatContext;
 
 
-/*
- * Public Metadata API.
+/**
+ * @defgroup metadata_api Public Metadata API
+ * @{
+ * @ingroup libavf
  * The metadata API allows libavformat to export metadata tags to a client
- * application using a sequence of key/value pairs.
+ * application when demuxing. Conversely it allows a client application to
+ * set metadata when muxing.
+ *
+ * Metadata is exported or set as pairs of key/value strings in the 'metadata'
+ * fields of the AVFormatContext, AVStream, AVChapter and AVProgram structs
+ * using the @ref lavu_dict "AVDictionary" API. Like all strings in FFmpeg,
+ * metadata is assumed to be UTF-8 encoded Unicode. Note that metadata
+ * exported by demuxers isn't checked to be valid UTF-8 in most cases.
+ *
  * Important concepts to keep in mind:
- * 1. Keys are unique; there can never be 2 tags with the same key. This is
+ *  Keys are unique; there can never be 2 tags with the same key. This is
  *    also meant semantically, i.e., a demuxer should not knowingly produce
  *    several keys that are literally different but semantically identical.
  *    E.g., key=Author5, key=Author6. In this example, all authors must be
  *    placed in the same tag.
- * 2. Metadata is flat, not hierarchical; there are no subtags. If you
+ *  Metadata is flat, not hierarchical; there are no subtags. If you
  *    want to store, e.g., the email address of the child of producer Alice
  *    and actor Bob, that could have key=alice_and_bobs_childs_email_address.
- * 3. A tag whose value is localized for a particular language is appended
- *    with a dash character ('-') and the ISO 639-2/B 3-letter language code.
- *    For example: Author-ger=Michael, Author-eng=Mike
- *    The original/default language is in the unqualified "Author" tag.
- *    A demuxer should set a default if it sets any translated tag.
- */
-
-#define AV_METADATA_MATCH_CASE      1
-#define AV_METADATA_IGNORE_SUFFIX   2
-
-typedef struct {
-    char *key;
-    char *value;
-}AVMetadataTag;
-
-typedef struct AVMetadata AVMetadata;
-typedef struct AVMetadataConv AVMetadataConv;
-
-/**
- * Gets a metadata element with matching key.
- * @param prev Set to the previous matching element to find the next.
- * @param flags Allows case as well as suffix-insensitive comparisons.
- * @return Found tag or NULL, changing key or value leads to undefined behavior.
- */
-AVMetadataTag *
-av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags);
-
-/**
- * Sets the given tag in m, overwriting an existing tag.
- * @param key tag key to add to m (will be av_strduped)
- * @param value tag value to add to m (will be av_strduped)
- * @return >= 0 on success otherwise an error code <0
- */
-int av_metadata_set(AVMetadata **pm, const char *key, const char *value);
-
-/**
- * Convert all the metadata sets from ctx according to the source and
- * destination conversion tables.
- * @param d_conv destination tags format conversion table
- * @param s_conv source tags format conversion table
- */
-void av_metadata_conv(struct AVFormatContext *ctx,const AVMetadataConv *d_conv,
-                                                  const AVMetadataConv *s_conv);
-
-/**
- * Frees all the memory allocated for an AVMetadata struct.
+ * -  Several modifiers can be applied to the tag name. This is done by
+ *    appending a dash character ('-') and the modifier name in the order
+ *    they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng.
+ *    -  language -- a tag whose value is localized for a particular language
+ *       is appended with the ISO 639-2/B 3-letter language code.
+ *       For example: Author-ger=Michael, Author-eng=Mike
+ *       The original/default language is in the unqualified "Author" tag.
+ *       A demuxer should set a default if it sets any translated tag.
+ *    -  sorting  -- a modified version of a tag that should be used for
+ *       sorting will have '-sort' appended. E.g. artist="The Beatles",
+ *       artist-sort="Beatles, The".
+ *
+ * -  Demuxers attempt to export metadata in a generic format, however tags
+ *    with no generic equivalents are left as they are stored in the container.
+ *    Follows a list of generic tag names:
+ *
+ @verbatim
+ album        -- name of the set this work belongs to
+ album_artist -- main creator of the set/album, if different from artist.
+                 e.g. "Various Artists" for compilation albums.
+ artist       -- main creator of the work
+ comment      -- any additional description of the file.
+ composer     -- who composed the work, if different from artist.
+ copyright    -- name of copyright holder.
+ creation_time-- date when the file was created, preferably in ISO 8601.
+ date         -- date when the work was created, preferably in ISO 8601.
+ disc         -- number of a subset, e.g. disc in a multi-disc collection.
+ encoder      -- name/settings of the software/hardware that produced the file.
+ encoded_by   -- person/group who created the file.
+ filename     -- original name of the file.
+ genre        -- <self-evident>.
+ language     -- main language in which the work is performed, preferably
+                 in ISO 639-2 format. Multiple languages can be specified by
+                 separating them with commas.
+ performer    -- artist who performed the work, if different from artist.
+                 E.g for "Also sprach Zarathustra", artist would be "Richard
+                 Strauss" and performer "London Philharmonic Orchestra".
+ publisher    -- name of the label/publisher.
+ service_name     -- name of the service in broadcasting (channel name).
+ service_provider -- name of the service provider in broadcasting.
+ title        -- name of the work.
+ track        -- number of this work in the set, can be in form current/total.
+ variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of
+ @endverbatim
+ *
+ * Look in the examples section for an application example how to use the Metadata API.
+ *
+ * @}
  */
-void av_metadata_free(AVMetadata **m);
-
 
 /* packet functions */
 
 
 /**
- * Allocate and read the payload of a packet and initialize its fields with
- * default values.
+ * Allocate and read the payload of a packet and initialize its
+ * fields with default values.
  *
  * @param pkt packet
  * @param size desired payload size
  * @return >0 (read size) if OK, AVERROR_xxx otherwise
  */
-int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size);
+int av_get_packet(AVIOContext *s, AVPacket *pkt, int size);
 
 
+/**
+ * Read data and append it to the current content of the AVPacket.
+ * If pkt->size is 0 this is identical to av_get_packet.
+ * Note that this uses av_grow_packet and thus involves a realloc
+ * which is inefficient. Thus this function should only be used
+ * when there is no reasonable way to know (an upper bound of)
+ * the final size.
+ *
+ * @param pkt packet
+ * @param size amount of data to read
+ * @return >0 (read size) if OK, AVERROR_xxx otherwise, previous data
+ *         will not be lost even if an error occurs.
+ */
+int av_append_packet(AVIOContext *s, AVPacket *pkt, int size);
+
 /*************************************************/
 /* fractional numbers for exact pts handling */
 
@@ -142,39 +326,20 @@ typedef struct AVFrac {
 
 struct AVCodecTag;
 
-/** This structure contains the data a format has to probe a file. */
+/**
+ * This structure contains the data a format has to probe a file.
+ */
 typedef struct AVProbeData {
     const char *filename;
-    unsigned char *buf;
-    int buf_size;
+    unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */
+    int buf_size;       /**< Size of buf except extra allocated bytes */
 } AVProbeData;
 
 #define AVPROBE_SCORE_MAX 100               ///< maximum score, half of that is used for file-extension-based detection
+#define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4)
 #define AVPROBE_PADDING_SIZE 32             ///< extra allocated bytes at the end of the probe buffer
 
-typedef struct AVFormatParameters {
-    AVRational time_base;
-    int sample_rate;
-    int channels;
-    int width;
-    int height;
-    enum PixelFormat pix_fmt;
-    int channel; /**< Used to select DV channel. */
-    const char *standard; /**< TV standard, NTSC, PAL, SECAM */
-    unsigned int mpeg2ts_raw:1;  /**< Force raw MPEG-2 transport stream output, if possible. */
-    unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport
-                                            stream packet (only meaningful if
-                                            mpeg2ts_raw is TRUE). */
-    unsigned int initial_pause:1;       /**< Do not begin to play the stream
-                                            immediately (RTSP only). */
-    unsigned int prealloced_context:1;
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    enum CodecID video_codec_id;
-    enum CodecID audio_codec_id;
-#endif
-} AVFormatParameters;
-
-//! Demuxer will use url_fopen, no opened file should be provided by the caller.
+/// Demuxer will use avio_open, no opened file should be provided by the caller.
 #define AVFMT_NOFILE        0x0001
 #define AVFMT_NEEDNUMBER    0x0002 /**< Needs '%d' in filename. */
 #define AVFMT_SHOW_IDS      0x0008 /**< Show format stream IDs numbers. */
@@ -183,9 +348,29 @@ typedef struct AVFormatParameters {
 #define AVFMT_GLOBALHEADER  0x0040 /**< Format wants global header. */
 #define AVFMT_NOTIMESTAMPS  0x0080 /**< Format does not need / have any timestamps. */
 #define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */
-#define AVFMT_TS_DISCONT    0x0200 /**< Format allows timestamp discontinuities. */
+#define AVFMT_TS_DISCONT    0x0200 /**< Format allows timestamp discontinuities. Note, muxers always require valid (monotone) timestamps */
 #define AVFMT_VARIABLE_FPS  0x0400 /**< Format allows variable fps. */
+#define AVFMT_NODIMENSIONS  0x0800 /**< Format does not need width/height */
+#define AVFMT_NOSTREAMS     0x1000 /**< Format does not require any streams */
+#define AVFMT_NOBINSEARCH   0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
+#define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fallback to generic search */
+#define AVFMT_NO_BYTE_SEEK  0x8000 /**< Format does not allow seeking by bytes */
+#define AVFMT_ALLOW_FLUSH  0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
+#if LIBAVFORMAT_VERSION_MAJOR <= 54
+#define AVFMT_TS_NONSTRICT 0x8020000 //we try to be compatible to the ABIs of ffmpeg and major forks
+#else
+#define AVFMT_TS_NONSTRICT 0x20000
+#endif
+                                   /**< Format does not require strictly
+                                        increasing timestamps, but they must
+                                        still be monotonic */
+
+#define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
 
+/**
+ * @addtogroup lavf_encoding
+ * @{
+ */
 typedef struct AVOutputFormat {
     const char *name;
     /**
@@ -196,69 +381,157 @@ typedef struct AVOutputFormat {
     const char *long_name;
     const char *mime_type;
     const char *extensions; /**< comma-separated filename extensions */
-    /** size of private data so that it can be allocated in the wrapper */
-    int priv_data_size;
     /* output support */
-    enum CodecID audio_codec; /**< default audio codec */
-    enum CodecID video_codec; /**< default video codec */
-    int (*write_header)(struct AVFormatContext *);
-    int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
-    int (*write_trailer)(struct AVFormatContext *);
-    /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */
+    enum AVCodecID audio_codec;    /**< default audio codec */
+    enum AVCodecID video_codec;    /**< default video codec */
+    enum AVCodecID subtitle_codec; /**< default subtitle codec */
+    /**
+     * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE,
+     * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,
+     * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,
+     * AVFMT_TS_NONSTRICT
+     */
     int flags;
-    /** Currently only used to set pixel format if not YUV420P. */
-    int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *);
-    int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,
-                             AVPacket *in, int flush);
 
     /**
      * List of supported codec_id-codec_tag pairs, ordered by "better
-     * choice first". The arrays are all terminated by CODEC_ID_NONE.
+     * choice first". The arrays are all terminated by AV_CODEC_ID_NONE.
      */
     const struct AVCodecTag * const *codec_tag;
 
-    enum CodecID subtitle_codec; /**< default subtitle codec */
 
-    const AVMetadataConv *metadata_conv;
+    const AVClass *priv_class; ///< AVClass for the private context
 
-    /* private fields */
+    /*****************************************************************
+     * No fields below this line are part of the public API. They
+     * may not be used outside of libavformat and can be changed and
+     * removed at will.
+     * New public fields should be added right above.
+     *****************************************************************
+     */
     struct AVOutputFormat *next;
+    /**
+     * size of private data so that it can be allocated in the wrapper
+     */
+    int priv_data_size;
+
+    int (*write_header)(struct AVFormatContext *);
+    /**
+     * Write a packet. If AVFMT_ALLOW_FLUSH is set in flags,
+     * pkt can be NULL in order to flush data buffered in the muxer.
+     * When flushing, return 0 if there still is more data to flush,
+     * or 1 if everything was flushed and there is no more buffered
+     * data.
+     */
+    int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
+    int (*write_trailer)(struct AVFormatContext *);
+    /**
+     * Currently only used to set pixel format if not YUV420P.
+     */
+    int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,
+                             AVPacket *in, int flush);
+    /**
+     * Test if the given codec can be stored in this container.
+     *
+     * @return 1 if the codec is supported, 0 if it is not.
+     *         A negative number if unknown.
+     *         MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC
+     */
+    int (*query_codec)(enum AVCodecID id, int std_compliance);
+
+    void (*get_output_timestamp)(struct AVFormatContext *s, int stream,
+                                 int64_t *dts, int64_t *wall);
 } AVOutputFormat;
+/**
+ * @}
+ */
 
+/**
+ * @addtogroup lavf_decoding
+ * @{
+ */
 typedef struct AVInputFormat {
+    /**
+     * A comma separated list of short names for the format. New names
+     * may be appended with a minor bump.
+     */
     const char *name;
+
     /**
      * Descriptive name for the format, meant to be more human-readable
      * than name. You should use the NULL_IF_CONFIG_SMALL() macro
      * to define it.
      */
     const char *long_name;
-    /** Size of private data so that it can be allocated in the wrapper. */
+
+    /**
+     * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
+     * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
+     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
+     */
+    int flags;
+
+    /**
+     * If extensions are defined, then no probe is done. You should
+     * usually not use extension format guessing because it is not
+     * reliable enough
+     */
+    const char *extensions;
+
+    const struct AVCodecTag * const *codec_tag;
+
+    const AVClass *priv_class; ///< AVClass for the private context
+
+    /*****************************************************************
+     * No fields below this line are part of the public API. They
+     * may not be used outside of libavformat and can be changed and
+     * removed at will.
+     * New public fields should be added right above.
+     *****************************************************************
+     */
+    struct AVInputFormat *next;
+
+    /**
+     * Raw demuxers store their codec ID here.
+     */
+    int raw_codec_id;
+
+    /**
+     * Size of private data so that it can be allocated in the wrapper.
+     */
     int priv_data_size;
+
     /**
      * Tell if a given file has a chance of being parsed as this format.
      * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes
      * big so you do not have to check for that unless you need more.
      */
     int (*read_probe)(AVProbeData *);
-    /** Read the format header and initialize the AVFormatContext
-       structure. Return 0 if OK. 'ap' if non-NULL contains
-       additional parameters. Only used in raw format right
-       now. 'av_new_stream' should be called to create new streams.  */
-    int (*read_header)(struct AVFormatContext *,
-                       AVFormatParameters *ap);
-    /** Read one packet and put it in 'pkt'. pts and flags are also
-       set. 'av_new_stream' can be called only if the flag
-       AVFMTCTX_NOHEADER is used.
-       @return 0 on success, < 0 on error.
-               When returning an error, pkt must not have been allocated
-               or must be freed before returning */
+
+    /**
+     * Read the format header and initialize the AVFormatContext
+     * structure. Return 0 if OK. Only used in raw format right
+     * now. 'avformat_new_stream' should be called to create new streams.
+     */
+    int (*read_header)(struct AVFormatContext *);
+
+    /**
+     * Read one packet and put it in 'pkt'. pts and flags are also
+     * set. 'avformat_new_stream' can be called only if the flag
+     * AVFMTCTX_NOHEADER is used and only in the calling thread (not in a
+     * background thread).
+     * @return 0 on success, < 0 on error.
+     *         When returning an error, pkt must not have been allocated
+     *         or must be freed before returning
+     */
     int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
-    /** Close the stream. The AVFormatContext and AVStreams are not
-       freed by this function */
+
+    /**
+     * Close the stream. The AVFormatContext and AVStreams are not
+     * freed by this function
+     */
     int (*read_close)(struct AVFormatContext *);
 
-#if LIBAVFORMAT_VERSION_MAJOR < 53
     /**
      * Seek to a given timestamp relative to the frames in
      * stream component stream_index.
@@ -269,32 +542,26 @@ typedef struct AVInputFormat {
      */
     int (*read_seek)(struct AVFormatContext *,
                      int stream_index, int64_t timestamp, int flags);
-#endif
+
     /**
-     * Gets the next timestamp in stream[stream_index].time_base units.
+     * Get the next timestamp in stream[stream_index].time_base units.
      * @return the timestamp or AV_NOPTS_VALUE if an error occurred
      */
     int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,
                               int64_t *pos, int64_t pos_limit);
-    /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */
-    int flags;
-    /** If extensions are defined, then no probe is done. You should
-       usually not use extension format guessing because it is not
-       reliable enough */
-    const char *extensions;
-    /** General purpose read-only value that the format can use. */
-    int value;
 
-    /** Start/resume playing - only meaningful if using a network-based format
-       (RTSP). */
+    /**
+     * Start/resume playing - only meaningful if using a network-based format
+     * (RTSP).
+     */
     int (*read_play)(struct AVFormatContext *);
 
-    /** Pause playing - only meaningful if using a network-based format
-       (RTSP). */
+    /**
+     * Pause playing - only meaningful if using a network-based format
+     * (RTSP).
+     */
     int (*read_pause)(struct AVFormatContext *);
 
-    const struct AVCodecTag * const *codec_tag;
-
     /**
      * Seek to timestamp ts.
      * Seeking will be done so that the point from which all active streams
@@ -302,23 +569,30 @@ typedef struct AVInputFormat {
      * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL.
      */
     int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
-
-    const AVMetadataConv *metadata_conv;
-
-    /* private fields */
-    struct AVInputFormat *next;
 } AVInputFormat;
+/**
+ * @}
+ */
 
 enum AVStreamParseType {
     AVSTREAM_PARSE_NONE,
     AVSTREAM_PARSE_FULL,       /**< full parsing and repack */
     AVSTREAM_PARSE_HEADERS,    /**< Only parse headers, do not repack. */
     AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */
+    AVSTREAM_PARSE_FULL_ONCE,  /**< full parsing and repack of the first frame only, only implemented for H.264 currently */
+    AVSTREAM_PARSE_FULL_RAW=MKTAG(0,'R','A','W'),       /**< full parsing and repack with timestamp and position generation by parser for raw
+                                                             this assumes that each packet in the file contains no demuxer level headers and
+                                                             just codec level data, otherwise position generation would fail */
 };
 
 typedef struct AVIndexEntry {
     int64_t pos;
-    int64_t timestamp;
+    int64_t timestamp;        /**<
+                               * Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are available
+                               * when seeking to this entry. That means preferable PTS on keyframe based formats.
+                               * But demuxers can choose to store a different timestamp, if it is more convenient for the implementation or nothing better
+                               * is known
+                               */
 #define AVINDEX_KEYFRAME 0x0001
     int flags:2;
     int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment).
@@ -332,6 +606,23 @@ typedef struct AVIndexEntry {
 #define AV_DISPOSITION_LYRICS    0x0010
 #define AV_DISPOSITION_KARAOKE   0x0020
 
+/**
+ * Track should be used during playback by default.
+ * Useful for subtitle track that should be displayed
+ * even when user did not explicitly ask for subtitles.
+ */
+#define AV_DISPOSITION_FORCED    0x0040
+#define AV_DISPOSITION_HEARING_IMPAIRED  0x0080  /**< stream for hearing impaired audiences */
+#define AV_DISPOSITION_VISUAL_IMPAIRED   0x0100  /**< stream for visual impaired audiences */
+#define AV_DISPOSITION_CLEAN_EFFECTS     0x0200  /**< stream without voice */
+/**
+ * The stream is stored in the file as an attached picture/"cover art" (e.g.
+ * APIC frame in ID3v2). The single packet associated with it will be returned
+ * among the first few packets read from the file unless seeking takes place.
+ * It can also be accessed at any time in AVStream.attached_pic.
+ */
+#define AV_DISPOSITION_ATTACHED_PIC      0x0400
+
 /**
  * Stream structure.
  * New fields can be added to the end with minor version bumps.
@@ -341,8 +632,25 @@ typedef struct AVIndexEntry {
  */
 typedef struct AVStream {
     int index;    /**< stream index in AVFormatContext */
-    int id;       /**< format-specific stream ID */
-    AVCodecContext *codec; /**< codec context */
+    /**
+     * Format-specific stream ID.
+     * decoding: set by libavformat
+     * encoding: set by the user
+     */
+    int id;
+    /**
+     * Codec context associated with this stream. Allocated and freed by
+     * libavformat.
+     *
+     * - decoding: The demuxer exports codec information stored in the headers
+     *             here.
+     * - encoding: The user sets codec information, the muxer writes it to the
+     *             output. Mandatory fields as specified in AVCodecContext
+     *             documentation must be set even if this AVCodecContext is
+     *             not actually used for encoding.
+     */
+    AVCodecContext *codec;
+#if FF_API_R_FRAME_RATE
     /**
      * Real base framerate of the stream.
      * This is the lowest framerate with which all timestamps can be
@@ -352,29 +660,27 @@ typedef struct AVStream {
      * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
      */
     AVRational r_frame_rate;
+#endif
     void *priv_data;
 
-    /* internal data used in av_find_stream_info() */
-    int64_t first_dts;
-    /** encoding: pts generation when outputting stream */
+    /**
+     * encoding: pts generation when outputting stream
+     */
     struct AVFrac pts;
 
     /**
      * This is the fundamental unit of time (in seconds) in terms
-     * of which frame timestamps are represented. For fixed-fps content,
-     * time base should be 1/framerate and timestamp increments should be 1.
+     * of which frame timestamps are represented.
+     *
+     * decoding: set by libavformat
+     * encoding: set by libavformat in avformat_write_header. The muxer may use the
+     * user-provided value of @ref AVCodecContext.time_base "codec->time_base"
+     * as a hint.
      */
     AVRational time_base;
-    int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
-    /* ffmpeg.c private use */
-    int stream_copy; /**< If set, just copy stream. */
-    enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed.
-    //FIXME move stuff to a flags field?
-    /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame.
-     * MN: dunno if that is the right place for it */
-    float quality;
+
     /**
-     * Decoding: pts of the first frame of the stream, in stream time base.
+     * Decoding: pts of the first frame of the stream in presentation order, in stream time base.
      * Only set this if you are absolutely 100% sure that the value you set
      * it to really is the pts of the first frame.
      * This may be undefined (AV_NOPTS_VALUE).
@@ -382,6 +688,7 @@ typedef struct AVStream {
      * demuxer must NOT set this.
      */
     int64_t start_time;
+
     /**
      * Decoding: duration of the stream, in stream time base.
      * If a source file does not specify a duration, but does specify
@@ -389,36 +696,11 @@ typedef struct AVStream {
      */
     int64_t duration;
 
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    char language[4]; /** ISO 639-2/B 3-letter language code (empty string if undefined) */
-#endif
-
-    /* av_read_frame() support */
-    enum AVStreamParseType need_parsing;
-    struct AVCodecParserContext *parser;
-
-    int64_t cur_dts;
-    int last_IP_duration;
-    int64_t last_IP_pts;
-    /* av_seek_frame() support */
-    AVIndexEntry *index_entries; /**< Only used if the format does not
-                                    support seeking natively. */
-    int nb_index_entries;
-    unsigned int index_entries_allocated_size;
-
     int64_t nb_frames;                 ///< number of frames in this stream if known or 0
 
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    int64_t unused[4+1];
-
-    char *filename; /**< source filename of the stream */
-#endif
-
     int disposition; /**< AV_DISPOSITION_* bit field */
 
-    AVProbeData probe_data;
-#define MAX_REORDER_DELAY 16
-    int64_t pts_buffer[MAX_REORDER_DELAY+1];
+    enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed.
 
     /**
      * sample aspect ratio (0 if unknown)
@@ -427,12 +709,54 @@ typedef struct AVStream {
      */
     AVRational sample_aspect_ratio;
 
-    AVMetadata *metadata;
+    AVDictionary *metadata;
 
-    /* av_read_frame() support */
-    const uint8_t *cur_ptr;
-    int cur_len;
-    AVPacket cur_pkt;
+    /**
+     * Average framerate
+     */
+    AVRational avg_frame_rate;
+
+    /**
+     * For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet
+     * will contain the attached picture.
+     *
+     * decoding: set by libavformat, must not be modified by the caller.
+     * encoding: unused
+     */
+    AVPacket attached_pic;
+
+    /*****************************************************************
+     * All fields below this line are not part of the public API. They
+     * may not be used outside of libavformat and can be changed and
+     * removed at will.
+     * New public fields should be added right above.
+     *****************************************************************
+     */
+
+    /**
+     * Stream information used internally by av_find_stream_info()
+     */
+#define MAX_STD_TIMEBASES (60*12+6)
+    struct {
+        int64_t last_dts;
+        int64_t duration_gcd;
+        int duration_count;
+        double duration_error[2][2][MAX_STD_TIMEBASES];
+        int64_t codec_info_duration;
+        int64_t codec_info_duration_fields;
+        int found_decoder;
+
+        /**
+         * Those are used for average framerate estimation.
+         */
+        int64_t fps_first_dts;
+        int     fps_first_dts_idx;
+        int64_t fps_last_dts;
+        int     fps_last_dts_idx;
+
+    } *info;
+
+    int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
 
     // Timestamp generation support:
     /**
@@ -443,6 +767,80 @@ typedef struct AVStream {
      * AV_NOPTS_VALUE by default.
      */
     int64_t reference_dts;
+    int64_t first_dts;
+    int64_t cur_dts;
+    int64_t last_IP_pts;
+    int last_IP_duration;
+
+    /**
+     * Number of packets to buffer for codec probing
+     */
+#define MAX_PROBE_PACKETS 2500
+    int probe_packets;
+
+    /**
+     * Number of frames that have been demuxed during av_find_stream_info()
+     */
+    int codec_info_nb_frames;
+
+    /**
+     * Stream Identifier
+     * This is the MPEG-TS stream identifier +1
+     * 0 means unknown
+     */
+    int stream_identifier;
+
+    int64_t interleaver_chunk_size;
+    int64_t interleaver_chunk_duration;
+
+    /* av_read_frame() support */
+    enum AVStreamParseType need_parsing;
+    struct AVCodecParserContext *parser;
+
+    /**
+     * last packet in packet_buffer for this stream when muxing.
+     */
+    struct AVPacketList *last_in_packet_buffer;
+    AVProbeData probe_data;
+#define MAX_REORDER_DELAY 16
+    int64_t pts_buffer[MAX_REORDER_DELAY+1];
+
+    AVIndexEntry *index_entries; /**< Only used if the format does not
+                                    support seeking natively. */
+    int nb_index_entries;
+    unsigned int index_entries_allocated_size;
+
+    /**
+     * stream probing state
+     * -1   -> probing finished
+     *  0   -> no probing requested
+     * rest -> perform probing with request_probe being the minimum score to accept.
+     * NOT PART OF PUBLIC API
+     */
+    int request_probe;
+    /**
+     * Indicates that everything up to the next keyframe
+     * should be discarded.
+     */
+    int skip_to_keyframe;
+
+    /**
+     * Number of samples to skip at the start of the frame decoded from the next packet.
+     */
+    int skip_samples;
+
+    /**
+     * Number of internally decoded frames, used internally in libavformat, do not access
+     * its lifetime differs from info which is why its not in that structure.
+     */
+    int nb_decoded_frames;
+
+    /**
+     * Timestamp offset added to timestamps before muxing
+     * NOT PART OF PUBLIC API
+     */
+    int64_t mux_ts_offset;
+
 } AVStream;
 
 #define AV_PROGRAM_RUNNING 1
@@ -455,15 +853,15 @@ typedef struct AVStream {
  */
 typedef struct AVProgram {
     int            id;
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    char           *provider_name; ///< network name for DVB streams
-    char           *name;          ///< service name for DVB streams
-#endif
     int            flags;
     enum AVDiscard discard;        ///< selects which program to discard and which to feed to the caller
     unsigned int   *stream_index;
     unsigned int   nb_stream_indexes;
-    AVMetadata *metadata;
+    AVDictionary *metadata;
+
+    int program_num;
+    int pmt_pid;
+    int pcr_pid;
 } AVProgram;
 
 #define AVFMTCTX_NOHEADER      0x0001 /**< signal that no header is present
@@ -473,100 +871,128 @@ typedef struct AVChapter {
     int id;                 ///< unique ID to identify the chapter
     AVRational time_base;   ///< time base in which the start/end timestamps are specified
     int64_t start, end;     ///< chapter start/end time in time_base units
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    char *title;            ///< chapter title
-#endif
-    AVMetadata *metadata;
+    AVDictionary *metadata;
 } AVChapter;
 
-#define MAX_STREAMS 20
+
+/**
+ * The duration of a video can be estimated through various ways, and this enum can be used
+ * to know how the duration was estimated.
+ */
+enum AVDurationEstimationMethod {
+    AVFMT_DURATION_FROM_PTS,    ///< Duration accurately estimated from PTSes
+    AVFMT_DURATION_FROM_STREAM, ///< Duration estimated from a stream with a known duration
+    AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate)
+};
 
 /**
  * Format I/O context.
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
- * sizeof(AVFormatContext) must not be used outside libav*.
+ * sizeof(AVFormatContext) must not be used outside libav*, use
+ * avformat_alloc_context() to create an AVFormatContext.
  */
 typedef struct AVFormatContext {
-    const AVClass *av_class; /**< Set by avformat_alloc_context. */
-    /* Can only be iformat or oformat, not both at the same time. */
+    /**
+     * A class for logging and AVOptions. Set by avformat_alloc_context().
+     * Exports (de)muxer private options if they exist.
+     */
+    const AVClass *av_class;
+
+    /**
+     * Can only be iformat or oformat, not both at the same time.
+     *
+     * decoding: set by avformat_open_input().
+     * encoding: set by the user.
+     */
     struct AVInputFormat *iformat;
     struct AVOutputFormat *oformat;
+
+    /**
+     * Format private data. This is an AVOptions-enabled struct
+     * if and only if iformat/oformat.priv_class is not NULL.
+     */
     void *priv_data;
-    ByteIOContext *pb;
-    unsigned int nb_streams;
-    AVStream *streams[MAX_STREAMS];
-    char filename[1024]; /**< input or output filename */
-    /* stream info */
-    int64_t timestamp;
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    char title[512];
-    char author[512];
-    char copyright[512];
-    char comment[512];
-    char album[512];
-    int year;  /**< ID3 year, 0 if none */
-    int track; /**< track number, 0 if none */
-    char genre[32]; /**< ID3 genre */
-#endif
 
+    /**
+     * I/O context.
+     *
+     * decoding: either set by the user before avformat_open_input() (then
+     * the user must close it manually) or set by avformat_open_input().
+     * encoding: set by the user.
+     *
+     * Do NOT set this field if AVFMT_NOFILE flag is set in
+     * iformat/oformat.flags. In such a case, the (de)muxer will handle
+     * I/O in some other way and this field will be NULL.
+     */
+    AVIOContext *pb;
+
+    /* stream info */
     int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */
-    /* private data for pts handling (do not modify directly). */
-    /** This buffer is only needed when packets were already buffered but
-       not decoded, for example to get the codec parameters in MPEG
-       streams. */
-    struct AVPacketList *packet_buffer;
 
-    /** Decoding: position of the first frame of the component, in
-       AV_TIME_BASE fractional seconds. NEVER set this value directly:
-       It is deduced from the AVStream values.  */
+    /**
+     * A list of all streams in the file. New streams are created with
+     * avformat_new_stream().
+     *
+     * decoding: streams are created by libavformat in avformat_open_input().
+     * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also
+     * appear in av_read_frame().
+     * encoding: streams are created by the user before avformat_write_header().
+     */
+    unsigned int nb_streams;
+    AVStream **streams;
+
+    char filename[1024]; /**< input or output filename */
+
+    /**
+     * Decoding: position of the first frame of the component, in
+     * AV_TIME_BASE fractional seconds. NEVER set this value directly:
+     * It is deduced from the AVStream values.
+     */
     int64_t start_time;
-    /** Decoding: duration of the stream, in AV_TIME_BASE fractional
-       seconds. NEVER set this value directly: it is deduced from the
-       AVStream values.  */
-    int64_t duration;
-    /** decoding: total file size, 0 if unknown */
-    int64_t file_size;
-    /** Decoding: total stream bitrate in bit/s, 0 if not
-       available. Never set it directly if the file_size and the
-       duration are known as FFmpeg can compute it automatically. */
-    int bit_rate;
 
-    /* av_read_frame() support */
-    AVStream *cur_st;
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-    const uint8_t *cur_ptr_deprecated;
-    int cur_len_deprecated;
-    AVPacket cur_pkt_deprecated;
-#endif
+    /**
+     * Decoding: duration of the stream, in AV_TIME_BASE fractional
+     * seconds. Only set this value if you know none of the individual stream
+     * durations and also do not set any of them. This is deduced from the
+     * AVStream values if not set.
+     */
+    int64_t duration;
 
-    /* av_seek_frame() support */
-    int64_t data_offset; /** offset of the first packet */
-    int index_built;
+    /**
+     * Decoding: total stream bitrate in bit/s, 0 if not
+     * available. Never set it directly if the file_size and the
+     * duration are known as FFmpeg can compute it automatically.
+     */
+    int bit_rate;
 
-    int mux_rate;
-    int packet_size;
-    int preload;
+    unsigned int packet_size;
     int max_delay;
 
-#define AVFMT_NOOUTPUTLOOP -1
-#define AVFMT_INFINITEOUTPUTLOOP 0
-    /** number of times to loop output in formats that support it */
-    int loop_output;
-
     int flags;
 #define AVFMT_FLAG_GENPTS       0x0001 ///< Generate missing pts even if it requires parsing future frames.
 #define AVFMT_FLAG_IGNIDX       0x0002 ///< Ignore index.
 #define AVFMT_FLAG_NONBLOCK     0x0004 ///< Do not block when reading packets from input.
+#define AVFMT_FLAG_IGNDTS       0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
+#define AVFMT_FLAG_NOFILLIN     0x0010 ///< Do not infer any values from other values, just return what is stored in the container
+#define AVFMT_FLAG_NOPARSE      0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
+#define AVFMT_FLAG_NOBUFFER     0x0040 ///< Do not buffer frames when possible
+#define AVFMT_FLAG_CUSTOM_IO    0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
+#define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< Discard frames marked corrupted
+#define AVFMT_FLAG_MP4A_LATM    0x8000 ///< Enable RTP MP4A-LATM payload
+#define AVFMT_FLAG_SORT_DTS    0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
+#define AVFMT_FLAG_PRIV_OPT    0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
+#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate.
 
-    int loop_input;
-    /** decoding: size of data to probe; encoding: unused. */
+    /**
+     * decoding: size of data to probe; encoding: unused.
+     */
     unsigned int probesize;
 
     /**
-     * Maximum time (in AV_TIME_BASE units) during which the input should
-     * be analyzed in av_find_stream_info().
+     * decoding: maximum time (in AV_TIME_BASE units) during which the input should
+     * be analyzed in avformat_find_stream_info().
      */
     int max_analyze_duration;
 
@@ -580,17 +1006,19 @@ typedef struct AVFormatContext {
      * Forced video codec_id.
      * Demuxing: Set by user.
      */
-    enum CodecID video_codec_id;
+    enum AVCodecID video_codec_id;
+
     /**
      * Forced audio codec_id.
      * Demuxing: Set by user.
      */
-    enum CodecID audio_codec_id;
+    enum AVCodecID audio_codec_id;
+
     /**
      * Forced subtitle codec_id.
      * Demuxing: Set by user.
      */
-    enum CodecID subtitle_codec_id;
+    enum AVCodecID subtitle_codec_id;
 
     /**
      * Maximum amount of memory in bytes to use for the index of each stream.
@@ -613,12 +1041,130 @@ typedef struct AVFormatContext {
     unsigned int nb_chapters;
     AVChapter **chapters;
 
+    AVDictionary *metadata;
+
+    /**
+     * Start time of the stream in real world time, in microseconds
+     * since the unix epoch (00:00 1st January 1970). That is, pts=0
+     * in the stream was captured at this real world time.
+     * - encoding: Set by user.
+     * - decoding: Unused.
+     */
+    int64_t start_time_realtime;
+
+    /**
+     * decoding: number of frames used to probe fps
+     */
+    int fps_probe_size;
+
+    /**
+     * Error recognition; higher values will detect more errors but may
+     * misdetect some more or less valid parts as errors.
+     * - encoding: unused
+     * - decoding: Set by user.
+     */
+    int error_recognition;
+
+    /**
+     * Custom interrupt callbacks for the I/O layer.
+     *
+     * decoding: set by the user before avformat_open_input().
+     * encoding: set by the user before avformat_write_header()
+     * (mainly useful for AVFMT_NOFILE formats). The callback
+     * should also be passed to avio_open2() if it's used to
+     * open the file.
+     */
+    AVIOInterruptCB interrupt_callback;
+
     /**
      * Flags to enable debugging.
      */
     int debug;
 #define FF_FDEBUG_TS        0x0001
 
+    /**
+     * Transport stream id.
+     * This will be moved into demuxer private options. Thus no API/ABI compatibility
+     */
+    int ts_id;
+
+    /**
+     * Audio preload in microseconds.
+     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int audio_preload;
+
+    /**
+     * Max chunk time in microseconds.
+     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int max_chunk_duration;
+
+    /**
+     * Max chunk size in bytes
+     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int max_chunk_size;
+
+    /**
+     * forces the use of wallclock timestamps as pts/dts of packets
+     * This has undefined results in the presence of B frames.
+     * - encoding: unused
+     * - decoding: Set by user via AVOptions (NO direct access)
+     */
+    int use_wallclock_as_timestamps;
+
+    /**
+     * Avoids negative timestamps during muxing
+     *  0 -> allow negative timestamps
+     *  1 -> avoid negative timestamps
+     * -1 -> choose automatically (default)
+     * Note, this is only works when interleave_packet_per_dts is in use
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int avoid_negative_ts;
+
+    /**
+     * avio flags, used to force AVIO_FLAG_DIRECT.
+     * - encoding: unused
+     * - decoding: Set by user via AVOptions (NO direct access)
+     */
+    int avio_flags;
+
+    /**
+     * The duration field can be estimated through various ways, and this field can be used
+     * to know how the duration was estimated.
+     * - encoding: unused
+     * - decoding: Read by user via AVOptions (NO direct access)
+     */
+    enum AVDurationEstimationMethod duration_estimation_method;
+
+    /*****************************************************************
+     * All fields below this line are not part of the public API. They
+     * may not be used outside of libavformat and can be changed and
+     * removed at will.
+     * New public fields should be added right above.
+     *****************************************************************
+     */
+
+    /**
+     * This buffer is only needed when packets were already buffered but
+     * not decoded, for example to get the codec parameters in MPEG
+     * streams.
+     */
+    struct AVPacketList *packet_buffer;
+    struct AVPacketList *packet_buffer_end;
+
+    /* av_seek_frame() support */
+    int64_t data_offset; /**< offset of the first packet */
+
     /**
      * Raw packets from the demuxer, prior to parsing and decoding.
      * This buffer is used for buffering packets until the codec can
@@ -627,21 +1173,83 @@ typedef struct AVFormatContext {
      */
     struct AVPacketList *raw_packet_buffer;
     struct AVPacketList *raw_packet_buffer_end;
-
-    struct AVPacketList *packet_buffer_end;
-
-    AVMetadata *metadata;
+    /**
+     * Packets split by the parser get queued here.
+     */
+    struct AVPacketList *parse_queue;
+    struct AVPacketList *parse_queue_end;
+    /**
+     * Remaining size available for raw_packet_buffer, in bytes.
+     */
+#define RAW_PACKET_BUFFER_SIZE 2500000
+    int raw_packet_buffer_remaining_size;
 } AVFormatContext;
 
+/**
+ * Returns the method used to set ctx->duration.
+ *
+ * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE.
+ */
+enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx);
+
 typedef struct AVPacketList {
     AVPacket pkt;
     struct AVPacketList *next;
 } AVPacketList;
 
-#if LIBAVFORMAT_VERSION_INT < (53<<16)
-extern AVInputFormat *first_iformat;
-extern AVOutputFormat *first_oformat;
-#endif
+
+/**
+ * @defgroup lavf_core Core functions
+ * @ingroup libavf
+ *
+ * Functions for querying libavformat capabilities, allocating core structures,
+ * etc.
+ * @{
+ */
+
+/**
+ * Return the LIBAVFORMAT_VERSION_INT constant.
+ */
+unsigned avformat_version(void);
+
+/**
+ * Return the libavformat build-time configuration.
+ */
+const char *avformat_configuration(void);
+
+/**
+ * Return the libavformat license.
+ */
+const char *avformat_license(void);
+
+/**
+ * Initialize libavformat and register all the muxers, demuxers and
+ * protocols. If you do not call this function, then you can select
+ * exactly which formats you want to support.
+ *
+ * @see av_register_input_format()
+ * @see av_register_output_format()
+ * @see av_register_protocol()
+ */
+void av_register_all(void);
+
+void av_register_input_format(AVInputFormat *format);
+void av_register_output_format(AVOutputFormat *format);
+
+/**
+ * Do global initialization of network components. This is optional,
+ * but recommended, since it avoids the overhead of implicitly
+ * doing the setup for each session.
+ *
+ * Calling this function will become mandatory if using network
+ * protocols at some major version bump.
+ */
+int avformat_network_init(void);
+
+/**
+ * Undo the initialization done by avformat_network_init.
+ */
+int avformat_network_deinit(void);
 
 /**
  * If f is NULL, returns the first registered input format,
@@ -657,98 +1265,98 @@ AVInputFormat  *av_iformat_next(AVInputFormat  *f);
  */
 AVOutputFormat *av_oformat_next(AVOutputFormat *f);
 
-enum CodecID av_guess_image2_codec(const char *filename);
-
-/* XXX: Use automatic init with either ELF sections or C file parser */
-/* modules. */
-
-/* utils.c */
-void av_register_input_format(AVInputFormat *format);
-void av_register_output_format(AVOutputFormat *format);
-AVOutputFormat *guess_stream_format(const char *short_name,
-                                    const char *filename,
-                                    const char *mime_type);
-AVOutputFormat *guess_format(const char *short_name,
-                             const char *filename,
-                             const char *mime_type);
-
 /**
- * Guesses the codec ID based upon muxer and filename.
+ * Allocate an AVFormatContext.
+ * avformat_free_context() can be used to free the context and everything
+ * allocated by the framework within it.
  */
-enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
-                            const char *filename, const char *mime_type,
-                            enum CodecType type);
+AVFormatContext *avformat_alloc_context(void);
 
 /**
- * Send a nice hexadecimal dump of a buffer to the specified file stream.
- *
- * @param f The file stream pointer where the dump should be sent to.
- * @param buf buffer
- * @param size buffer size
+ * Free an AVFormatContext and all its streams.
+ * @param s context to free
+ */
+void avformat_free_context(AVFormatContext *s);
+
+/**
+ * Get the AVClass for AVFormatContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
  *
- * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log
+ * @see av_opt_find().
  */
-void av_hex_dump(FILE *f, uint8_t *buf, int size);
+const AVClass *avformat_get_class(void);
 
 /**
- * Send a nice hexadecimal dump of a buffer to the log.
+ * Add a new stream to a media file.
  *
- * @param avcl A pointer to an arbitrary struct of which the first field is a
- * pointer to an AVClass struct.
- * @param level The importance level of the message, lower values signifying
- * higher importance.
- * @param buf buffer
- * @param size buffer size
+ * When demuxing, it is called by the demuxer in read_header(). If the
+ * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also
+ * be called in read_packet().
+ *
+ * When muxing, should be called by the user before avformat_write_header().
  *
- * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log
+ * @param c If non-NULL, the AVCodecContext corresponding to the new stream
+ * will be initialized to use this codec. This is needed for e.g. codec-specific
+ * defaults to be set, so codec should be provided if it is known.
+ *
+ * @return newly created stream or NULL on error.
  */
-void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size);
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c);
+
+AVProgram *av_new_program(AVFormatContext *s, int id);
 
 /**
- * Send a nice dump of a packet to the specified file stream.
- *
- * @param f The file stream pointer where the dump should be sent to.
- * @param pkt packet to dump
- * @param dump_payload True if the payload must be displayed, too.
+ * @}
  */
-void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
 
+
+#if FF_API_PKT_DUMP
+attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
+attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
+                                          int dump_payload);
+#endif
+
+#if FF_API_ALLOC_OUTPUT_CONTEXT
 /**
- * Send a nice dump of a packet to the log.
- *
- * @param avcl A pointer to an arbitrary struct of which the first field is a
- * pointer to an AVClass struct.
- * @param level The importance level of the message, lower values signifying
- * higher importance.
- * @param pkt packet to dump
- * @param dump_payload True if the payload must be displayed, too.
+ * @deprecated deprecated in favor of avformat_alloc_output_context2()
  */
-void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload);
+attribute_deprecated
+AVFormatContext *avformat_alloc_output_context(const char *format,
+                                               AVOutputFormat *oformat,
+                                               const char *filename);
+#endif
 
 /**
- * Initialize libavformat and register all the muxers, demuxers and
- * protocols. If you do not call this function, then you can select
- * exactly which formats you want to support.
+ * Allocate an AVFormatContext for an output format.
+ * avformat_free_context() can be used to free the context and
+ * everything allocated by the framework within it.
  *
- * @see av_register_input_format()
- * @see av_register_output_format()
- * @see av_register_protocol()
+ * @param *ctx is set to the created format context, or to NULL in
+ * case of failure
+ * @param oformat format to use for allocating the context, if NULL
+ * format_name and filename are used instead
+ * @param format_name the name of output format to use for allocating the
+ * context, if NULL filename is used instead
+ * @param filename the name of the filename to use for allocating the
+ * context, may be NULL
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ * failure
  */
-void av_register_all(void);
-
-/** codec tag <-> codec id */
-enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
-unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id);
+int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat,
+                                   const char *format_name, const char *filename);
 
-/* media file input */
+/**
+ * @addtogroup lavf_decoding
+ * @{
+ */
 
 /**
- * Finds AVInputFormat based on the short name of the input format.
+ * Find AVInputFormat based on the short name of the input format.
  */
 AVInputFormat *av_find_input_format(const char *short_name);
 
 /**
- * Guess file format.
+ * Guess the file format.
  *
  * @param is_opened Whether the file is already opened; determines whether
  *                  demuxers with or without AVFMT_NOFILE are probed.
@@ -756,44 +1364,71 @@ AVInputFormat *av_find_input_format(const char *short_name);
 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
 
 /**
- * Allocates all the structures needed to read an input stream.
- *        This does not open the needed codecs for decoding the stream[s].
+ * Guess the file format.
+ *
+ * @param is_opened Whether the file is already opened; determines whether
+ *                  demuxers with or without AVFMT_NOFILE are probed.
+ * @param score_max A probe score larger that this is required to accept a
+ *                  detection, the variable is set to the actual detection
+ *                  score afterwards.
+ *                  If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended
+ *                  to retry with a larger probe buffer.
  */
-int av_open_input_stream(AVFormatContext **ic_ptr,
-                         ByteIOContext *pb, const char *filename,
-                         AVInputFormat *fmt, AVFormatParameters *ap);
+AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
 
 /**
- * Open a media file as input. The codecs are not opened. Only the file
- * header (if present) is read.
+ * Guess the file format.
  *
- * @param ic_ptr The opened media file handle is put here.
- * @param filename filename to open
- * @param fmt If non-NULL, force the file format to use.
- * @param buf_size optional buffer size (zero if default is OK)
- * @param ap Additional parameters needed when opening the file
- *           (NULL if default).
- * @return 0 if OK, AVERROR_xxx otherwise
+ * @param is_opened Whether the file is already opened; determines whether
+ *                  demuxers with or without AVFMT_NOFILE are probed.
+ * @param score_ret The score of the best detection.
  */
-int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
-                       AVInputFormat *fmt,
-                       int buf_size,
-                       AVFormatParameters *ap);
+AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret);
 
-#if LIBAVFORMAT_VERSION_MAJOR < 53
 /**
- * @deprecated Use avformat_alloc_context() instead.
+ * Probe a bytestream to determine the input format. Each time a probe returns
+ * with a score that is too low, the probe buffer size is increased and another
+ * attempt is made. When the maximum probe size is reached, the input format
+ * with the highest score is returned.
+ *
+ * @param pb the bytestream to probe
+ * @param fmt the input format is put here
+ * @param filename the filename of the stream
+ * @param logctx the log context
+ * @param offset the offset within the bytestream to probe from
+ * @param max_probe_size the maximum probe buffer size (zero for default)
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code otherwise
  */
-attribute_deprecated AVFormatContext *av_alloc_format_context(void);
-#endif
+int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
+                          const char *filename, void *logctx,
+                          unsigned int offset, unsigned int max_probe_size);
 
 /**
- * Allocate an AVFormatContext.
- * Can be freed with av_free() but do not forget to free everything you
- * explicitly allocated as well!
+ * Open an input stream and read the header. The codecs are not opened.
+ * The stream must be closed with av_close_input_file().
+ *
+ * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
+ *           May be a pointer to NULL, in which case an AVFormatContext is allocated by this
+ *           function and written into ps.
+ *           Note that a user-supplied AVFormatContext will be freed on failure.
+ * @param filename Name of the stream to open.
+ * @param fmt If non-NULL, this parameter forces a specific input format.
+ *            Otherwise the format is autodetected.
+ * @param options  A dictionary filled with AVFormatContext and demuxer-private options.
+ *                 On return this parameter will be destroyed and replaced with a dict containing
+ *                 options that were not found. May be NULL.
+ *
+ * @return 0 on success, a negative AVERROR on failure.
+ *
+ * @note If you want to use custom IO, preallocate the format context and set its pb field.
  */
-AVFormatContext *avformat_alloc_context(void);
+int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
 
+attribute_deprecated
+int av_demuxer_open(AVFormatContext *ic);
+
+#if FF_API_FORMAT_PARAMETERS
 /**
  * Read packets of a media file to get stream information. This
  * is useful for file formats with no headers such as MPEG. This
@@ -806,10 +1441,84 @@ AVFormatContext *avformat_alloc_context(void);
  * @return >=0 if OK, AVERROR_xxx on error
  * @todo Let the user decide somehow what information is needed so that
  *       we do not waste time getting stuff the user does not need.
+ *
+ * @deprecated use avformat_find_stream_info.
  */
+attribute_deprecated
 int av_find_stream_info(AVFormatContext *ic);
+#endif
+
+/**
+ * Read packets of a media file to get stream information. This
+ * is useful for file formats with no headers such as MPEG. This
+ * function also computes the real framerate in case of MPEG-2 repeat
+ * frame mode.
+ * The logical file position is not changed by this function;
+ * examined packets may be buffered for later processing.
+ *
+ * @param ic media file handle
+ * @param options  If non-NULL, an ic.nb_streams long array of pointers to
+ *                 dictionaries, where i-th member contains options for
+ *                 codec corresponding to i-th stream.
+ *                 On return each dictionary will be filled with options that were not found.
+ * @return >=0 if OK, AVERROR_xxx on error
+ *
+ * @note this function isn't guaranteed to open all the codecs, so
+ *       options being non-empty at return is a perfectly normal behavior.
+ *
+ * @todo Let the user decide somehow what information is needed so that
+ *       we do not waste time getting stuff the user does not need.
+ */
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
+
+/**
+ * Find the programs which belong to a given stream.
+ *
+ * @param ic    media file handle
+ * @param last  the last found program, the search will start after this
+ *              program, or from the beginning if it is NULL
+ * @param s     stream index
+ * @return the next program which belongs to s, NULL if no program is found or
+ *         the last program is not among the programs of ic.
+ */
+AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s);
 
 /**
+ * Find the "best" stream in the file.
+ * The best stream is determined according to various heuristics as the most
+ * likely to be what the user expects.
+ * If the decoder parameter is non-NULL, av_find_best_stream will find the
+ * default decoder for the stream's codec; streams for which no decoder can
+ * be found are ignored.
+ *
+ * @param ic                media file handle
+ * @param type              stream type: video, audio, subtitles, etc.
+ * @param wanted_stream_nb  user-requested stream number,
+ *                          or -1 for automatic selection
+ * @param related_stream    try to find a stream related (eg. in the same
+ *                          program) to this one, or -1 if none
+ * @param decoder_ret       if non-NULL, returns the decoder for the
+ *                          selected stream
+ * @param flags             flags; none are currently defined
+ * @return  the non-negative stream number in case of success,
+ *          AVERROR_STREAM_NOT_FOUND if no stream with the requested type
+ *          could be found,
+ *          AVERROR_DECODER_NOT_FOUND if streams were found but no decoder
+ * @note  If av_find_best_stream returns successfully and decoder_ret is not
+ *        NULL, then *decoder_ret is guaranteed to be set to a valid AVCodec.
+ */
+int av_find_best_stream(AVFormatContext *ic,
+                        enum AVMediaType type,
+                        int wanted_stream_nb,
+                        int related_stream,
+                        AVCodec **decoder_ret,
+                        int flags);
+
+#if FF_API_READ_PACKET
+/**
+ * @deprecated use AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE to read raw
+ * unprocessed packets
+ *
  * Read a transport packet from a media file.
  *
  * This function is obsolete and should never be used.
@@ -819,10 +1528,17 @@ int av_find_stream_info(AVFormatContext *ic);
  * @param pkt is filled
  * @return 0 if OK, AVERROR_xxx on error
  */
+attribute_deprecated
 int av_read_packet(AVFormatContext *s, AVPacket *pkt);
+#endif
 
 /**
  * Return the next frame of a stream.
+ * This function returns what is stored in the file, and does not validate
+ * that what is there are valid frames for the decoder. It will split what is
+ * stored in the file into frames and return one for each call. It will not
+ * omit invalid data between valid frames so as to give the decoder the maximum
+ * information possible for decoding.
  *
  * The returned packet is valid
  * until the next av_read_frame() or until av_close_input_file() and
@@ -876,9 +1592,9 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
  * @param ts target timestamp
  * @param max_ts largest acceptable timestamp
  * @param flags flags
- * @returns >=0 on success, error code otherwise
+ * @return >=0 on success, error code otherwise
  *
- * @NOTE This is part of the new seek API which is still under construction.
+ * @note This is part of the new seek API which is still under construction.
  *       Thus do not use this yet. It may change at any time, do not expect
  *       ABI compatibility yet!
  */
@@ -897,19 +1613,27 @@ int av_read_play(AVFormatContext *s);
  */
 int av_read_pause(AVFormatContext *s);
 
+#if FF_API_CLOSE_INPUT_FILE
 /**
- * Free a AVFormatContext allocated by av_open_input_stream.
- * @param s context to free
- */
-void av_close_input_stream(AVFormatContext *s);
-
-/**
+ * @deprecated use avformat_close_input()
  * Close a media file (but not its codecs).
  *
  * @param s media file handle
  */
+attribute_deprecated
 void av_close_input_file(AVFormatContext *s);
+#endif
+
+/**
+ * Close an opened input AVFormatContext. Free it and all its contents
+ * and set *s to NULL.
+ */
+void avformat_close_input(AVFormatContext **s);
+/**
+ * @}
+ */
 
+#if FF_API_NEW_STREAM
 /**
  * Add a new stream to a media file.
  *
@@ -920,117 +1644,44 @@ void av_close_input_file(AVFormatContext *s);
  * @param s media file handle
  * @param id file-format-dependent stream ID
  */
+attribute_deprecated
 AVStream *av_new_stream(AVFormatContext *s, int id);
-AVProgram *av_new_program(AVFormatContext *s, int id);
-
-/**
- * Add a new chapter.
- * This function is NOT part of the public API
- * and should ONLY be used by demuxers.
- *
- * @param s media file handle
- * @param id unique ID for this chapter
- * @param start chapter start time in time_base units
- * @param end chapter end time in time_base units
- * @param title chapter title
- *
- * @return AVChapter or NULL on error
- */
-AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base,
-                          int64_t start, int64_t end, const char *title);
+#endif
 
+#if FF_API_SET_PTS_INFO
 /**
- * Set the pts for a given stream.
- *
- * @param s stream
- * @param pts_wrap_bits number of bits effectively used by the pts
- *        (used for wrap control, 33 is the value for MPEG)
- * @param pts_num numerator to convert to seconds (MPEG: 1)
- * @param pts_den denominator to convert to seconds (MPEG: 90000)
+ * @deprecated this function is not supposed to be called outside of lavf
  */
+attribute_deprecated
 void av_set_pts_info(AVStream *s, int pts_wrap_bits,
-                     int pts_num, int pts_den);
+                     unsigned int pts_num, unsigned int pts_den);
+#endif
 
 #define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
 #define AVSEEK_FLAG_BYTE     2 ///< seeking based on position in bytes
 #define AVSEEK_FLAG_ANY      4 ///< seek to any frame, even non-keyframes
-
-int av_find_default_stream_index(AVFormatContext *s);
-
-/**
- * Gets the index for a specific timestamp.
- * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond
- *                 to the timestamp which is <= the requested one, if backward
- *                 is 0, then it will be >=
- *              if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
- * @return < 0 if no such timestamp could be found
- */
-int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
+#define AVSEEK_FLAG_FRAME    8 ///< seeking based on frame number
 
 /**
- * Ensures the index uses less memory than the maximum specified in
- * AVFormatContext.max_index_size by discarding entries if it grows
- * too large.
- * This function is not part of the public API and should only be called
- * by demuxers.
+ * @addtogroup lavf_encoding
+ * @{
  */
-void ff_reduce_index(AVFormatContext *s, int stream_index);
-
 /**
- * Add an index entry into a sorted list. Update the entry if the list
- * already contains it.
+ * Allocate the stream private data and write the stream header to
+ * an output media file.
  *
- * @param timestamp timestamp in the time base of the given stream
- */
-int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
-                       int size, int distance, int flags);
-
-/**
- * Does a binary search using av_index_search_timestamp() and
- * AVCodec.read_timestamp().
- * This is not supposed to be called directly by a user application,
- * but by demuxers.
- * @param target_ts target timestamp in the time base of the given stream
- * @param stream_index stream number
- */
-int av_seek_frame_binary(AVFormatContext *s, int stream_index,
-                         int64_t target_ts, int flags);
-
-/**
- * Updates cur_dts of all streams based on the given timestamp and AVStream.
+ * @param s Media file handle, must be allocated with avformat_alloc_context().
+ *          Its oformat field must be set to the desired output format;
+ *          Its pb field must be set to an already openened AVIOContext.
+ * @param options  An AVDictionary filled with AVFormatContext and muxer-private options.
+ *                 On return this parameter will be destroyed and replaced with a dict containing
+ *                 options that were not found. May be NULL.
  *
- * Stream ref_st unchanged, others set cur_dts in their native time base.
- * Only needed for timestamp wrapping or if (dts not set and pts!=dts).
- * @param timestamp new dts expressed in time_base of param ref_st
- * @param ref_st reference stream giving time_base of param timestamp
- */
-void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
-
-/**
- * Does a binary search using read_timestamp().
- * This is not supposed to be called directly by a user application,
- * but by demuxers.
- * @param target_ts target timestamp in the time base of the given stream
- * @param stream_index stream number
- */
-int64_t av_gen_search(AVFormatContext *s, int stream_index,
-                      int64_t target_ts, int64_t pos_min,
-                      int64_t pos_max, int64_t pos_limit,
-                      int64_t ts_min, int64_t ts_max,
-                      int flags, int64_t *ts_ret,
-                      int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
-
-/** media file output */
-int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
-
-/**
- * Allocate the stream private data and write the stream header to an
- * output media file.
+ * @return 0 on success, negative AVERROR on failure.
  *
- * @param s media file handle
- * @return 0 if OK, AVERROR_xxx on error
+ * @see av_opt_find, av_dict_set, avio_open, av_oformat_next.
  */
-int av_write_header(AVFormatContext *s);
+int avformat_write_header(AVFormatContext *s, AVDictionary **options);
 
 /**
  * Write a packet to an output media file.
@@ -1041,13 +1692,17 @@ int av_write_header(AVFormatContext *s);
  *
  * @param s media file handle
  * @param pkt The packet, which contains the stream_index, buf/buf_size,
-              dts/pts, ...
- * @return < 0 on error, = 0 if OK, 1 if end of stream wanted
+ *            dts/pts, ...
+ *            This can be NULL (at any time, not just at the end), in
+ *            order to immediately flush data buffered within the muxer,
+ *            for muxers that buffer up data internally before writing it
+ *            to the output.
+ * @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush
  */
 int av_write_frame(AVFormatContext *s, AVPacket *pkt);
 
 /**
- * Writes a packet to an output media file ensuring correct interleaving.
+ * Write a packet to an output media file ensuring correct interleaving.
  *
  * The packet must contain one audio or video frame.
  * If the packets are already correctly interleaved, the application should
@@ -1057,109 +1712,224 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt);
  * demuxer level.
  *
  * @param s media file handle
- * @param pkt The packet, which contains the stream_index, buf/buf_size,
-              dts/pts, ...
- * @return < 0 on error, = 0 if OK, 1 if end of stream wanted
+ * @param pkt The packet containing the data to be written. Libavformat takes
+ * ownership of the data and will free it when it sees fit using the packet's
+ * This can be NULL (at any time, not just at the end), to flush the
+ * interleaving queues.
+ * @ref AVPacket.destruct "destruct" field. The caller must not access the data
+ * after this function returns, as it may already be freed.
+ * Packet's @ref AVPacket.stream_index "stream_index" field must be set to the
+ * index of the corresponding stream in @ref AVFormatContext.streams
+ * "s.streams".
+ * It is very strongly recommended that timing information (@ref AVPacket.pts
+ * "pts", @ref AVPacket.dts "dts" @ref AVPacket.duration "duration") is set to
+ * correct values.
+ *
+ * @return 0 on success, a negative AVERROR on error.
  */
 int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
 
+#if FF_API_INTERLEAVE_PACKET
 /**
- * Interleave a packet per dts in an output media file.
- *
- * Packets with pkt->destruct == av_destruct_packet will be freed inside this
- * function, so they cannot be used after it. Note that calling av_free_packet()
- * on them is still safe.
- *
- * @param s media file handle
- * @param out the interleaved packet will be output here
- * @param in the input packet
- * @param flush 1 if no further packets are available as input and all
- *              remaining packets should be output
- * @return 1 if a packet was output, 0 if no packet could be output,
- *         < 0 if an error occurred
+ * @deprecated this function was never meant to be called by the user
+ * programs.
  */
+attribute_deprecated
 int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
                                  AVPacket *pkt, int flush);
+#endif
 
 /**
- * @brief Write the stream trailer to an output media file and
- *        free the file private data.
+ * Write the stream trailer to an output media file and free the
+ * file private data.
  *
- * May only be called after a successful call to av_write_header.
+ * May only be called after a successful call to avformat_write_header.
  *
  * @param s media file handle
  * @return 0 if OK, AVERROR_xxx on error
  */
 int av_write_trailer(AVFormatContext *s);
 
-void dump_format(AVFormatContext *ic,
-                 int index,
-                 const char *url,
-                 int is_output);
+/**
+ * Return the output format in the list of registered output formats
+ * which best matches the provided parameters, or return NULL if
+ * there is no match.
+ *
+ * @param short_name if non-NULL checks if short_name matches with the
+ * names of the registered formats
+ * @param filename if non-NULL checks if filename terminates with the
+ * extensions of the registered formats
+ * @param mime_type if non-NULL checks if mime_type matches with the
+ * MIME type of the registered formats
+ */
+AVOutputFormat *av_guess_format(const char *short_name,
+                                const char *filename,
+                                const char *mime_type);
 
-#if LIBAVFORMAT_VERSION_MAJOR < 53
 /**
- * Parses width and height out of string str.
- * @deprecated Use av_parse_video_frame_size instead.
+ * Guess the codec ID based upon muxer and filename.
  */
-attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr,
-                                          const char *str);
+enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+                            const char *filename, const char *mime_type,
+                            enum AVMediaType type);
 
 /**
- * Converts framerate from a string to a fraction.
- * @deprecated Use av_parse_video_frame_rate instead.
+ * Get timing information for the data currently output.
+ * The exact meaning of "currently output" depends on the format.
+ * It is mostly relevant for devices that have an internal buffer and/or
+ * work in real time.
+ * @param s          media file handle
+ * @param stream     stream in the media file
+ * @param dts[out]   DTS of the last packet output for the stream, in stream
+ *                   time_base units
+ * @param wall[out]  absolute time when that packet whas output,
+ *                   in microsecond
+ * @return  0 if OK, AVERROR(ENOSYS) if the format does not support it
+ * Note: some formats or devices may not allow to measure dts and wall
+ * atomically.
  */
-attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base,
-                                          const char *arg);
-#endif
+int av_get_output_timestamp(struct AVFormatContext *s, int stream,
+                            int64_t *dts, int64_t *wall);
+
 
 /**
- * Parses datestr and returns a corresponding number of microseconds.
- * @param datestr String representing a date or a duration.
- * - If a date the syntax is:
- * @code
- *  [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
- * @endcode
- * Time is local time unless Z is appended, in which case it is
- * interpreted as UTC.
- * If the year-month-day part is not specified it takes the current
- * year-month-day.
- * Returns the number of microseconds since 1st of January, 1970 up to
- * the time of the parsed date or INT64_MIN if datestr cannot be
- * successfully parsed.
- * - If a duration the syntax is:
- * @code
- *  [-]HH[:MM[:SS[.m...]]]
- *  [-]S+[.m...]
- * @endcode
- * Returns the number of microseconds contained in a time interval
- * with the specified duration or INT64_MIN if datestr cannot be
- * successfully parsed.
- * @param duration Flag which tells how to interpret datestr, if
- * not zero datestr is interpreted as a duration, otherwise as a
- * date.
+ * @}
+ */
+
+
+/**
+ * @defgroup lavf_misc Utility functions
+ * @ingroup libavf
+ * @{
+ *
+ * Miscellaneous utility functions related to both muxing and demuxing
+ * (or neither).
+ */
+
+/**
+ * Send a nice hexadecimal dump of a buffer to the specified file stream.
+ *
+ * @param f The file stream pointer where the dump should be sent to.
+ * @param buf buffer
+ * @param size buffer size
+ *
+ * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2
+ */
+void av_hex_dump(FILE *f, const uint8_t *buf, int size);
+
+/**
+ * Send a nice hexadecimal dump of a buffer to the log.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param buf buffer
+ * @param size buffer size
+ *
+ * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2
+ */
+void av_hex_dump_log(void *avcl, int level, const uint8_t *buf, int size);
+
+/**
+ * Send a nice dump of a packet to the specified file stream.
+ *
+ * @param f The file stream pointer where the dump should be sent to.
+ * @param pkt packet to dump
+ * @param dump_payload True if the payload must be displayed, too.
+ * @param st AVStream that the packet belongs to
+ */
+void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st);
+
+
+/**
+ * Send a nice dump of a packet to the log.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param pkt packet to dump
+ * @param dump_payload True if the payload must be displayed, too.
+ * @param st AVStream that the packet belongs to
+ */
+void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
+                      AVStream *st);
+
+/**
+ * Get the AVCodecID for the given codec tag tag.
+ * If no codec id is found returns AV_CODEC_ID_NONE.
+ *
+ * @param tags list of supported codec_id-codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ */
+enum AVCodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
+
+/**
+ * Get the codec tag for the given codec id id.
+ * If no codec tag is found returns 0.
+ *
+ * @param tags list of supported codec_id-codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ */
+unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id);
+
+int av_find_default_stream_index(AVFormatContext *s);
+
+/**
+ * Get the index for a specific timestamp.
+ * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond
+ *                 to the timestamp which is <= the requested one, if backward
+ *                 is 0, then it will be >=
+ *              if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
+ * @return < 0 if no such timestamp could be found
  */
-int64_t parse_date(const char *datestr, int duration);
+int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
 
-/** Gets the current time in microseconds. */
-int64_t av_gettime(void);
+/**
+ * Add an index entry into a sorted list. Update the entry if the list
+ * already contains it.
+ *
+ * @param timestamp timestamp in the time base of the given stream
+ */
+int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
+                       int size, int distance, int flags);
 
-/* ffm-specific for ffserver */
-#define FFM_PACKET_SIZE 4096
-int64_t ffm_read_write_index(int fd);
-int ffm_write_write_index(int fd, int64_t pos);
-void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size);
 
 /**
- * Attempts to find a specific tag in a URL.
+ * Split a URL string into components.
+ *
+ * The pointers to buffers for storing individual components may be null,
+ * in order to ignore that component. Buffers for components not found are
+ * set to empty strings. If the port is not found, it is set to a negative
+ * value.
  *
- * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done.
- * Return 1 if found.
+ * @param proto the buffer for the protocol
+ * @param proto_size the size of the proto buffer
+ * @param authorization the buffer for the authorization
+ * @param authorization_size the size of the authorization buffer
+ * @param hostname the buffer for the host name
+ * @param hostname_size the size of the hostname buffer
+ * @param port_ptr a pointer to store the port number in
+ * @param path the buffer for the path
+ * @param path_size the size of the path buffer
+ * @param url the URL to split
  */
-int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info);
+void av_url_split(char *proto,         int proto_size,
+                  char *authorization, int authorization_size,
+                  char *hostname,      int hostname_size,
+                  int *port_ptr,
+                  char *path,          int path_size,
+                  const char *url);
+
+
+void av_dump_format(AVFormatContext *ic,
+                    int index,
+                    const char *url,
+                    int is_output);
 
 /**
- * Returns in 'buf' the path with '%d' replaced by a number.
+ * Return in 'buf' the path with '%d' replaced by a number.
  *
  * Also handles the '%0nd' format where 'n' is the total number
  * of digits and '%%'.
@@ -1190,49 +1960,96 @@ int av_filename_number_test(const char *filename);
  *           all the contexts in the array (an AVCodecContext per RTP stream)
  *           must contain only one AVStream.
  * @param n_files number of AVCodecContexts contained in ac
- * @param buff buffer where the SDP will be stored (must be allocated by
- *             the caller)
+ * @param buf buffer where the SDP will be stored (must be allocated by
+ *            the caller)
  * @param size the size of the buffer
  * @return 0 if OK, AVERROR_xxx on error
  */
-int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size);
+int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size);
 
-#ifdef HAVE_AV_CONFIG_H
+/**
+ * Return a positive value if the given filename has one of the given
+ * extensions, 0 otherwise.
+ *
+ * @param extensions a comma-separated list of filename extensions
+ */
+int av_match_ext(const char *filename, const char *extensions);
 
-void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem);
+/**
+ * Test if the given container can store a codec.
+ *
+ * @param std_compliance standards compliance level, one of FF_COMPLIANCE_*
+ *
+ * @return 1 if codec with ID codec_id can be stored in ofmt, 0 if it cannot.
+ *         A negative number if this information is not available.
+ */
+int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance);
 
-#ifdef __GNUC__
-#define dynarray_add(tab, nb_ptr, elem)\
-do {\
-    __typeof__(tab) _tab = (tab);\
-    __typeof__(elem) _elem = (elem);\
-    (void)sizeof(**_tab == _elem); /* check that types are compatible */\
-    ff_dynarray_add((intptr_t **)_tab, nb_ptr, (intptr_t)_elem);\
-} while(0)
-#else
-#define dynarray_add(tab, nb_ptr, elem)\
-do {\
-    ff_dynarray_add((intptr_t **)(tab), nb_ptr, (intptr_t)(elem));\
-} while(0)
-#endif
+/**
+ * @defgroup riff_fourcc RIFF FourCCs
+ * @{
+ * Get the tables mapping RIFF FourCCs to libavcodec AVCodecIDs. The tables are
+ * meant to be passed to av_codec_get_id()/av_codec_get_tag() as in the
+ * following code:
+ * @code
+ * uint32_t tag = MKTAG('H', '2', '6', '4');
+ * const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 };
+ * enum AVCodecID id = av_codec_get_id(table, tag);
+ * @endcode
+ */
+/**
+ * @return the table mapping RIFF FourCCs for video to libavcodec AVCodecID.
+ */
+const struct AVCodecTag *avformat_get_riff_video_tags(void);
+/**
+ * @return the table mapping RIFF FourCCs for audio to AVCodecID.
+ */
+const struct AVCodecTag *avformat_get_riff_audio_tags(void);
+
+/**
+ * @}
+ */
 
-time_t mktimegm(struct tm *tm);
-struct tm *brktimegm(time_t secs, struct tm *tm);
-const char *small_strptime(const char *p, const char *fmt,
-                           struct tm *dt);
+/**
+ * Guess the sample aspect ratio of a frame, based on both the stream and the
+ * frame aspect ratio.
+ *
+ * Since the frame aspect ratio is set by the codec but the stream aspect ratio
+ * is set by the demuxer, these two may not be equal. This function tries to
+ * return the value that you should use if you would like to display the frame.
+ *
+ * Basic logic is to use the stream aspect ratio if it is set to something sane
+ * otherwise use the frame aspect ratio. This way a container setting, which is
+ * usually easy to modify can override the coded value in the frames.
+ *
+ * @param format the format context which the stream is part of
+ * @param stream the stream which the frame is part of
+ * @param frame the frame with the aspect ratio to be determined
+ * @return the guessed (valid) sample_aspect_ratio, 0/1 if no idea
+ */
+AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame);
 
-struct in_addr;
-int resolve_host(struct in_addr *sin_addr, const char *hostname);
+/**
+ * Check if the stream st contained in s is matched by the stream specifier
+ * spec.
+ *
+ * See the "stream specifiers" chapter in the documentation for the syntax
+ * of spec.
+ *
+ * @return  >0 if st is matched by spec;
+ *          0  if st is not matched by spec;
+ *          AVERROR code if spec is invalid
+ *
+ * @note  A stream specifier can match several streams in the format.
+ */
+int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
+                                    const char *spec);
 
-void url_split(char *proto, int proto_size,
-               char *authorization, int authorization_size,
-               char *hostname, int hostname_size,
-               int *port_ptr,
-               char *path, int path_size,
-               const char *url);
+void avformat_queue_attached_pictures(AVFormatContext *s);
 
-int match_ext(const char *filename, const char *extensions);
 
-#endif /* HAVE_AV_CONFIG_H */
+/**
+ * @}
+ */
 
 #endif /* AVFORMAT_AVFORMAT_H */
index 06749fb555d3fd0452bba35064873d4607a0b9e8..17b341d6c79542bf46b7dadb091fb82b75202105 100644 (file)
 #define AVFORMAT_AVIO_H
 
 /**
- * @file libavformat/avio.h
- * unbuffered I/O operations
- *
- * @warning This file has to be considered an internal but installed
- * header, so it should not be directly included in your projects.
+ * @file
+ * @ingroup lavf_io
+ * Buffered I/O operations
  */
 
-#if !defined(WIN32) && !defined(_WIN32_WCE)
 #include <stdint.h>
-#endif
 
 #include "libavutil/common.h"
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
 
-/* unbuffered I/O */
-
-/**
- * URL Context.
- * New fields can be added to the end with minor version bumps.
- * Removal, reordering and changes to existing fields require a major
- * version bump.
- * sizeof(URLContext) must not be used outside libav*.
- */
-typedef struct URLContext {
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
-    const AVClass *av_class; ///< information for av_log(). Set by url_open().
-#endif
-    struct URLProtocol *prot;
-    int flags;
-    int is_streamed;  /**< true if streamed (no seek possible), default = false */
-    int max_packet_size;  /**< if non zero, the stream is packetized with this max packet size */
-    void *priv_data;
-    char *filename; /**< specified filename */
-} URLContext;
-
-typedef struct URLPollEntry {
-    URLContext *handle;
-    int events;
-    int revents;
-} URLPollEntry;
-
-#define URL_RDONLY 0
-#define URL_WRONLY 1
-#define URL_RDWR   2
-
-typedef int URLInterruptCB(void);
-
-int url_open_protocol (URLContext **puc, struct URLProtocol *up,
-                       const char *filename, int flags);
-int url_open(URLContext **h, const char *filename, int flags);
-int url_read(URLContext *h, unsigned char *buf, int size);
-int url_write(URLContext *h, unsigned char *buf, int size);
-int64_t url_seek(URLContext *h, int64_t pos, int whence);
-int url_close(URLContext *h);
-int url_exist(const char *filename);
-int64_t url_filesize(URLContext *h);
-
-/**
- * Return the file descriptor associated with this URL. For RTP, this
- * will return only the RTP file descriptor, not the RTCP file descriptor.
- * To get both, use rtp_get_file_handles().
- *
- * @return the file descriptor associated with this URL, or <0 on error.
- */
-int url_get_file_handle(URLContext *h);
-
-/**
- * Return the maximum packet size associated to packetized file
- * handle. If the file is not packetized (stream like HTTP or file on
- * disk), then 0 is returned.
- *
- * @param h file handle
- * @return maximum packet size in bytes
- */
-int url_get_max_packet_size(URLContext *h);
-void url_get_filename(URLContext *h, char *buf, int buf_size);
-
-/**
- * The callback is called in blocking functions to test regulary if
- * asynchronous interruption is needed. AVERROR(EINTR) is returned
- * in this case by the interrupted function. 'NULL' means no interrupt
- * callback is given.
- */
-void url_set_interrupt_cb(URLInterruptCB *interrupt_cb);
-
-/* not implemented */
-int url_poll(URLPollEntry *poll_table, int n, int timeout);
-
-/**
- * Pause and resume playing - only meaningful if using a network streaming
- * protocol (e.g. MMS).
- * @param pause 1 for pause, 0 for resume
- */
-int av_url_read_pause(URLContext *h, int pause);
-
-/**
- * Seek to a given timestamp relative to some component stream.
- * Only meaningful if using a network streaming protocol (e.g. MMS.).
- * @param stream_index The stream index that the timestamp is relative to.
- *        If stream_index is (-1) the timestamp should be in AV_TIME_BASE
- *        units from the beginning of the presentation.
- *        If a stream_index >= 0 is used and the protocol does not support
- *        seeking based on component streams, the call will fail with ENOTSUP.
- * @param timestamp timestamp in AVStream.time_base units
- *        or if there is no stream specified then in AV_TIME_BASE units.
- * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE
- *        and AVSEEK_FLAG_ANY. The protocol may silently ignore
- *        AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will
- *        fail with ENOTSUP if used and not supported.
- * @return >= 0 on success
- * @see AVInputFormat::read_seek
- */
-int64_t av_url_read_seek(URLContext *h, int stream_index,
-                         int64_t timestamp, int flags);
-
-/**
- * Passing this as the "whence" parameter to a seek function causes it to
- * return the filesize without seeking anywhere. Supporting this is optional.
- * If it is not supported then the seek function will return <0.
- */
-#define AVSEEK_SIZE 0x10000
-
-typedef struct URLProtocol {
-    const char *name;
-    int (*url_open)(URLContext *h, const char *filename, int flags);
-    int (*url_read)(URLContext *h, unsigned char *buf, int size);
-    int (*url_write)(URLContext *h, unsigned char *buf, int size);
-    int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);
-    int (*url_close)(URLContext *h);
-    struct URLProtocol *next;
-    int (*url_read_pause)(URLContext *h, int pause);
-    int64_t (*url_read_seek)(URLContext *h, int stream_index,
-                             int64_t timestamp, int flags);
-    int (*url_get_file_handle)(URLContext *h);
-} URLProtocol;
+#include "libavformat/version.h"
 
-#if LIBAVFORMAT_VERSION_MAJOR < 53
-extern URLProtocol *first_protocol;
-#endif
 
-extern URLInterruptCB *url_interrupt_cb;
-
-/**
- * If protocol is NULL, returns the first registered protocol,
- * if protocol is non-NULL, returns the next registered protocol after protocol,
- * or NULL if protocol is the last one.
- */
-URLProtocol *av_protocol_next(URLProtocol *p);
+#define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */
 
-#if LIBAVFORMAT_VERSION_MAJOR < 53
 /**
- * @deprecated Use av_register_protocol() instead.
+ * Callback for checking whether to abort blocking functions.
+ * AVERROR_EXIT is returned in this case by the interrupted
+ * function. During blocking operations, callback is called with
+ * opaque as parameter. If the callback returns 1, the
+ * blocking operation will be aborted.
+ *
+ * No members can be added to this struct without a major bump, if
+ * new elements have been added after this struct in AVFormatContext
+ * or AVIOContext.
  */
-attribute_deprecated int register_protocol(URLProtocol *protocol);
-#endif
-
-int av_register_protocol(URLProtocol *protocol);
+typedef struct AVIOInterruptCB {
+    int (*callback)(void*);
+    void *opaque;
+} AVIOInterruptCB;
 
 /**
  * Bytestream IO Context.
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
- * sizeof(ByteIOContext) must not be used outside libav*.
+ * sizeof(AVIOContext) must not be used outside libav*.
+ *
+ * @note None of the function pointers in AVIOContext should be called
+ *       directly, they should only be set by the client application
+ *       when implementing custom I/O. Normally these are set to the
+ *       function pointers specified in avio_alloc_context()
  */
-typedef struct {
-    unsigned char *buffer;
-    int buffer_size;
-    unsigned char *buf_ptr, *buf_end;
-    void *opaque;
+typedef struct AVIOContext {
+    /**
+     * A class for private options.
+     *
+     * If this AVIOContext is created by avio_open2(), av_class is set and
+     * passes the options down to protocols.
+     *
+     * If this AVIOContext is manually allocated, then av_class may be set by
+     * the caller.
+     *
+     * warning -- this field can be NULL, be sure to not pass this AVIOContext
+     * to any av_opt_* functions in that case.
+     */
+    const AVClass *av_class;
+    unsigned char *buffer;  /**< Start of the buffer. */
+    int buffer_size;        /**< Maximum buffer size */
+    unsigned char *buf_ptr; /**< Current position in the buffer */
+    unsigned char *buf_end; /**< End of the data, may be less than
+                                 buffer+buffer_size if the read function returned
+                                 less data than requested, e.g. for streams where
+                                 no more data has been received yet. */
+    void *opaque;           /**< A private pointer, passed to the read/write/seek/...
+                                 functions. */
     int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
     int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
     int64_t (*seek)(void *opaque, int64_t offset, int whence);
-    int64_t pos; /**< position in the file of the current buffer */
-    int must_flush; /**< true if the next seek should flush */
-    int eof_reached; /**< true if eof reached */
-    int write_flag;  /**< true if open for writing */
-    int is_streamed;
+    int64_t pos;            /**< position in the file of the current buffer */
+    int must_flush;         /**< true if the next seek should flush */
+    int eof_reached;        /**< true if eof reached */
+    int write_flag;         /**< true if open for writing */
     int max_packet_size;
     unsigned long checksum;
     unsigned char *checksum_ptr;
     unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
-    int error;         ///< contains the error code or 0 if no error happened
+    int error;              /**< contains the error code or 0 if no error happened */
+    /**
+     * Pause or resume playback for network streaming protocols - e.g. MMS.
+     */
     int (*read_pause)(void *opaque, int pause);
+    /**
+     * Seek to a given timestamp in stream with the specified stream_index.
+     * Needed for some network streaming protocols which don't support seeking
+     * to byte position.
+     */
     int64_t (*read_seek)(void *opaque, int stream_index,
                          int64_t timestamp, int flags);
-} ByteIOContext;
+    /**
+     * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
+     */
+    int seekable;
+
+    /**
+     * max filesize, used to limit allocations
+     * This field is internal to libavformat and access from outside is not allowed.
+     */
+     int64_t maxsize;
+
+     /**
+      * avio_read and avio_write should if possible be satisfied directly
+      * instead of going through a buffer, and avio_seek will always
+      * call the underlying seek function directly.
+      */
+     int direct;
+
+    /**
+     * Bytes read statistic
+     * This field is internal to libavformat and access from outside is not allowed.
+     */
+     int64_t bytes_read;
+
+    /**
+     * seek statistic
+     * This field is internal to libavformat and access from outside is not allowed.
+     */
+     int seek_count;
+} AVIOContext;
 
-int init_put_byte(ByteIOContext *s,
-                  unsigned char *buffer,
-                  int buffer_size,
-                  int write_flag,
-                  void *opaque,
-                  int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
-                  int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
-                  int64_t (*seek)(void *opaque, int64_t offset, int whence));
-ByteIOContext *av_alloc_put_byte(
+/* unbuffered I/O */
+
+/**
+ * Return AVIO_FLAG_* access flags corresponding to the access permissions
+ * of the resource in url, or a negative value corresponding to an
+ * AVERROR code in case of failure. The returned access flags are
+ * masked by the value in flags.
+ *
+ * @note This function is intrinsically unsafe, in the sense that the
+ * checked resource may change its existence or permission status from
+ * one call to another. Thus you should not trust the returned value,
+ * unless you are sure that no other processes are accessing the
+ * checked resource.
+ */
+int avio_check(const char *url, int flags);
+
+/**
+ * Allocate and initialize an AVIOContext for buffered I/O. It must be later
+ * freed with av_free().
+ *
+ * @param buffer Memory block for input/output operations via AVIOContext.
+ *        The buffer must be allocated with av_malloc() and friends.
+ * @param buffer_size The buffer size is very important for performance.
+ *        For protocols with fixed blocksize it should be set to this blocksize.
+ *        For others a typical size is a cache page, e.g. 4kb.
+ * @param write_flag Set to 1 if the buffer should be writable, 0 otherwise.
+ * @param opaque An opaque pointer to user-specific data.
+ * @param read_packet  A function for refilling the buffer, may be NULL.
+ * @param write_packet A function for writing the buffer contents, may be NULL.
+ *        The function may not change the input buffers content.
+ * @param seek A function for seeking to specified byte position, may be NULL.
+ *
+ * @return Allocated AVIOContext or NULL on failure.
+ */
+AVIOContext *avio_alloc_context(
                   unsigned char *buffer,
                   int buffer_size,
                   int write_flag,
@@ -225,182 +185,291 @@ ByteIOContext *av_alloc_put_byte(
                   int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
                   int64_t (*seek)(void *opaque, int64_t offset, int whence));
 
-void put_byte(ByteIOContext *s, int b);
-void put_buffer(ByteIOContext *s, const unsigned char *buf, int size);
-void put_le64(ByteIOContext *s, uint64_t val);
-void put_be64(ByteIOContext *s, uint64_t val);
-void put_le32(ByteIOContext *s, unsigned int val);
-void put_be32(ByteIOContext *s, unsigned int val);
-void put_le24(ByteIOContext *s, unsigned int val);
-void put_be24(ByteIOContext *s, unsigned int val);
-void put_le16(ByteIOContext *s, unsigned int val);
-void put_be16(ByteIOContext *s, unsigned int val);
-void put_tag(ByteIOContext *s, const char *tag);
+void avio_w8(AVIOContext *s, int b);
+void avio_write(AVIOContext *s, const unsigned char *buf, int size);
+void avio_wl64(AVIOContext *s, uint64_t val);
+void avio_wb64(AVIOContext *s, uint64_t val);
+void avio_wl32(AVIOContext *s, unsigned int val);
+void avio_wb32(AVIOContext *s, unsigned int val);
+void avio_wl24(AVIOContext *s, unsigned int val);
+void avio_wb24(AVIOContext *s, unsigned int val);
+void avio_wl16(AVIOContext *s, unsigned int val);
+void avio_wb16(AVIOContext *s, unsigned int val);
+
+/**
+ * Write a NULL-terminated string.
+ * @return number of bytes written.
+ */
+int avio_put_str(AVIOContext *s, const char *str);
 
-void put_strz(ByteIOContext *s, const char *buf);
+/**
+ * Convert an UTF-8 string to UTF-16LE and write it.
+ * @return number of bytes written.
+ */
+int avio_put_str16le(AVIOContext *s, const char *str);
 
 /**
- * fseek() equivalent for ByteIOContext.
+ * Passing this as the "whence" parameter to a seek function causes it to
+ * return the filesize without seeking anywhere. Supporting this is optional.
+ * If it is not supported then the seek function will return <0.
+ */
+#define AVSEEK_SIZE 0x10000
+
+/**
+ * Oring this flag as into the "whence" parameter to a seek function causes it to
+ * seek by any means (like reopening and linear reading) or other normally unreasonble
+ * means that can be extreemly slow.
+ * This may be ignored by the seek code.
+ */
+#define AVSEEK_FORCE 0x20000
+
+/**
+ * fseek() equivalent for AVIOContext.
  * @return new position or AVERROR.
  */
-int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence);
+int64_t avio_seek(AVIOContext *s, int64_t offset, int whence);
 
 /**
- * Skip given number of bytes forward.
- * @param offset number of bytes
+ * Skip given number of bytes forward
+ * @return new position or AVERROR.
  */
-void url_fskip(ByteIOContext *s, int64_t offset);
+int64_t avio_skip(AVIOContext *s, int64_t offset);
 
 /**
- * ftell() equivalent for ByteIOContext.
+ * ftell() equivalent for AVIOContext.
  * @return position or AVERROR.
  */
-int64_t url_ftell(ByteIOContext *s);
+static av_always_inline int64_t avio_tell(AVIOContext *s)
+{
+    return avio_seek(s, 0, SEEK_CUR);
+}
 
 /**
- * Gets the filesize.
+ * Get the filesize.
  * @return filesize or AVERROR
  */
-int64_t url_fsize(ByteIOContext *s);
+int64_t avio_size(AVIOContext *s);
 
 /**
- * feof() equivalent for ByteIOContext.
+ * feof() equivalent for AVIOContext.
  * @return non zero if and only if end of file
  */
-int url_feof(ByteIOContext *s);
-
-int url_ferror(ByteIOContext *s);
-
-int av_url_read_fpause(ByteIOContext *h, int pause);
-int64_t av_url_read_fseek(ByteIOContext *h, int stream_index,
-                          int64_t timestamp, int flags);
-
-#define URL_EOF (-1)
-/** @note return URL_EOF (-1) if EOF */
-int url_fgetc(ByteIOContext *s);
+int url_feof(AVIOContext *s);
 
 /** @warning currently size is limited */
-#ifdef __GNUC__
-int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
-#else
-int url_fprintf(ByteIOContext *s, const char *fmt, ...);
-#endif
-
-/** @note unlike fgets, the EOL character is not returned and a whole
-    line is parsed. return NULL if first char read was EOF */
-char *url_fgets(ByteIOContext *s, char *buf, int buf_size);
-
-void put_flush_packet(ByteIOContext *s);
-
+int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
 
 /**
- * Reads size bytes from ByteIOContext into buf.
- * @returns number of bytes read or AVERROR
+ * Force flushing of buffered data to the output s.
+ *
+ * Force the buffered data to be immediately written to the output,
+ * without to wait to fill the internal buffer.
  */
-int get_buffer(ByteIOContext *s, unsigned char *buf, int size);
+void avio_flush(AVIOContext *s);
 
 /**
- * Reads size bytes from ByteIOContext into buf.
- * This reads at most 1 packet. If that is not enough fewer bytes will be
- * returned.
- * @returns number of bytes read or AVERROR
+ * Read size bytes from AVIOContext into buf.
+ * @return number of bytes read or AVERROR
  */
-int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size);
+int avio_read(AVIOContext *s, unsigned char *buf, int size);
 
-/** @note return 0 if EOF, so you cannot use it if EOF handling is
-    necessary */
-int get_byte(ByteIOContext *s);
-unsigned int get_le24(ByteIOContext *s);
-unsigned int get_le32(ByteIOContext *s);
-uint64_t get_le64(ByteIOContext *s);
-unsigned int get_le16(ByteIOContext *s);
+/**
+ * @name Functions for reading from AVIOContext
+ * @{
+ *
+ * @note return 0 if EOF, so you cannot use it if EOF handling is
+ *       necessary
+ */
+int          avio_r8  (AVIOContext *s);
+unsigned int avio_rl16(AVIOContext *s);
+unsigned int avio_rl24(AVIOContext *s);
+unsigned int avio_rl32(AVIOContext *s);
+uint64_t     avio_rl64(AVIOContext *s);
+unsigned int avio_rb16(AVIOContext *s);
+unsigned int avio_rb24(AVIOContext *s);
+unsigned int avio_rb32(AVIOContext *s);
+uint64_t     avio_rb64(AVIOContext *s);
+/**
+ * @}
+ */
 
-char *get_strz(ByteIOContext *s, char *buf, int maxlen);
-unsigned int get_be16(ByteIOContext *s);
-unsigned int get_be24(ByteIOContext *s);
-unsigned int get_be32(ByteIOContext *s);
-uint64_t get_be64(ByteIOContext *s);
+/**
+ * Read a string from pb into buf. The reading will terminate when either
+ * a NULL character was encountered, maxlen bytes have been read, or nothing
+ * more can be read from pb. The result is guaranteed to be NULL-terminated, it
+ * will be truncated if buf is too small.
+ * Note that the string is not interpreted or validated in any way, it
+ * might get truncated in the middle of a sequence for multi-byte encodings.
+ *
+ * @return number of bytes read (is always <= maxlen).
+ * If reading ends on EOF or error, the return value will be one more than
+ * bytes actually read.
+ */
+int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen);
 
-uint64_t ff_get_v(ByteIOContext *bc);
+/**
+ * Read a UTF-16 string from pb and convert it to UTF-8.
+ * The reading will terminate when either a null or invalid character was
+ * encountered or maxlen bytes have been read.
+ * @return number of bytes read (is always <= maxlen)
+ */
+int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen);
+int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen);
 
-static inline int url_is_streamed(ByteIOContext *s)
-{
-    return s->is_streamed;
-}
 
-/** @note when opened as read/write, the buffers are only used for
-    writing */
-int url_fdopen(ByteIOContext **s, URLContext *h);
+/**
+ * @name URL open modes
+ * The flags argument to avio_open must be one of the following
+ * constants, optionally ORed with other flags.
+ * @{
+ */
+#define AVIO_FLAG_READ  1                                      /**< read-only */
+#define AVIO_FLAG_WRITE 2                                      /**< write-only */
+#define AVIO_FLAG_READ_WRITE (AVIO_FLAG_READ|AVIO_FLAG_WRITE)  /**< read-write pseudo flag */
+/**
+ * @}
+ */
 
-/** @warning must be called before any I/O */
-int url_setbufsize(ByteIOContext *s, int buf_size);
-/** Reset the buffer for reading or writing.
- * @note Will drop any data currently in the buffer without transmitting it.
- * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY
- *        to set up the buffer for writing. */
-int url_resetbuf(ByteIOContext *s, int flags);
+/**
+ * Use non-blocking mode.
+ * If this flag is set, operations on the context will return
+ * AVERROR(EAGAIN) if they can not be performed immediately.
+ * If this flag is not set, operations on the context will never return
+ * AVERROR(EAGAIN).
+ * Note that this flag does not affect the opening/connecting of the
+ * context. Connecting a protocol will always block if necessary (e.g. on
+ * network protocols) but never hang (e.g. on busy devices).
+ * Warning: non-blocking protocols is work-in-progress; this flag may be
+ * silently ignored.
+ */
+#define AVIO_FLAG_NONBLOCK 8
 
-/** @note when opened as read/write, the buffers are only used for
-    writing */
-int url_fopen(ByteIOContext **s, const char *filename, int flags);
-int url_fclose(ByteIOContext *s);
-URLContext *url_fileno(ByteIOContext *s);
+/**
+ * Use direct mode.
+ * avio_read and avio_write should if possible be satisfied directly
+ * instead of going through a buffer, and avio_seek will always
+ * call the underlying seek function directly.
+ */
+#define AVIO_FLAG_DIRECT 0x8000
 
 /**
- * Return the maximum packet size associated to packetized buffered file
- * handle. If the file is not packetized (stream like http or file on
- * disk), then 0 is returned.
+ * Create and initialize a AVIOContext for accessing the
+ * resource indicated by url.
+ * @note When the resource indicated by url has been opened in
+ * read+write mode, the AVIOContext can be used only for writing.
  *
- * @param s buffered file handle
- * @return maximum packet size in bytes
+ * @param s Used to return the pointer to the created AVIOContext.
+ * In case of failure the pointed to value is set to NULL.
+ * @param flags flags which control how the resource indicated by url
+ * is to be opened
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
  */
-int url_fget_max_packet_size(ByteIOContext *s);
+int avio_open(AVIOContext **s, const char *url, int flags);
 
-int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags);
+/**
+ * Create and initialize a AVIOContext for accessing the
+ * resource indicated by url.
+ * @note When the resource indicated by url has been opened in
+ * read+write mode, the AVIOContext can be used only for writing.
+ *
+ * @param s Used to return the pointer to the created AVIOContext.
+ * In case of failure the pointed to value is set to NULL.
+ * @param flags flags which control how the resource indicated by url
+ * is to be opened
+ * @param int_cb an interrupt callback to be used at the protocols level
+ * @param options  A dictionary filled with protocol-private options. On return
+ * this parameter will be destroyed and replaced with a dict containing options
+ * that were not found. May be NULL.
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int avio_open2(AVIOContext **s, const char *url, int flags,
+               const AVIOInterruptCB *int_cb, AVDictionary **options);
 
-/** return the written or read size */
-int url_close_buf(ByteIOContext *s);
+/**
+ * Close the resource accessed by the AVIOContext s and free it.
+ * This function can only be used if s was opened by avio_open().
+ *
+ * The internal buffer is automatically flushed before closing the
+ * resource.
+ *
+ * @return 0 on success, an AVERROR < 0 on error.
+ * @see avio_closep
+ */
+int avio_close(AVIOContext *s);
 
 /**
- * Open a write only memory stream.
+ * Close the resource accessed by the AVIOContext *s, free it
+ * and set the pointer pointing to it to NULL.
+ * This function can only be used if s was opened by avio_open().
  *
- * @param s new IO context
- * @return zero if no error.
+ * The internal buffer is automatically flushed before closing the
+ * resource.
+ *
+ * @return 0 on success, an AVERROR < 0 on error.
+ * @see avio_close
  */
-int url_open_dyn_buf(ByteIOContext **s);
+int avio_closep(AVIOContext **s);
+
 
 /**
- * Open a write only packetized memory stream with a maximum packet
- * size of 'max_packet_size'.  The stream is stored in a memory buffer
- * with a big endian 4 byte header giving the packet size in bytes.
+ * Open a write only memory stream.
  *
  * @param s new IO context
- * @param max_packet_size maximum packet size (must be > 0)
  * @return zero if no error.
  */
-int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size);
+int avio_open_dyn_buf(AVIOContext **s);
 
 /**
  * Return the written size and a pointer to the buffer. The buffer
- *  must be freed with av_free().
+ * must be freed with av_free().
+ * Padding of FF_INPUT_BUFFER_PADDING_SIZE is added to the buffer.
+ *
  * @param s IO context
  * @param pbuffer pointer to a byte buffer
  * @return the length of the byte buffer
  */
-int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer);
-
-unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
-                                    unsigned int len);
-unsigned long get_checksum(ByteIOContext *s);
-void init_checksum(ByteIOContext *s,
-                   unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
-                   unsigned long checksum);
-
-/* udp.c */
-int udp_set_remote_url(URLContext *h, const char *uri);
-int udp_get_local_port(URLContext *h);
-#if (LIBAVFORMAT_VERSION_MAJOR <= 52)
-int udp_get_file_handle(URLContext *h);
-#endif
+int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
+
+/**
+ * Iterate through names of available protocols.
+ *
+ * @param opaque A private pointer representing current protocol.
+ *        It must be a pointer to NULL on first iteration and will
+ *        be updated by successive calls to avio_enum_protocols.
+ * @param output If set to 1, iterate over output protocols,
+ *               otherwise over input protocols.
+ *
+ * @return A static string containing the name of current protocol or NULL
+ */
+const char *avio_enum_protocols(void **opaque, int output);
+
+/**
+ * Pause and resume playing - only meaningful if using a network streaming
+ * protocol (e.g. MMS).
+ * @param pause 1 for pause, 0 for resume
+ */
+int     avio_pause(AVIOContext *h, int pause);
+
+/**
+ * Seek to a given timestamp relative to some component stream.
+ * Only meaningful if using a network streaming protocol (e.g. MMS.).
+ * @param stream_index The stream index that the timestamp is relative to.
+ *        If stream_index is (-1) the timestamp should be in AV_TIME_BASE
+ *        units from the beginning of the presentation.
+ *        If a stream_index >= 0 is used and the protocol does not support
+ *        seeking based on component streams, the call will fail.
+ * @param timestamp timestamp in AVStream.time_base units
+ *        or if there is no stream specified then in AV_TIME_BASE units.
+ * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE
+ *        and AVSEEK_FLAG_ANY. The protocol may silently ignore
+ *        AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will
+ *        fail if used and not supported.
+ * @return >= 0 on success
+ * @see AVInputFormat::read_seek
+ */
+int64_t avio_seek_time(AVIOContext *h, int stream_index,
+                       int64_t timestamp, int flags);
 
 #endif /* AVFORMAT_AVIO_H */
diff --git a/extra_lib/include/libavformat/version.h b/extra_lib/include/libavformat/version.h
new file mode 100644 (file)
index 0000000..749b9e0
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Version macros.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_VERSION_H
+#define AVFORMAT_VERSION_H
+
+/**
+ * @file
+ * @ingroup libavf
+ * Libavformat version macros
+ */
+
+#include "libavutil/avutil.h"
+
+#define LIBAVFORMAT_VERSION_MAJOR 54
+#define LIBAVFORMAT_VERSION_MINOR 33
+#define LIBAVFORMAT_VERSION_MICRO 100
+
+#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
+                                               LIBAVFORMAT_VERSION_MINOR, \
+                                               LIBAVFORMAT_VERSION_MICRO)
+#define LIBAVFORMAT_VERSION     AV_VERSION(LIBAVFORMAT_VERSION_MAJOR,   \
+                                           LIBAVFORMAT_VERSION_MINOR,   \
+                                           LIBAVFORMAT_VERSION_MICRO)
+#define LIBAVFORMAT_BUILD       LIBAVFORMAT_VERSION_INT
+
+#define LIBAVFORMAT_IDENT       "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
+
+/**
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ */
+
+#ifndef FF_API_OLD_AVIO
+#define FF_API_OLD_AVIO                (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_PKT_DUMP
+#define FF_API_PKT_DUMP                (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
+#define FF_API_ALLOC_OUTPUT_CONTEXT    (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_FORMAT_PARAMETERS
+#define FF_API_FORMAT_PARAMETERS       (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_NEW_STREAM
+#define FF_API_NEW_STREAM              (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_SET_PTS_INFO
+#define FF_API_SET_PTS_INFO            (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_CLOSE_INPUT_FILE
+#define FF_API_CLOSE_INPUT_FILE        (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_APPLEHTTP_PROTO
+#define FF_API_APPLEHTTP_PROTO         (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_READ_PACKET
+#define FF_API_READ_PACKET             (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_INTERLEAVE_PACKET
+#define FF_API_INTERLEAVE_PACKET       (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_AV_GETTIME
+#define FF_API_AV_GETTIME              (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_R_FRAME_RATE
+#define FF_API_R_FRAME_RATE            (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+
+#endif /* AVFORMAT_VERSION_H */
diff --git a/extra_lib/include/libavutil/adler32.h b/extra_lib/include/libavutil/adler32.h
new file mode 100644 (file)
index 0000000..e926ef6
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * copyright (c) 2006 Mans Rullgard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ADLER32_H
+#define AVUTIL_ADLER32_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+/**
+ * @ingroup lavu_crypto
+ * Calculate the Adler32 checksum of a buffer.
+ *
+ * Passing the return value to a subsequent av_adler32_update() call
+ * allows the checksum of multiple buffers to be calculated as though
+ * they were concatenated.
+ *
+ * @param adler initial checksum value
+ * @param buf   pointer to input buffer
+ * @param len   size of input buffer
+ * @return      updated checksum
+ */
+unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf,
+                                unsigned int len) av_pure;
+
+#endif /* AVUTIL_ADLER32_H */
diff --git a/extra_lib/include/libavutil/aes.h b/extra_lib/include/libavutil/aes.h
new file mode 100644 (file)
index 0000000..9c1a54e
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AES_H
+#define AVUTIL_AES_H
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "version.h"
+
+/**
+ * @defgroup lavu_aes AES
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+#if FF_API_CONTEXT_SIZE
+extern attribute_deprecated const int av_aes_size;
+#endif
+
+struct AVAES;
+
+/**
+ * Allocate an AVAES context.
+ */
+struct AVAES *av_aes_alloc(void);
+
+/**
+ * Initialize an AVAES context.
+ * @param key_bits 128, 192 or 256
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ * @param count number of 16 byte blocks
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param iv initialization vector for CBC mode, if NULL then ECB will be used
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_AES_H */
diff --git a/extra_lib/include/libavutil/attributes.h b/extra_lib/include/libavutil/attributes.h
new file mode 100644 (file)
index 0000000..64b46f6
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Macro definitions for various function/variable attributes
+ */
+
+#ifndef AVUTIL_ATTRIBUTES_H
+#define AVUTIL_ATTRIBUTES_H
+
+#ifdef __GNUC__
+#    define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
+#else
+#    define AV_GCC_VERSION_AT_LEAST(x,y) 0
+#endif
+
+#ifndef av_always_inline
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+#    define av_always_inline __attribute__((always_inline)) inline
+#elif defined(_MSC_VER)
+#    define av_always_inline __forceinline
+#else
+#    define av_always_inline inline
+#endif
+#endif
+
+#ifndef av_extern_inline
+#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__)
+#    define av_extern_inline extern inline
+#else
+#    define av_extern_inline inline
+#endif
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+#    define av_noinline __attribute__((noinline))
+#else
+#    define av_noinline
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+#    define av_pure __attribute__((pure))
+#else
+#    define av_pure
+#endif
+
+#ifndef av_restrict
+#define av_restrict restrict
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(2,6)
+#    define av_const __attribute__((const))
+#else
+#    define av_const
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(4,3)
+#    define av_cold __attribute__((cold))
+#else
+#    define av_cold
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(4,1)
+#    define av_flatten __attribute__((flatten))
+#else
+#    define av_flatten
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+#    define attribute_deprecated __attribute__((deprecated))
+#else
+#    define attribute_deprecated
+#endif
+
+/**
+ * Disable warnings about deprecated features
+ * This is useful for sections of code kept for backward compatibility and
+ * scheduled for removal.
+ */
+#ifndef AV_NOWARN_DEPRECATED
+#if AV_GCC_VERSION_AT_LEAST(4,6)
+#    define AV_NOWARN_DEPRECATED(code) \
+        _Pragma("GCC diagnostic push") \
+        _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
+        code \
+        _Pragma("GCC diagnostic pop")
+#else
+#    define AV_NOWARN_DEPRECATED(code) code
+#endif
+#endif
+
+
+#if defined(__GNUC__)
+#    define av_unused __attribute__((unused))
+#else
+#    define av_unused
+#endif
+
+/**
+ * Mark a variable as used and prevent the compiler from optimizing it
+ * away.  This is useful for variables accessed only from inline
+ * assembler without the compiler being aware.
+ */
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+#    define av_used __attribute__((used))
+#else
+#    define av_used
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(3,3)
+#   define av_alias __attribute__((may_alias))
+#else
+#   define av_alias
+#endif
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
+#    define av_uninit(x) x=x
+#else
+#    define av_uninit(x) x
+#endif
+
+#ifdef __GNUC__
+#    define av_builtin_constant_p __builtin_constant_p
+#    define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos)))
+#else
+#    define av_builtin_constant_p(x) 0
+#    define av_printf_format(fmtpos, attrpos)
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(2,5)
+#    define av_noreturn __attribute__((noreturn))
+#else
+#    define av_noreturn
+#endif
+
+#endif /* AVUTIL_ATTRIBUTES_H */
diff --git a/extra_lib/include/libavutil/audio_fifo.h b/extra_lib/include/libavutil/audio_fifo.h
new file mode 100644 (file)
index 0000000..8c76388
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Audio FIFO
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.1 of the License, or (at your option) any later version.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Audio FIFO Buffer
+ */
+
+#ifndef AVUTIL_AUDIO_FIFO_H
+#define AVUTIL_AUDIO_FIFO_H
+
+#include "avutil.h"
+#include "fifo.h"
+#include "samplefmt.h"
+
+/**
+ * @addtogroup lavu_audio
+ * @{
+ */
+
+/**
+ * Context for an Audio FIFO Buffer.
+ *
+ * - Operates at the sample level rather than the byte level.
+ * - Supports multiple channels with either planar or packed sample format.
+ * - Automatic reallocation when writing to a full buffer.
+ */
+typedef struct AVAudioFifo AVAudioFifo;
+
+/**
+ * Free an AVAudioFifo.
+ *
+ * @param af  AVAudioFifo to free
+ */
+void av_audio_fifo_free(AVAudioFifo *af);
+
+/**
+ * Allocate an AVAudioFifo.
+ *
+ * @param sample_fmt  sample format
+ * @param channels    number of channels
+ * @param nb_samples  initial allocation size, in samples
+ * @return            newly allocated AVAudioFifo, or NULL on error
+ */
+AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels,
+                                 int nb_samples);
+
+/**
+ * Reallocate an AVAudioFifo.
+ *
+ * @param af          AVAudioFifo to reallocate
+ * @param nb_samples  new allocation size, in samples
+ * @return            0 if OK, or negative AVERROR code on failure
+ */
+int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples);
+
+/**
+ * Write data to an AVAudioFifo.
+ *
+ * The AVAudioFifo will be reallocated automatically if the available space
+ * is less than nb_samples.
+ *
+ * @see enum AVSampleFormat
+ * The documentation for AVSampleFormat describes the data layout.
+ *
+ * @param af          AVAudioFifo to write to
+ * @param data        audio data plane pointers
+ * @param nb_samples  number of samples to write
+ * @return            number of samples actually written, or negative AVERROR
+ *                    code on failure.
+ */
+int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples);
+
+/**
+ * Read data from an AVAudioFifo.
+ *
+ * @see enum AVSampleFormat
+ * The documentation for AVSampleFormat describes the data layout.
+ *
+ * @param af          AVAudioFifo to read from
+ * @param data        audio data plane pointers
+ * @param nb_samples  number of samples to read
+ * @return            number of samples actually read, or negative AVERROR code
+ *                    on failure.
+ */
+int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples);
+
+/**
+ * Drain data from an AVAudioFifo.
+ *
+ * Removes the data without reading it.
+ *
+ * @param af          AVAudioFifo to drain
+ * @param nb_samples  number of samples to drain
+ * @return            0 if OK, or negative AVERROR code on failure
+ */
+int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples);
+
+/**
+ * Reset the AVAudioFifo buffer.
+ *
+ * This empties all data in the buffer.
+ *
+ * @param af  AVAudioFifo to reset
+ */
+void av_audio_fifo_reset(AVAudioFifo *af);
+
+/**
+ * Get the current number of samples in the AVAudioFifo available for reading.
+ *
+ * @param af  the AVAudioFifo to query
+ * @return    number of samples available for reading
+ */
+int av_audio_fifo_size(AVAudioFifo *af);
+
+/**
+ * Get the current number of samples in the AVAudioFifo available for writing.
+ *
+ * @param af  the AVAudioFifo to query
+ * @return    number of samples available for writing
+ */
+int av_audio_fifo_space(AVAudioFifo *af);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_AUDIO_FIFO_H */
diff --git a/extra_lib/include/libavutil/audioconvert.h b/extra_lib/include/libavutil/audioconvert.h
new file mode 100644 (file)
index 0000000..76eb278
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2008 Peter Ross
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AUDIOCONVERT_H
+#define AVUTIL_AUDIOCONVERT_H
+
+#include <stdint.h>
+
+/**
+ * @file
+ * audio conversion routines
+ */
+
+/**
+ * @addtogroup lavu_audio
+ * @{
+ */
+
+/**
+ * @defgroup channel_masks Audio channel masks
+ * @{
+ */
+#define AV_CH_FRONT_LEFT             0x00000001
+#define AV_CH_FRONT_RIGHT            0x00000002
+#define AV_CH_FRONT_CENTER           0x00000004
+#define AV_CH_LOW_FREQUENCY          0x00000008
+#define AV_CH_BACK_LEFT              0x00000010
+#define AV_CH_BACK_RIGHT             0x00000020
+#define AV_CH_FRONT_LEFT_OF_CENTER   0x00000040
+#define AV_CH_FRONT_RIGHT_OF_CENTER  0x00000080
+#define AV_CH_BACK_CENTER            0x00000100
+#define AV_CH_SIDE_LEFT              0x00000200
+#define AV_CH_SIDE_RIGHT             0x00000400
+#define AV_CH_TOP_CENTER             0x00000800
+#define AV_CH_TOP_FRONT_LEFT         0x00001000
+#define AV_CH_TOP_FRONT_CENTER       0x00002000
+#define AV_CH_TOP_FRONT_RIGHT        0x00004000
+#define AV_CH_TOP_BACK_LEFT          0x00008000
+#define AV_CH_TOP_BACK_CENTER        0x00010000
+#define AV_CH_TOP_BACK_RIGHT         0x00020000
+#define AV_CH_STEREO_LEFT            0x20000000  ///< Stereo downmix.
+#define AV_CH_STEREO_RIGHT           0x40000000  ///< See AV_CH_STEREO_LEFT.
+#define AV_CH_WIDE_LEFT              0x0000000080000000ULL
+#define AV_CH_WIDE_RIGHT             0x0000000100000000ULL
+#define AV_CH_SURROUND_DIRECT_LEFT   0x0000000200000000ULL
+#define AV_CH_SURROUND_DIRECT_RIGHT  0x0000000400000000ULL
+#define AV_CH_LOW_FREQUENCY_2        0x0000000800000000ULL
+
+/** Channel mask value used for AVCodecContext.request_channel_layout
+    to indicate that the user requests the channel order of the decoder output
+    to be the native codec channel order. */
+#define AV_CH_LAYOUT_NATIVE          0x8000000000000000ULL
+
+/**
+ * @}
+ * @defgroup channel_mask_c Audio channel convenience macros
+ * @{
+ * */
+#define AV_CH_LAYOUT_MONO              (AV_CH_FRONT_CENTER)
+#define AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
+#define AV_CH_LAYOUT_2POINT1           (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_2_1               (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_SURROUND          (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)
+#define AV_CH_LAYOUT_3POINT1           (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_4POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_4POINT1           (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_2_2               (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
+#define AV_CH_LAYOUT_QUAD              (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_5POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
+#define AV_CH_LAYOUT_5POINT1           (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_5POINT0_BACK      (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_5POINT1_BACK      (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_6POINT0           (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT0_FRONT     (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_HEXAGONAL         (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT1           (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT1_BACK      (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT1_FRONT     (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_7POINT0           (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_7POINT0_FRONT     (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_7POINT1           (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_7POINT1_WIDE      (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_7POINT1_WIDE_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_OCTAGONAL         (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_STEREO_DOWNMIX    (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT)
+
+enum AVMatrixEncoding {
+    AV_MATRIX_ENCODING_NONE,
+    AV_MATRIX_ENCODING_DOLBY,
+    AV_MATRIX_ENCODING_DPLII,
+    AV_MATRIX_ENCODING_NB
+};
+
+/**
+ * @}
+ */
+
+/**
+ * Return a channel layout id that matches name, or 0 if no match is found.
+ *
+ * name can be one or several of the following notations,
+ * separated by '+' or '|':
+ * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0,
+ *   5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix);
+ * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC,
+ *   SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR);
+ * - a number of channels, in decimal, optionally followed by 'c', yielding
+ *   the default channel layout for that number of channels (@see
+ *   av_get_default_channel_layout);
+ * - a channel layout mask, in hexadecimal starting with "0x" (see the
+ *   AV_CH_* macros).
+ *
+ * Example: "stereo+FC" = "2+FC" = "2c+1c" = "0x7"
+ */
+uint64_t av_get_channel_layout(const char *name);
+
+/**
+ * Return a description of a channel layout.
+ * If nb_channels is <= 0, it is guessed from the channel_layout.
+ *
+ * @param buf put here the string containing the channel layout
+ * @param buf_size size in bytes of the buffer
+ */
+void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout);
+
+struct AVBPrint;
+/**
+ * Append a description of a channel layout to a bprint buffer.
+ */
+void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout);
+
+/**
+ * Return the number of channels in the channel layout.
+ */
+int av_get_channel_layout_nb_channels(uint64_t channel_layout);
+
+/**
+ * Return default channel layout for a given number of channels.
+ */
+int64_t av_get_default_channel_layout(int nb_channels);
+
+/**
+ * Get the index of a channel in channel_layout.
+ *
+ * @param channel a channel layout describing exactly one channel which must be
+ *                present in channel_layout.
+ *
+ * @return index of channel in channel_layout on success, a negative AVERROR
+ *         on error.
+ */
+int av_get_channel_layout_channel_index(uint64_t channel_layout,
+                                        uint64_t channel);
+
+/**
+ * Get the channel with the given index in channel_layout.
+ */
+uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index);
+
+/**
+ * Get the name of a given channel.
+ *
+ * @return channel name on success, NULL on error.
+ */
+const char *av_get_channel_name(uint64_t channel);
+
+/**
+ * Get the description of a given channel.
+ *
+ * @param channel  a channel layout with a single channel
+ * @return  channel description on success, NULL on error
+ */
+const char *av_get_channel_description(uint64_t channel);
+
+/**
+ * Get the value and name of a standard channel layout.
+ *
+ * @param[in]  index   index in an internal list, starting at 0
+ * @param[out] layout  channel layout mask
+ * @param[out] name    name of the layout
+ * @return  0  if the layout exists,
+ *          <0 if index is beyond the limits
+ */
+int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
+                                   const char **name);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_AUDIOCONVERT_H */
diff --git a/extra_lib/include/libavutil/avassert.h b/extra_lib/include/libavutil/avassert.h
new file mode 100644 (file)
index 0000000..e100d0b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * copyright (c) 2010 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * simple assert() macros that are a bit more flexible than ISO C assert().
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef AVUTIL_AVASSERT_H
+#define AVUTIL_AVASSERT_H
+
+#include <stdlib.h>
+#include "avutil.h"
+#include "log.h"
+
+/**
+ * assert() equivalent, that is always enabled.
+ */
+#define av_assert0(cond) do {                                           \
+    if (!(cond)) {                                                      \
+        av_log(NULL, AV_LOG_FATAL, "Assertion %s failed at %s:%d\n",    \
+               AV_STRINGIFY(cond), __FILE__, __LINE__);                 \
+        abort();                                                        \
+    }                                                                   \
+} while (0)
+
+
+/**
+ * assert() equivalent, that does not lie in speed critical code.
+ * These asserts() thus can be enabled without fearing speedloss.
+ */
+#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 0
+#define av_assert1(cond) av_assert0(cond)
+#else
+#define av_assert1(cond) ((void)0)
+#endif
+
+
+/**
+ * assert() equivalent, that does lie in speed critical code.
+ */
+#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
+#define av_assert2(cond) av_assert0(cond)
+#else
+#define av_assert2(cond) ((void)0)
+#endif
+
+#endif /* AVUTIL_AVASSERT_H */
diff --git a/extra_lib/include/libavutil/avconfig.h b/extra_lib/include/libavutil/avconfig.h
new file mode 100644 (file)
index 0000000..2ec333d
--- /dev/null
@@ -0,0 +1,7 @@
+/* Generated by ffconf */
+#ifndef AVUTIL_AVCONFIG_H
+#define AVUTIL_AVCONFIG_H
+#define AV_HAVE_BIGENDIAN 0
+#define AV_HAVE_FAST_UNALIGNED 1
+#define AV_HAVE_INCOMPATIBLE_FORK_ABI 0
+#endif /* AVUTIL_AVCONFIG_H */
diff --git a/extra_lib/include/libavutil/avstring.h b/extra_lib/include/libavutil/avstring.h
new file mode 100644 (file)
index 0000000..f73d6e7
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2007 Mans Rullgard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AVSTRING_H
+#define AVUTIL_AVSTRING_H
+
+#include <stddef.h>
+#include "attributes.h"
+
+/**
+ * @addtogroup lavu_string
+ * @{
+ */
+
+/**
+ * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to
+ * the address of the first character in str after the prefix.
+ *
+ * @param str input string
+ * @param pfx prefix to test
+ * @param ptr updated if the prefix is matched inside str
+ * @return non-zero if the prefix matches, zero otherwise
+ */
+int av_strstart(const char *str, const char *pfx, const char **ptr);
+
+/**
+ * Return non-zero if pfx is a prefix of str independent of case. If
+ * it is, *ptr is set to the address of the first character in str
+ * after the prefix.
+ *
+ * @param str input string
+ * @param pfx prefix to test
+ * @param ptr updated if the prefix is matched inside str
+ * @return non-zero if the prefix matches, zero otherwise
+ */
+int av_stristart(const char *str, const char *pfx, const char **ptr);
+
+/**
+ * Locate the first case-independent occurrence in the string haystack
+ * of the string needle.  A zero-length string needle is considered to
+ * match at the start of haystack.
+ *
+ * This function is a case-insensitive version of the standard strstr().
+ *
+ * @param haystack string to search in
+ * @param needle   string to search for
+ * @return         pointer to the located match within haystack
+ *                 or a null pointer if no match
+ */
+char *av_stristr(const char *haystack, const char *needle);
+
+/**
+ * Copy the string src to dst, but no more than size - 1 bytes, and
+ * null-terminate dst.
+ *
+ * This function is the same as BSD strlcpy().
+ *
+ * @param dst destination buffer
+ * @param src source string
+ * @param size size of destination buffer
+ * @return the length of src
+ *
+ * @warning since the return value is the length of src, src absolutely
+ * _must_ be a properly 0-terminated string, otherwise this will read beyond
+ * the end of the buffer and possibly crash.
+ */
+size_t av_strlcpy(char *dst, const char *src, size_t size);
+
+/**
+ * Append the string src to the string dst, but to a total length of
+ * no more than size - 1 bytes, and null-terminate dst.
+ *
+ * This function is similar to BSD strlcat(), but differs when
+ * size <= strlen(dst).
+ *
+ * @param dst destination buffer
+ * @param src source string
+ * @param size size of destination buffer
+ * @return the total length of src and dst
+ *
+ * @warning since the return value use the length of src and dst, these
+ * absolutely _must_ be a properly 0-terminated strings, otherwise this
+ * will read beyond the end of the buffer and possibly crash.
+ */
+size_t av_strlcat(char *dst, const char *src, size_t size);
+
+/**
+ * Append output to a string, according to a format. Never write out of
+ * the destination buffer, and always put a terminating 0 within
+ * the buffer.
+ * @param dst destination buffer (string to which the output is
+ *  appended)
+ * @param size total size of the destination buffer
+ * @param fmt printf-compatible format string, specifying how the
+ *  following parameters are used
+ * @return the length of the string that would have been generated
+ *  if enough space had been available
+ */
+size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4);
+
+/**
+ * Print arguments following specified format into a large enough auto
+ * allocated buffer. It is similar to GNU asprintf().
+ * @param fmt printf-compatible format string, specifying how the
+ *            following parameters are used.
+ * @return the allocated string
+ * @note You have to free the string yourself with av_free().
+ */
+char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2);
+
+/**
+ * Convert a number to a av_malloced string.
+ */
+char *av_d2str(double d);
+
+/**
+ * Unescape the given string until a non escaped terminating char,
+ * and return the token corresponding to the unescaped string.
+ *
+ * The normal \ and ' escaping is supported. Leading and trailing
+ * whitespaces are removed, unless they are escaped with '\' or are
+ * enclosed between ''.
+ *
+ * @param buf the buffer to parse, buf will be updated to point to the
+ * terminating char
+ * @param term a 0-terminated list of terminating chars
+ * @return the malloced unescaped string, which must be av_freed by
+ * the user, NULL in case of allocation failure
+ */
+char *av_get_token(const char **buf, const char *term);
+
+/**
+ * Split the string into several tokens which can be accessed by
+ * successive calls to av_strtok().
+ *
+ * A token is defined as a sequence of characters not belonging to the
+ * set specified in delim.
+ *
+ * On the first call to av_strtok(), s should point to the string to
+ * parse, and the value of saveptr is ignored. In subsequent calls, s
+ * should be NULL, and saveptr should be unchanged since the previous
+ * call.
+ *
+ * This function is similar to strtok_r() defined in POSIX.1.
+ *
+ * @param s the string to parse, may be NULL
+ * @param delim 0-terminated list of token delimiters, must be non-NULL
+ * @param saveptr user-provided pointer which points to stored
+ * information necessary for av_strtok() to continue scanning the same
+ * string. saveptr is updated to point to the next character after the
+ * first delimiter found, or to NULL if the string was terminated
+ * @return the found token, or NULL when no token is found
+ */
+char *av_strtok(char *s, const char *delim, char **saveptr);
+
+/**
+ * Locale-independent conversion of ASCII characters to uppercase.
+ */
+static inline int av_toupper(int c)
+{
+    if (c >= 'a' && c <= 'z')
+        c ^= 0x20;
+    return c;
+}
+
+/**
+ * Locale-independent conversion of ASCII characters to lowercase.
+ */
+static inline int av_tolower(int c)
+{
+    if (c >= 'A' && c <= 'Z')
+        c ^= 0x20;
+    return c;
+}
+
+/**
+ * Locale-independent case-insensitive compare.
+ * @note This means only ASCII-range characters are case-insensitive
+ */
+int av_strcasecmp(const char *a, const char *b);
+
+/**
+ * Locale-independent case-insensitive compare.
+ * @note This means only ASCII-range characters are case-insensitive
+ */
+int av_strncasecmp(const char *a, const char *b, size_t n);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_AVSTRING_H */
index fac1f5e2dd92153ff2f45a430cd3327217dfb504..ae6eef12454cc942c4bdfebdcc8e1afcf8e5ac20 100644 (file)
 #define AVUTIL_AVUTIL_H
 
 /**
- * @file libavutil/avutil.h
+ * @file
  * external API header
  */
 
+/*
+ * @mainpage
+ *
+ * @section ffmpeg_intro Introduction
+ *
+ * This document describes the usage of the different libraries
+ * provided by FFmpeg.
+ *
+ * @li @ref libavc "libavcodec" encoding/decoding library
+ * @li @subpage libavfilter graph based frame editing library
+ * @li @ref libavf "libavformat" I/O and muxing/demuxing library
+ * @li @ref lavd "libavdevice" special devices muxing/demuxing library
+ * @li @ref lavu "libavutil" common utility library
+ * @li @subpage libpostproc post processing library
+ * @li @subpage libswscale  color conversion and scaling library
+ */
+
+/**
+ * @defgroup lavu Common utility functions
+ *
+ * @brief
+ * libavutil contains the code shared across all the other FFmpeg
+ * libraries
+ *
+ * @note In order to use the functions provided by avutil you must include
+ * the specific header.
+ *
+ * @{
+ *
+ * @defgroup lavu_crypto Crypto and Hashing
+ *
+ * @{
+ * @}
+ *
+ * @defgroup lavu_math Maths
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_string String Manipulation
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_mem Memory Management
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_data Data Structures
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_audio Audio related
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_error Error Codes
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_misc Other
+ *
+ * @{
+ *
+ * @defgroup lavu_internal Internal
+ *
+ * Not exported functions, for internal usage only
+ *
+ * @{
+ *
+ * @}
+ */
+
 
-#define AV_STRINGIFY(s)         AV_TOSTRING(s)
-#define AV_TOSTRING(s) #s
+/**
+ * @addtogroup lavu_ver
+ * @{
+ */
 
-#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c)
-#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c
-#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
+/**
+ * Return the LIBAVUTIL_VERSION_INT constant.
+ */
+unsigned avutil_version(void);
 
-#define LIBAVUTIL_VERSION_MAJOR 50
-#define LIBAVUTIL_VERSION_MINOR  3
-#define LIBAVUTIL_VERSION_MICRO  0
+/**
+ * Return the libavutil build-time configuration.
+ */
+const char *avutil_configuration(void);
 
-#define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-                                               LIBAVUTIL_VERSION_MINOR, \
-                                               LIBAVUTIL_VERSION_MICRO)
-#define LIBAVUTIL_VERSION       AV_VERSION(LIBAVUTIL_VERSION_MAJOR,     \
-                                           LIBAVUTIL_VERSION_MINOR,     \
-                                           LIBAVUTIL_VERSION_MICRO)
-#define LIBAVUTIL_BUILD         LIBAVUTIL_VERSION_INT
+/**
+ * Return the libavutil license.
+ */
+const char *avutil_license(void);
 
-#define LIBAVUTIL_IDENT         "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
+/**
+ * @}
+ */
 
 /**
- * Returns the LIBAVUTIL_VERSION_INT constant.
+ * @addtogroup lavu_media Media Type
+ * @brief Media Type
+ */
+
+enum AVMediaType {
+    AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATA
+    AVMEDIA_TYPE_VIDEO,
+    AVMEDIA_TYPE_AUDIO,
+    AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuous
+    AVMEDIA_TYPE_SUBTITLE,
+    AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparse
+    AVMEDIA_TYPE_NB
+};
+
+/**
+ * Return a string describing the media_type enum, NULL if media_type
+ * is unknown.
+ */
+const char *av_get_media_type_string(enum AVMediaType media_type);
+
+/**
+ * @defgroup lavu_const Constants
+ * @{
+ *
+ * @defgroup lavu_enc Encoding specific
+ *
+ * @note those definition should move to avcodec
+ * @{
+ */
+
+#define FF_LAMBDA_SHIFT 7
+#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT)
+#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda
+#define FF_LAMBDA_MAX (256*128-1)
+
+#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove
+
+/**
+ * @}
+ * @defgroup lavu_time Timestamp specific
+ *
+ * FFmpeg internal timebase and timestamp definitions
+ *
+ * @{
+ */
+
+/**
+ * @brief Undefined timestamp value
+ *
+ * Usually reported by demuxer that work on containers that do not provide
+ * either pts or dts.
+ */
+
+#define AV_NOPTS_VALUE          ((int64_t)UINT64_C(0x8000000000000000))
+
+/**
+ * Internal time base represented as integer
+ */
+
+#define AV_TIME_BASE            1000000
+
+/**
+ * Internal time base represented as fractional value
+ */
+
+#define AV_TIME_BASE_Q          (AVRational){1, AV_TIME_BASE}
+
+/**
+ * @}
+ * @}
+ * @defgroup lavu_picture Image related
+ *
+ * AVPicture types, pixel formats and basic image planes manipulation.
+ *
+ * @{
+ */
+
+enum AVPictureType {
+    AV_PICTURE_TYPE_NONE = 0, ///< Undefined
+    AV_PICTURE_TYPE_I,     ///< Intra
+    AV_PICTURE_TYPE_P,     ///< Predicted
+    AV_PICTURE_TYPE_B,     ///< Bi-dir predicted
+    AV_PICTURE_TYPE_S,     ///< S(GMC)-VOP MPEG4
+    AV_PICTURE_TYPE_SI,    ///< Switching Intra
+    AV_PICTURE_TYPE_SP,    ///< Switching Predicted
+    AV_PICTURE_TYPE_BI,    ///< BI type
+};
+
+/**
+ * Return a single letter to describe the given picture type
+ * pict_type.
+ *
+ * @param[in] pict_type the picture type @return a single character
+ * representing the picture type, '?' if pict_type is unknown
+ */
+char av_get_picture_type_char(enum AVPictureType pict_type);
+
+/**
+ * @}
  */
-unsigned avutil_version(void);
 
 #include "common.h"
+#include "error.h"
+#include "version.h"
 #include "mathematics.h"
 #include "rational.h"
 #include "intfloat_readwrite.h"
 #include "log.h"
 #include "pixfmt.h"
 
+/**
+ * Return x default pointer in case p is NULL.
+ */
+static inline void *av_x_if_null(const void *p, const void *x)
+{
+    return (void *)(intptr_t)(p ? p : x);
+}
+
+/**
+ * @}
+ * @}
+ */
+
 #endif /* AVUTIL_AVUTIL_H */
diff --git a/extra_lib/include/libavutil/base64.h b/extra_lib/include/libavutil/base64.h
new file mode 100644 (file)
index 0000000..b095576
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_BASE64_H
+#define AVUTIL_BASE64_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_base64 Base64
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+
+/**
+ * Decode a base64-encoded string.
+ *
+ * @param out      buffer for decoded data
+ * @param in       null-terminated input string
+ * @param out_size size in bytes of the out buffer, must be at
+ *                 least 3/4 of the length of in
+ * @return         number of bytes written, or a negative value in case of
+ *                 invalid input
+ */
+int av_base64_decode(uint8_t *out, const char *in, int out_size);
+
+/**
+ * Encode data to base64 and null-terminate.
+ *
+ * @param out      buffer for encoded data
+ * @param out_size size in bytes of the output buffer, must be at
+ *                 least AV_BASE64_SIZE(in_size)
+ * @param in_size  size in bytes of the 'in' buffer
+ * @return         'out' or NULL in case of error
+ */
+char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size);
+
+/**
+ * Calculate the output size needed to base64-encode x bytes.
+ */
+#define AV_BASE64_SIZE(x)  (((x)+2) / 3 * 4 + 1)
+
+ /**
+  * @}
+  */
+
+#endif /* AVUTIL_BASE64_H */
diff --git a/extra_lib/include/libavutil/blowfish.h b/extra_lib/include/libavutil/blowfish.h
new file mode 100644 (file)
index 0000000..0b00453
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Blowfish algorithm
+ * Copyright (c) 2012 Samuel Pitoiset
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_BLOWFISH_H
+#define AVUTIL_BLOWFISH_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_blowfish Blowfish
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+#define AV_BF_ROUNDS 16
+
+typedef struct AVBlowfish {
+    uint32_t p[AV_BF_ROUNDS + 2];
+    uint32_t s[4][256];
+} AVBlowfish;
+
+/**
+ * Initialize an AVBlowfish context.
+ *
+ * @param ctx an AVBlowfish context
+ * @param key a key
+ * @param key_len length of the key
+ */
+void av_blowfish_init(struct AVBlowfish *ctx, const uint8_t *key, int key_len);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ *
+ * @param ctx an AVBlowfish context
+ * @param xl left four bytes halves of input to be encrypted
+ * @param xr right four bytes halves of input to be encrypted
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_blowfish_crypt_ecb(struct AVBlowfish *ctx, uint32_t *xl, uint32_t *xr,
+                           int decrypt);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ *
+ * @param ctx an AVBlowfish context
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param count number of 8 byte blocks
+ * @param iv initialization vector for CBC mode, if NULL ECB will be used
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_blowfish_crypt(struct AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
+                       int count, uint8_t *iv, int decrypt);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_BLOWFISH_H */
diff --git a/extra_lib/include/libavutil/bprint.h b/extra_lib/include/libavutil/bprint.h
new file mode 100644 (file)
index 0000000..2bef18d
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012 Nicolas George
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_BPRINT_H
+#define AVUTIL_BPRINT_H
+
+#include "attributes.h"
+
+/**
+ * Define a structure with extra padding to a fixed size
+ * This helps ensuring binary compatibility with future versions.
+ */
+#define FF_PAD_STRUCTURE(size, ...) \
+    __VA_ARGS__ \
+    char reserved_padding[size - sizeof(struct { __VA_ARGS__ })];
+
+/**
+ * Buffer to print data progressively
+ *
+ * The string buffer grows as necessary and is always 0-terminated.
+ * The content of the string is never accessed, and thus is
+ * encoding-agnostic and can even hold binary data.
+ *
+ * Small buffers are kept in the structure itself, and thus require no
+ * memory allocation at all (unless the contents of the buffer is needed
+ * after the structure goes out of scope). This is almost as lightweight as
+ * declaring a local "char buf[512]".
+ *
+ * The length of the string can go beyond the allocated size: the buffer is
+ * then truncated, but the functions still keep account of the actual total
+ * length.
+ *
+ * In other words, buf->len can be greater than buf->size and records the
+ * total length of what would have been to the buffer if there had been
+ * enough memory.
+ *
+ * Append operations do not need to be tested for failure: if a memory
+ * allocation fails, data stop being appended to the buffer, but the length
+ * is still updated. This situation can be tested with
+ * av_bprint_is_complete().
+ *
+ * The size_max field determines several possible behaviours:
+ *
+ * size_max = -1 (= UINT_MAX) or any large value will let the buffer be
+ * reallocated as necessary, with an amortized linear cost.
+ *
+ * size_max = 0 prevents writing anything to the buffer: only the total
+ * length is computed. The write operations can then possibly be repeated in
+ * a buffer with exactly the necessary size
+ * (using size_init = size_max = len + 1).
+ *
+ * size_max = 1 is automatically replaced by the exact size available in the
+ * structure itself, thus ensuring no dynamic memory allocation. The
+ * internal buffer is large enough to hold a reasonable paragraph of text,
+ * such as the current paragraph.
+ */
+typedef struct AVBPrint {
+    FF_PAD_STRUCTURE(1024,
+    char *str;         /** string so far */
+    unsigned len;      /** length so far */
+    unsigned size;     /** allocated memory */
+    unsigned size_max; /** maximum allocated memory */
+    char reserved_internal_buffer[1];
+    )
+} AVBPrint;
+
+/**
+ * Convenience macros for special values for av_bprint_init() size_max
+ * parameter.
+ */
+#define AV_BPRINT_SIZE_UNLIMITED  ((unsigned)-1)
+#define AV_BPRINT_SIZE_AUTOMATIC  1
+#define AV_BPRINT_SIZE_COUNT_ONLY 0
+
+/**
+ * Init a print buffer.
+ *
+ * @param buf        buffer to init
+ * @param size_init  initial size (including the final 0)
+ * @param size_max   maximum size;
+ *                   0 means do not write anything, just count the length;
+ *                   1 is replaced by the maximum value for automatic storage;
+ *                   any large value means that the internal buffer will be
+ *                   reallocated as needed up to that limit; -1 is converted to
+ *                   UINT_MAX, the largest limit possible.
+ *                   Check also AV_BPRINT_SIZE_* macros.
+ */
+void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max);
+
+/**
+ * Init a print buffer using a pre-existing buffer.
+ *
+ * The buffer will not be reallocated.
+ *
+ * @param buf     buffer structure to init
+ * @param buffer  byte buffer to use for the string data
+ * @param size    size of buffer
+ */
+void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size);
+
+/**
+ * Append a formated string to a print buffer.
+ */
+void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
+
+/**
+ * Append char c n times to a print buffer.
+ */
+void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
+
+/**
+ * Reset the string to "" but keep internal allocated data.
+ */
+void av_bprint_clear(AVBPrint *buf);
+
+/**
+ * Test if the print buffer is complete (not truncated).
+ *
+ * It may have been truncated due to a memory allocation failure
+ * or the size_max limit (compare size and size_max if necessary).
+ */
+static inline int av_bprint_is_complete(AVBPrint *buf)
+{
+    return buf->len < buf->size;
+}
+
+/**
+ * Finalize a print buffer.
+ *
+ * The print buffer can no longer be used afterwards,
+ * but the len and size fields are still valid.
+ *
+ * @arg[out] ret_str  if not NULL, used to return a permanent copy of the
+ *                    buffer contents, or NULL if memory allocation fails;
+ *                    if NULL, the buffer is discarded and freed
+ * @return  0 for success or error code (probably AVERROR(ENOMEM))
+ */
+int av_bprint_finalize(AVBPrint *buf, char **ret_str);
+
+#endif /* AVUTIL_BPRINT_H */
diff --git a/extra_lib/include/libavutil/bswap.h b/extra_lib/include/libavutil/bswap.h
new file mode 100644 (file)
index 0000000..06f6548
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * byte swapping routines
+ */
+
+#ifndef AVUTIL_BSWAP_H
+#define AVUTIL_BSWAP_H
+
+#include <stdint.h>
+#include "libavutil/avconfig.h"
+#include "attributes.h"
+
+#ifdef HAVE_AV_CONFIG_H
+
+#include "config.h"
+
+#if   ARCH_ARM
+#   include "arm/bswap.h"
+#elif ARCH_AVR32
+#   include "avr32/bswap.h"
+#elif ARCH_BFIN
+#   include "bfin/bswap.h"
+#elif ARCH_SH4
+#   include "sh4/bswap.h"
+#elif ARCH_X86
+#   include "x86/bswap.h"
+#endif
+
+#endif /* HAVE_AV_CONFIG_H */
+
+#define AV_BSWAP16C(x) (((x) << 8 & 0xff00)  | ((x) >> 8 & 0x00ff))
+#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16))
+#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32))
+
+#define AV_BSWAPC(s, x) AV_BSWAP##s##C(x)
+
+#ifndef av_bswap16
+static av_always_inline av_const uint16_t av_bswap16(uint16_t x)
+{
+    x= (x>>8) | (x<<8);
+    return x;
+}
+#endif
+
+#ifndef av_bswap32
+static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
+{
+    return AV_BSWAP32C(x);
+}
+#endif
+
+#ifndef av_bswap64
+static inline uint64_t av_const av_bswap64(uint64_t x)
+{
+    return (uint64_t)av_bswap32(x) << 32 | av_bswap32(x >> 32);
+}
+#endif
+
+// be2ne ... big-endian to native-endian
+// le2ne ... little-endian to native-endian
+
+#if AV_HAVE_BIGENDIAN
+#define av_be2ne16(x) (x)
+#define av_be2ne32(x) (x)
+#define av_be2ne64(x) (x)
+#define av_le2ne16(x) av_bswap16(x)
+#define av_le2ne32(x) av_bswap32(x)
+#define av_le2ne64(x) av_bswap64(x)
+#define AV_BE2NEC(s, x) (x)
+#define AV_LE2NEC(s, x) AV_BSWAPC(s, x)
+#else
+#define av_be2ne16(x) av_bswap16(x)
+#define av_be2ne32(x) av_bswap32(x)
+#define av_be2ne64(x) av_bswap64(x)
+#define av_le2ne16(x) (x)
+#define av_le2ne32(x) (x)
+#define av_le2ne64(x) (x)
+#define AV_BE2NEC(s, x) AV_BSWAPC(s, x)
+#define AV_LE2NEC(s, x) (x)
+#endif
+
+#define AV_BE2NE16C(x) AV_BE2NEC(16, x)
+#define AV_BE2NE32C(x) AV_BE2NEC(32, x)
+#define AV_BE2NE64C(x) AV_BE2NEC(64, x)
+#define AV_LE2NE16C(x) AV_LE2NEC(16, x)
+#define AV_LE2NE32C(x) AV_LE2NEC(32, x)
+#define AV_LE2NE64C(x) AV_LE2NEC(64, x)
+
+#endif /* AVUTIL_BSWAP_H */
index 32f2104c1056ff5182f6db2e3ae1764edfc2eec2..9ed6f11468d1416f2fd31f49f39c1e23280d2877 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 /**
- * @file libavutil/common.h
+ * @file
  * common internal and external API header
  */
 
 
 #include <ctype.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#if !defined(EMULATE_INTTYPES)
-#      include <inttypes.h>
-#else
-       typedef signed char  int8_t;
-       typedef signed short int16_t;
-       typedef signed int   int32_t;
-       typedef unsigned char  uint8_t;
-       typedef unsigned short uint16_t;
-       typedef unsigned int   uint32_t;
-
-#      ifdef CONFIG_WIN32
-               typedef signed __int64   int64_t;
-               typedef unsigned __int64 uint64_t;
-#      else /* other OS */
-               typedef signed long long   int64_t;
-               typedef unsigned long long uint64_t;
-#      endif /* other OS */
-#endif /* HAVE_INTTYPES_H */
-
-
-#ifndef INT64_C
-# ifdef CONFIG_MSVC
-#  define INT64_C(x)  (x ## i64)
-#  define UINT64_C(x)  (x ## Ui64)
-# else
-#  define INT64_C(x)  (x ## LL)
-#  define UINT64_C(x)  (x ## ULL)
-# endif
-#endif
-
-#ifdef __GNUC__
-#    define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
-#else
-#    define AV_GCC_VERSION_AT_LEAST(x,y) 0
-#endif
-
-#ifndef av_always_inline
-#if AV_GCC_VERSION_AT_LEAST(3,1)
-#    define av_always_inline __attribute__((always_inline)) inline
-#else
-#    define av_always_inline inline
-#endif
-#endif
-
-#ifndef av_noinline
-#if AV_GCC_VERSION_AT_LEAST(3,1)
-#    define av_noinline __attribute__((noinline))
-#else
-#    define av_noinline
-#endif
-#endif
-
-#ifndef av_pure
-#if AV_GCC_VERSION_AT_LEAST(3,1)
-#    define av_pure __attribute__((pure))
-#else
-#    define av_pure
-#endif
-#endif
-
-#ifndef av_const
-#if AV_GCC_VERSION_AT_LEAST(2,6)
-#    define av_const __attribute__((const))
-#else
-#    define av_const
-#endif
-#endif
-
-#ifndef av_cold
-#if (!defined(__ICC) || __ICC > 1100) && AV_GCC_VERSION_AT_LEAST(4,3)
-#    define av_cold __attribute__((cold))
-#else
-#    define av_cold
-#endif
-#endif
-
-#ifndef av_flatten
-#if AV_GCC_VERSION_AT_LEAST(4,1)
-#    define av_flatten __attribute__((flatten))
-#else
-#    define av_flatten
-#endif
-#endif
+#include "attributes.h"
+#include "version.h"
+#include "libavutil/avconfig.h"
 
-#ifndef attribute_deprecated
-#if AV_GCC_VERSION_AT_LEAST(3,1)
-#    define attribute_deprecated __attribute__((deprecated))
+#if AV_HAVE_BIGENDIAN
+#   define AV_NE(be, le) (be)
 #else
-#    define attribute_deprecated
-#endif
-#endif
-
-#ifndef av_unused
-#if defined(__GNUC__)
-#    define av_unused __attribute__((unused))
-#else
-#    define av_unused
-#endif
-#endif
-
-#ifndef av_uninit
-#if defined(__GNUC__) && !defined(__ICC)
-#    define av_uninit(x) x=x
-#else
-#    define av_uninit(x) x
-#endif
+#   define AV_NE(be, le) (le)
 #endif
 
 //rounded division & shift
 #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
 /* assume b>0 */
 #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
+#define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b))
+#define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b))
 #define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
 #define FFSIGN(a) ((a) > 0 ? 1 : -1)
 
 /* misc math functions */
 extern const uint8_t ff_log2_tab[256];
 
-static inline av_const int av_log2(unsigned int v)
+/**
+ * Reverse the order of the bits of an 8-bits unsigned integer.
+ */
+#if FF_API_AV_REVERSE
+extern attribute_deprecated const uint8_t av_reverse[256];
+#endif
+
+static av_always_inline av_const int av_log2_c(unsigned int v)
 {
     int n = 0;
     if (v & 0xffff0000) {
@@ -177,7 +89,7 @@ static inline av_const int av_log2(unsigned int v)
     return n;
 }
 
-static inline av_const int av_log2_16bit(unsigned int v)
+static av_always_inline av_const int av_log2_16bit_c(unsigned int v)
 {
     int n = 0;
     if (v & 0xff00) {
@@ -189,14 +101,22 @@ static inline av_const int av_log2_16bit(unsigned int v)
     return n;
 }
 
+#ifdef HAVE_AV_CONFIG_H
+#   include "config.h"
+#   include "intmath.h"
+#endif
+
+/* Pull in unguarded fallback defines at the end of this file. */
+#include "common.h"
+
 /**
- * Clips a signed integer value into the amin-amax range.
+ * Clip a signed integer value into the amin-amax range.
  * @param a value to clip
  * @param amin minimum value of the clip range
  * @param amax maximum value of the clip range
  * @return clipped value
  */
-static inline av_const int av_clip(int a, int amin, int amax)
+static av_always_inline av_const int av_clip_c(int a, int amin, int amax)
 {
     if      (a < amin) return amin;
     else if (a > amax) return amax;
@@ -204,56 +124,156 @@ static inline av_const int av_clip(int a, int amin, int amax)
 }
 
 /**
- * Clips a signed integer value into the 0-255 range.
+ * Clip a signed integer value into the 0-255 range.
  * @param a value to clip
  * @return clipped value
  */
-static inline av_const uint8_t av_clip_uint8(int a)
+static av_always_inline av_const uint8_t av_clip_uint8_c(int a)
 {
-    if (a&(~255)) return (-a)>>31;
-    else          return a;
+    if (a&(~0xFF)) return (-a)>>31;
+    else           return a;
 }
 
 /**
- * Clips a signed integer value into the -32768,32767 range.
+ * Clip a signed integer value into the -128,127 range.
  * @param a value to clip
  * @return clipped value
  */
-static inline av_const int16_t av_clip_int16(int a)
+static av_always_inline av_const int8_t av_clip_int8_c(int a)
 {
-    if ((a+32768) & ~65535) return (a>>31) ^ 32767;
-    else                    return a;
+    if ((a+0x80) & ~0xFF) return (a>>31) ^ 0x7F;
+    else                  return a;
 }
 
 /**
- * Clips a float value into the amin-amax range.
+ * Clip a signed integer value into the 0-65535 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static av_always_inline av_const uint16_t av_clip_uint16_c(int a)
+{
+    if (a&(~0xFFFF)) return (-a)>>31;
+    else             return a;
+}
+
+/**
+ * Clip a signed integer value into the -32768,32767 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static av_always_inline av_const int16_t av_clip_int16_c(int a)
+{
+    if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF;
+    else                      return a;
+}
+
+/**
+ * Clip a signed 64-bit integer value into the -2147483648,2147483647 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a)
+{
+    if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF;
+    else                                         return (int32_t)a;
+}
+
+/**
+ * Clip a signed integer to an unsigned power of two range.
+ * @param  a value to clip
+ * @param  p bit position to clip at
+ * @return clipped value
+ */
+static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
+{
+    if (a & ~((1<<p) - 1)) return -a >> 31 & ((1<<p) - 1);
+    else                   return  a;
+}
+
+/**
+ * Add two signed 32-bit values with saturation.
+ *
+ * @param  a one value
+ * @param  b another value
+ * @return sum with signed saturation
+ */
+static av_always_inline int av_sat_add32_c(int a, int b)
+{
+    return av_clipl_int32((int64_t)a + b);
+}
+
+/**
+ * Add a doubled value to another value with saturation at both stages.
+ *
+ * @param  a first value
+ * @param  b value doubled and added to a
+ * @return sum with signed saturation
+ */
+static av_always_inline int av_sat_dadd32_c(int a, int b)
+{
+    return av_sat_add32(a, av_sat_add32(b, b));
+}
+
+/**
+ * Clip a float value into the amin-amax range.
  * @param a value to clip
  * @param amin minimum value of the clip range
  * @param amax maximum value of the clip range
  * @return clipped value
  */
-static inline av_const float av_clipf(float a, float amin, float amax)
+static av_always_inline av_const float av_clipf_c(float a, float amin, float amax)
 {
     if      (a < amin) return amin;
     else if (a > amax) return amax;
     else               return a;
 }
 
-#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
-#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
-
-/*!
- * \def GET_UTF8(val, GET_BYTE, ERROR)
- * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form
- * \param val is the output and should be of type uint32_t. It holds the converted
- * UCS-4 character and should be a left value.
- * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be
- * a function or a statement whose return value or evaluated value is of type
- * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range,
- * and up to 7 times in the general case.
- * \param ERROR action that should be taken when an invalid UTF-8 byte is returned
- * from GET_BYTE. It should be a statement that jumps out of the macro,
- * like exit(), goto, return, break, or continue.
+/** Compute ceil(log2(x)).
+ * @param x value used to compute ceil(log2(x))
+ * @return computed ceiling of log2(x)
+ */
+static av_always_inline av_const int av_ceil_log2_c(int x)
+{
+    return av_log2((x - 1) << 1);
+}
+
+/**
+ * Count number of bits set to one in x
+ * @param x value to count bits of
+ * @return the number of bits set to one in x
+ */
+static av_always_inline av_const int av_popcount_c(uint32_t x)
+{
+    x -= (x >> 1) & 0x55555555;
+    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+    x = (x + (x >> 4)) & 0x0F0F0F0F;
+    x += x >> 8;
+    return (x + (x >> 16)) & 0x3F;
+}
+
+/**
+ * Count number of bits set to one in x
+ * @param x value to count bits of
+ * @return the number of bits set to one in x
+ */
+static av_always_inline av_const int av_popcount64_c(uint64_t x)
+{
+    return av_popcount((uint32_t)x) + av_popcount(x >> 32);
+}
+
+#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))
+#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
+
+/**
+ * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val      Output value, must be an lvalue of type uint32_t.
+ * @param GET_BYTE Expression reading one byte from the input.
+ *                 Evaluated up to 7 times (4 for the currently
+ *                 assigned Unicode range).  With a memory buffer
+ *                 input, this could be *ptr++.
+ * @param ERROR    Expression to be evaluated on invalid input,
+ *                 typically a goto statement.
  */
 #define GET_UTF8(val, GET_BYTE, ERROR)\
     val= GET_BYTE;\
@@ -270,16 +290,37 @@ static inline av_const float av_clipf(float a, float amin, float amax)
         }\
     }
 
-/*!
- * \def PUT_UTF8(val, tmp, PUT_BYTE)
- * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
- * \param val is an input-only argument and should be of type uint32_t. It holds
+/**
+ * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val       Output value, must be an lvalue of type uint32_t.
+ * @param GET_16BIT Expression returning two bytes of UTF-16 data converted
+ *                  to native byte order.  Evaluated one or two times.
+ * @param ERROR     Expression to be evaluated on invalid input,
+ *                  typically a goto statement.
+ */
+#define GET_UTF16(val, GET_16BIT, ERROR)\
+    val = GET_16BIT;\
+    {\
+        unsigned int hi = val - 0xD800;\
+        if (hi < 0x800) {\
+            val = GET_16BIT - 0xDC00;\
+            if (val > 0x3FFU || hi > 0x3FFU)\
+                ERROR\
+            val += (hi<<10) + 0x10000;\
+        }\
+    }\
+
+/**
+ * @def PUT_UTF8(val, tmp, PUT_BYTE)
+ * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
+ * @param val is an input-only argument and should be of type uint32_t. It holds
  * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If
  * val is given as a function it is executed only once.
- * \param tmp is a temporary variable and should be of type uint8_t. It
+ * @param tmp is a temporary variable and should be of type uint8_t. It
  * represents an intermediate value during conversion that is to be
  * output by PUT_BYTE.
- * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
+ * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
  * It could be a function or a statement, and uses tmp as the input byte.
  * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
  * executed up to 4 times for values in the valid UTF-8 range and up to
@@ -306,11 +347,91 @@ static inline av_const float av_clipf(float a, float amin, float amax)
         }\
     }
 
+/**
+ * @def PUT_UTF16(val, tmp, PUT_16BIT)
+ * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
+ * @param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If
+ * val is given as a function it is executed only once.
+ * @param tmp is a temporary variable and should be of type uint16_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_16BIT.
+ * @param PUT_16BIT writes the converted UTF-16 data to any proper destination
+ * in desired endianness. It could be a function or a statement, and uses tmp
+ * as the input byte.  For example, PUT_BYTE could be "*output++ = tmp;"
+ * PUT_BYTE will be executed 1 or 2 times depending on input character.
+ */
+#define PUT_UTF16(val, tmp, PUT_16BIT)\
+    {\
+        uint32_t in = val;\
+        if (in < 0x10000) {\
+            tmp = in;\
+            PUT_16BIT\
+        } else {\
+            tmp = 0xD800 | ((in - 0x10000) >> 10);\
+            PUT_16BIT\
+            tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\
+            PUT_16BIT\
+        }\
+    }\
+
+
+
 #include "mem.h"
 
 #ifdef HAVE_AV_CONFIG_H
-#    include "config.h"
 #    include "internal.h"
 #endif /* HAVE_AV_CONFIG_H */
 
 #endif /* AVUTIL_COMMON_H */
+
+/*
+ * The following definitions are outside the multiple inclusion guard
+ * to ensure they are immediately available in intmath.h.
+ */
+
+#ifndef av_log2
+#   define av_log2       av_log2_c
+#endif
+#ifndef av_log2_16bit
+#   define av_log2_16bit av_log2_16bit_c
+#endif
+#ifndef av_ceil_log2
+#   define av_ceil_log2     av_ceil_log2_c
+#endif
+#ifndef av_clip
+#   define av_clip          av_clip_c
+#endif
+#ifndef av_clip_uint8
+#   define av_clip_uint8    av_clip_uint8_c
+#endif
+#ifndef av_clip_int8
+#   define av_clip_int8     av_clip_int8_c
+#endif
+#ifndef av_clip_uint16
+#   define av_clip_uint16   av_clip_uint16_c
+#endif
+#ifndef av_clip_int16
+#   define av_clip_int16    av_clip_int16_c
+#endif
+#ifndef av_clipl_int32
+#   define av_clipl_int32   av_clipl_int32_c
+#endif
+#ifndef av_clip_uintp2
+#   define av_clip_uintp2   av_clip_uintp2_c
+#endif
+#ifndef av_sat_add32
+#   define av_sat_add32     av_sat_add32_c
+#endif
+#ifndef av_sat_dadd32
+#   define av_sat_dadd32    av_sat_dadd32_c
+#endif
+#ifndef av_clipf
+#   define av_clipf         av_clipf_c
+#endif
+#ifndef av_popcount
+#   define av_popcount      av_popcount_c
+#endif
+#ifndef av_popcount64
+#   define av_popcount64    av_popcount64_c
+#endif
diff --git a/extra_lib/include/libavutil/cpu.h b/extra_lib/include/libavutil/cpu.h
new file mode 100644 (file)
index 0000000..c8f34e0
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_CPU_H
+#define AVUTIL_CPU_H
+
+#include "attributes.h"
+
+#define AV_CPU_FLAG_FORCE    0x80000000 /* force usage of selected flags (OR) */
+
+    /* lower 16 bits - CPU features */
+#define AV_CPU_FLAG_MMX          0x0001 ///< standard MMX
+#define AV_CPU_FLAG_MMXEXT       0x0002 ///< SSE integer functions or AMD MMX ext
+#define AV_CPU_FLAG_MMX2         0x0002 ///< SSE integer functions or AMD MMX ext
+#define AV_CPU_FLAG_3DNOW        0x0004 ///< AMD 3DNOW
+#define AV_CPU_FLAG_SSE          0x0008 ///< SSE functions
+#define AV_CPU_FLAG_SSE2         0x0010 ///< PIV SSE2 functions
+#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster
+#define AV_CPU_FLAG_3DNOWEXT     0x0020 ///< AMD 3DNowExt
+#define AV_CPU_FLAG_SSE3         0x0040 ///< Prescott SSE3 functions
+#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster
+#define AV_CPU_FLAG_SSSE3        0x0080 ///< Conroe SSSE3 functions
+#define AV_CPU_FLAG_ATOM     0x10000000 ///< Atom processor, some SSSE3 instructions are slower
+#define AV_CPU_FLAG_SSE4         0x0100 ///< Penryn SSE4.1 functions
+#define AV_CPU_FLAG_SSE42        0x0200 ///< Nehalem SSE4.2 functions
+#define AV_CPU_FLAG_AVX          0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
+#define AV_CPU_FLAG_XOP          0x0400 ///< Bulldozer XOP functions
+#define AV_CPU_FLAG_FMA4         0x0800 ///< Bulldozer FMA4 functions
+// #if LIBAVUTIL_VERSION_MAJOR <52
+#define AV_CPU_FLAG_CMOV      0x1001000 ///< supports cmov instruction
+// #else
+// #define AV_CPU_FLAG_CMOV         0x1000 ///< supports cmov instruction
+// #endif
+
+#define AV_CPU_FLAG_ALTIVEC      0x0001 ///< standard
+
+#define AV_CPU_FLAG_ARMV5TE      (1 << 0)
+#define AV_CPU_FLAG_ARMV6        (1 << 1)
+#define AV_CPU_FLAG_ARMV6T2      (1 << 2)
+#define AV_CPU_FLAG_VFP          (1 << 3)
+#define AV_CPU_FLAG_VFPV3        (1 << 4)
+#define AV_CPU_FLAG_NEON         (1 << 5)
+
+/**
+ * Return the flags which specify extensions supported by the CPU.
+ * The returned value is affected by av_force_cpu_flags() if that was used
+ * before. So av_get_cpu_flags() can easily be used in a application to
+ * detect the enabled cpu flags.
+ */
+int av_get_cpu_flags(void);
+
+/**
+ * Disables cpu detection and forces the specified flags.
+ * -1 is a special case that disables forcing of specific flags.
+ */
+void av_force_cpu_flags(int flags);
+
+/**
+ * Set a mask on flags returned by av_get_cpu_flags().
+ * This function is mainly useful for testing.
+ * Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible
+ *
+ * @warning this function is not thread safe.
+ */
+attribute_deprecated void av_set_cpu_flags_mask(int mask);
+
+/**
+ * Parse CPU flags from a string.
+ *
+ * The returned flags contain the specified flags as well as related unspecified flags.
+ *
+ * This function exists only for compatibility with libav.
+ * Please use av_parse_cpu_caps() when possible.
+ * @return a combination of AV_CPU_* flags, negative on error.
+ */
+attribute_deprecated
+int av_parse_cpu_flags(const char *s);
+
+/**
+ * Parse CPU caps from a string and update the given AV_CPU_* flags based on that.
+ *
+ * @return negative on error.
+ */
+int av_parse_cpu_caps(unsigned *flags, const char *s);
+
+/* The following CPU-specific functions shall not be called directly. */
+int ff_get_cpu_flags_arm(void);
+int ff_get_cpu_flags_ppc(void);
+int ff_get_cpu_flags_x86(void);
+
+#endif /* AVUTIL_CPU_H */
diff --git a/extra_lib/include/libavutil/crc.h b/extra_lib/include/libavutil/crc.h
new file mode 100644 (file)
index 0000000..1265054
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_CRC_H
+#define AVUTIL_CRC_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "attributes.h"
+
+typedef uint32_t AVCRC;
+
+typedef enum {
+    AV_CRC_8_ATM,
+    AV_CRC_16_ANSI,
+    AV_CRC_16_CCITT,
+    AV_CRC_32_IEEE,
+    AV_CRC_32_IEEE_LE,  /*< reversed bitorder version of AV_CRC_32_IEEE */
+    AV_CRC_MAX,         /*< Not part of public API! Do not use outside libavutil. */
+}AVCRCId;
+
+int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size);
+const AVCRC *av_crc_get_table(AVCRCId crc_id);
+uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length) av_pure;
+
+#endif /* AVUTIL_CRC_H */
diff --git a/extra_lib/include/libavutil/dict.h b/extra_lib/include/libavutil/dict.h
new file mode 100644 (file)
index 0000000..fde3650
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Public dictionary API.
+ * @deprecated
+ *  AVDictionary is provided for compatibility with libav. It is both in
+ *  implementation as well as API inefficient. It does not scale and is
+ *  extremely slow with large dictionaries.
+ *  It is recommended that new code uses our tree container from tree.c/h
+ *  where applicable, which uses AVL trees to achieve O(log n) performance.
+ */
+
+#ifndef AVUTIL_DICT_H
+#define AVUTIL_DICT_H
+
+/**
+ * @addtogroup lavu_dict AVDictionary
+ * @ingroup lavu_data
+ *
+ * @brief Simple key:value store
+ *
+ * @{
+ * Dictionaries are used for storing key:value pairs. To create
+ * an AVDictionary, simply pass an address of a NULL pointer to
+ * av_dict_set(). NULL can be used as an empty dictionary wherever
+ * a pointer to an AVDictionary is required.
+ * Use av_dict_get() to retrieve an entry or iterate over all
+ * entries and finally av_dict_free() to free the dictionary
+ * and all its contents.
+ *
+ * @code
+ * AVDictionary *d = NULL;                // "create" an empty dictionary
+ * av_dict_set(&d, "foo", "bar", 0);      // add an entry
+ *
+ * char *k = av_strdup("key");            // if your strings are already allocated,
+ * char *v = av_strdup("value");          // you can avoid copying them like this
+ * av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
+ *
+ * AVDictionaryEntry *t = NULL;
+ * while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) {
+ *     <....>                             // iterate over all entries in d
+ * }
+ *
+ * av_dict_free(&d);
+ * @endcode
+ *
+ */
+
+#define AV_DICT_MATCH_CASE      1
+#define AV_DICT_IGNORE_SUFFIX   2
+#define AV_DICT_DONT_STRDUP_KEY 4   /**< Take ownership of a key that's been
+                                         allocated with av_malloc() and children. */
+#define AV_DICT_DONT_STRDUP_VAL 8   /**< Take ownership of a value that's been
+                                         allocated with av_malloc() and chilren. */
+#define AV_DICT_DONT_OVERWRITE 16   ///< Don't overwrite existing entries.
+#define AV_DICT_APPEND         32   /**< If the entry already exists, append to it.  Note that no
+                                      delimiter is added, the strings are simply concatenated. */
+
+typedef struct AVDictionaryEntry {
+    char *key;
+    char *value;
+} AVDictionaryEntry;
+
+typedef struct AVDictionary AVDictionary;
+
+/**
+ * Get a dictionary entry with matching key.
+ *
+ * @param prev Set to the previous matching element to find the next.
+ *             If set to NULL the first matching element is returned.
+ * @param flags Allows case as well as suffix-insensitive comparisons.
+ * @return Found entry or NULL, changing key or value leads to undefined behavior.
+ */
+AVDictionaryEntry *
+av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags);
+
+/**
+ * Get number of entries in dictionary.
+ *
+ * @param m dictionary
+ * @return  number of entries in dictionary
+ */
+int av_dict_count(const AVDictionary *m);
+
+/**
+ * Set the given entry in *pm, overwriting an existing entry.
+ *
+ * @param pm pointer to a pointer to a dictionary struct. If *pm is NULL
+ * a dictionary struct is allocated and put in *pm.
+ * @param key entry key to add to *pm (will be av_strduped depending on flags)
+ * @param value entry value to add to *pm (will be av_strduped depending on flags).
+ *        Passing a NULL value will cause an existing entry to be deleted.
+ * @return >= 0 on success otherwise an error code <0
+ */
+int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags);
+
+/**
+ * Copy entries from one AVDictionary struct into another.
+ * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL,
+ *            this function will allocate a struct for you and put it in *dst
+ * @param src pointer to source AVDictionary struct
+ * @param flags flags to use when setting entries in *dst
+ * @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag
+ */
+void av_dict_copy(AVDictionary **dst, AVDictionary *src, int flags);
+
+/**
+ * Free all the memory allocated for an AVDictionary struct
+ * and all keys and values.
+ */
+void av_dict_free(AVDictionary **m);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_DICT_H */
diff --git a/extra_lib/include/libavutil/error.h b/extra_lib/include/libavutil/error.h
new file mode 100644 (file)
index 0000000..1768167
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * error code definitions
+ */
+
+#ifndef AVUTIL_ERROR_H
+#define AVUTIL_ERROR_H
+
+#include <errno.h>
+#include <stddef.h>
+
+/**
+ * @addtogroup lavu_error
+ *
+ * @{
+ */
+
+
+/* error handling */
+#if EDOM > 0
+#define AVERROR(e) (-(e))   ///< Returns a negative error code from a POSIX error code, to return from library functions.
+#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value.
+#else
+/* Some platforms have E* and errno already negated. */
+#define AVERROR(e) (e)
+#define AVUNERROR(e) (e)
+#endif
+
+#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d))
+
+#define AVERROR_BSF_NOT_FOUND      FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found
+#define AVERROR_BUG                FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2
+#define AVERROR_BUFFER_TOO_SMALL   FFERRTAG( 'B','U','F','S') ///< Buffer too small
+#define AVERROR_DECODER_NOT_FOUND  FFERRTAG(0xF8,'D','E','C') ///< Decoder not found
+#define AVERROR_DEMUXER_NOT_FOUND  FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found
+#define AVERROR_ENCODER_NOT_FOUND  FFERRTAG(0xF8,'E','N','C') ///< Encoder not found
+#define AVERROR_EOF                FFERRTAG( 'E','O','F',' ') ///< End of file
+#define AVERROR_EXIT               FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted
+#define AVERROR_EXTERNAL           FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library
+#define AVERROR_FILTER_NOT_FOUND   FFERRTAG(0xF8,'F','I','L') ///< Filter not found
+#define AVERROR_INVALIDDATA        FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input
+#define AVERROR_MUXER_NOT_FOUND    FFERRTAG(0xF8,'M','U','X') ///< Muxer not found
+#define AVERROR_OPTION_NOT_FOUND   FFERRTAG(0xF8,'O','P','T') ///< Option not found
+#define AVERROR_PATCHWELCOME       FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome
+#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found
+#define AVERROR_STREAM_NOT_FOUND   FFERRTAG(0xF8,'S','T','R') ///< Stream not found
+
+/**
+ * This is semantically identical to AVERROR_BUG
+ * it has been introduced in Libav after our AVERROR_BUG and with a modified value.
+ */
+#define AVERROR_BUG2               FFERRTAG( 'B','U','G',' ')
+#define AVERROR_UNKNOWN            FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library
+
+#define AV_ERROR_MAX_STRING_SIZE 64
+
+/**
+ * Put a description of the AVERROR code errnum in errbuf.
+ * In case of failure the global variable errno is set to indicate the
+ * error. Even in case of failure av_strerror() will print a generic
+ * error message indicating the errnum provided to errbuf.
+ *
+ * @param errnum      error code to describe
+ * @param errbuf      buffer to which description is written
+ * @param errbuf_size the size in bytes of errbuf
+ * @return 0 on success, a negative value if a description for errnum
+ * cannot be found
+ */
+int av_strerror(int errnum, char *errbuf, size_t errbuf_size);
+
+/**
+ * Fill the provided buffer with a string containing an error string
+ * corresponding to the AVERROR code errnum.
+ *
+ * @param errbuf         a buffer
+ * @param errbuf_size    size in bytes of errbuf
+ * @param errnum         error code to describe
+ * @return the buffer in input, filled with the error description
+ * @see av_strerror()
+ */
+static inline char *av_make_error_string(char *errbuf, size_t errbuf_size, int errnum)
+{
+    av_strerror(errnum, errbuf, errbuf_size);
+    return errbuf;
+}
+
+/**
+ * Convenience macro, the return value should be used only directly in
+ * function arguments but never stand-alone.
+ */
+#define av_err2str(errnum) \
+    av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum)
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_ERROR_H */
diff --git a/extra_lib/include/libavutil/eval.h b/extra_lib/include/libavutil/eval.h
new file mode 100644 (file)
index 0000000..22fa121
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * simple arithmetic expression evaluator
+ */
+
+#ifndef AVUTIL_EVAL_H
+#define AVUTIL_EVAL_H
+
+#include "avutil.h"
+
+typedef struct AVExpr AVExpr;
+
+/**
+ * Parse and evaluate an expression.
+ * Note, this is significantly slower than av_expr_eval().
+ *
+ * @param res a pointer to a double where is put the result value of
+ * the expression, or NAN in case of error
+ * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)"
+ * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0}
+ * @param const_values a zero terminated array of values for the identifiers from const_names
+ * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers
+ * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument
+ * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers
+ * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments
+ * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2
+ * @param log_ctx parent logging context
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code otherwise
+ */
+int av_expr_parse_and_eval(double *res, const char *s,
+                           const char * const *const_names, const double *const_values,
+                           const char * const *func1_names, double (* const *funcs1)(void *, double),
+                           const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                           void *opaque, int log_offset, void *log_ctx);
+
+/**
+ * Parse an expression.
+ *
+ * @param expr a pointer where is put an AVExpr containing the parsed
+ * value in case of successful parsing, or NULL otherwise.
+ * The pointed to AVExpr must be freed with av_expr_free() by the user
+ * when it is not needed anymore.
+ * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)"
+ * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0}
+ * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers
+ * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument
+ * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers
+ * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments
+ * @param log_ctx parent logging context
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code otherwise
+ */
+int av_expr_parse(AVExpr **expr, const char *s,
+                  const char * const *const_names,
+                  const char * const *func1_names, double (* const *funcs1)(void *, double),
+                  const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                  int log_offset, void *log_ctx);
+
+/**
+ * Evaluate a previously parsed expression.
+ *
+ * @param const_values a zero terminated array of values for the identifiers from av_expr_parse() const_names
+ * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2
+ * @return the value of the expression
+ */
+double av_expr_eval(AVExpr *e, const double *const_values, void *opaque);
+
+/**
+ * Free a parsed expression previously created with av_expr_parse().
+ */
+void av_expr_free(AVExpr *e);
+
+#if FF_API_OLD_EVAL_NAMES
+/**
+ * @deprecated Deprecated in favor of av_expr_parse_and_eval().
+ */
+attribute_deprecated
+int av_parse_and_eval_expr(double *res, const char *s,
+                           const char * const *const_names, const double *const_values,
+                           const char * const *func1_names, double (* const *funcs1)(void *, double),
+                           const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                           void *opaque, int log_offset, void *log_ctx);
+
+/**
+ * @deprecated Deprecated in favor of av_expr_parse().
+ */
+attribute_deprecated
+int av_parse_expr(AVExpr **expr, const char *s,
+                  const char * const *const_names,
+                  const char * const *func1_names, double (* const *funcs1)(void *, double),
+                  const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                  int log_offset, void *log_ctx);
+/**
+ * @deprecated Deprecated in favor of av_expr_eval().
+ */
+attribute_deprecated
+double av_eval_expr(AVExpr *e, const double *const_values, void *opaque);
+
+/**
+ * @deprecated Deprecated in favor of av_expr_free().
+ */
+attribute_deprecated
+void av_free_expr(AVExpr *e);
+#endif /* FF_API_OLD_EVAL_NAMES */
+
+/**
+ * Parse the string in numstr and return its value as a double. If
+ * the string is empty, contains only whitespaces, or does not contain
+ * an initial substring that has the expected syntax for a
+ * floating-point number, no conversion is performed. In this case,
+ * returns a value of zero and the value returned in tail is the value
+ * of numstr.
+ *
+ * @param numstr a string representing a number, may contain one of
+ * the International System number postfixes, for example 'K', 'M',
+ * 'G'. If 'i' is appended after the postfix, powers of 2 are used
+ * instead of powers of 10. The 'B' postfix multiplies the value for
+ * 8, and can be appended after another postfix or used alone. This
+ * allows using for example 'KB', 'MiB', 'G' and 'B' as postfix.
+ * @param tail if non-NULL puts here the pointer to the char next
+ * after the last parsed character
+ */
+double av_strtod(const char *numstr, char **tail);
+
+#endif /* AVUTIL_EVAL_H */
diff --git a/extra_lib/include/libavutil/fifo.h b/extra_lib/include/libavutil/fifo.h
new file mode 100644 (file)
index 0000000..ff66c95
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * a very simple circular buffer FIFO implementation
+ */
+
+#ifndef AVUTIL_FIFO_H
+#define AVUTIL_FIFO_H
+
+#include <stdint.h>
+#include "avutil.h"
+#include "attributes.h"
+
+typedef struct AVFifoBuffer {
+    uint8_t *buffer;
+    uint8_t *rptr, *wptr, *end;
+    uint32_t rndx, wndx;
+} AVFifoBuffer;
+
+/**
+ * Initialize an AVFifoBuffer.
+ * @param size of FIFO
+ * @return AVFifoBuffer or NULL in case of memory allocation failure
+ */
+AVFifoBuffer *av_fifo_alloc(unsigned int size);
+
+/**
+ * Free an AVFifoBuffer.
+ * @param f AVFifoBuffer to free
+ */
+void av_fifo_free(AVFifoBuffer *f);
+
+/**
+ * Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
+ * @param f AVFifoBuffer to reset
+ */
+void av_fifo_reset(AVFifoBuffer *f);
+
+/**
+ * Return the amount of data in bytes in the AVFifoBuffer, that is the
+ * amount of data you can read from it.
+ * @param f AVFifoBuffer to read from
+ * @return size
+ */
+int av_fifo_size(AVFifoBuffer *f);
+
+/**
+ * Return the amount of space in bytes in the AVFifoBuffer, that is the
+ * amount of data you can write into it.
+ * @param f AVFifoBuffer to write into
+ * @return size
+ */
+int av_fifo_space(AVFifoBuffer *f);
+
+/**
+ * Feed data from an AVFifoBuffer to a user-supplied callback.
+ * @param f AVFifoBuffer to read from
+ * @param buf_size number of bytes to read
+ * @param func generic read function
+ * @param dest data destination
+ */
+int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
+
+/**
+ * Feed data from a user-supplied callback to an AVFifoBuffer.
+ * @param f AVFifoBuffer to write to
+ * @param src data source; non-const since it may be used as a
+ * modifiable context by the function defined in func
+ * @param size number of bytes to write
+ * @param func generic write function; the first parameter is src,
+ * the second is dest_buf, the third is dest_buf_size.
+ * func must return the number of bytes written to dest_buf, or <= 0 to
+ * indicate no more data available to write.
+ * If func is NULL, src is interpreted as a simple byte array for source data.
+ * @return the number of bytes written to the FIFO
+ */
+int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int));
+
+/**
+ * Resize an AVFifoBuffer.
+ * In case of reallocation failure, the old FIFO is kept unchanged.
+ *
+ * @param f AVFifoBuffer to resize
+ * @param size new AVFifoBuffer size in bytes
+ * @return <0 for failure, >=0 otherwise
+ */
+int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size);
+
+/**
+ * Enlarge an AVFifoBuffer.
+ * In case of reallocation failure, the old FIFO is kept unchanged.
+ * The new fifo size may be larger than the requested size.
+ *
+ * @param f AVFifoBuffer to resize
+ * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size()
+ * @return <0 for failure, >=0 otherwise
+ */
+int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space);
+
+/**
+ * Read and discard the specified amount of data from an AVFifoBuffer.
+ * @param f AVFifoBuffer to read from
+ * @param size amount of data to read in bytes
+ */
+void av_fifo_drain(AVFifoBuffer *f, int size);
+
+/**
+ * Return a pointer to the data stored in a FIFO buffer at a certain offset.
+ * The FIFO buffer is not modified.
+ *
+ * @param f    AVFifoBuffer to peek at, f must be non-NULL
+ * @param offs an offset in bytes, its absolute value must be less
+ *             than the used buffer size or the returned pointer will
+ *             point outside to the buffer data.
+ *             The used buffer size can be checked with av_fifo_size().
+ */
+static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs)
+{
+    uint8_t *ptr = f->rptr + offs;
+    if (ptr >= f->end)
+        ptr = f->buffer + (ptr - f->end);
+    else if (ptr < f->buffer)
+        ptr = f->end - (f->buffer - ptr);
+    return ptr;
+}
+
+#if FF_API_AV_FIFO_PEEK
+/**
+ * @deprecated Use av_fifo_peek2() instead.
+ */
+attribute_deprecated
+static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs)
+{
+    return *av_fifo_peek2(f, offs);
+}
+#endif
+
+#endif /* AVUTIL_FIFO_H */
diff --git a/extra_lib/include/libavutil/file.h b/extra_lib/include/libavutil/file.h
new file mode 100644 (file)
index 0000000..f637005
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_FILE_H
+#define AVUTIL_FILE_H
+
+#include <stdint.h>
+
+#include "avutil.h"
+
+/**
+ * @file
+ * Misc file utilities.
+ */
+
+/**
+ * Read the file with name filename, and put its content in a newly
+ * allocated buffer or map it with mmap() when available.
+ * In case of success set *bufptr to the read or mmapped buffer, and
+ * *size to the size in bytes of the buffer in *bufptr.
+ * The returned buffer must be released with av_file_unmap().
+ *
+ * @param log_offset loglevel offset used for logging
+ * @param log_ctx context used for logging
+ * @return a non negative number in case of success, a negative value
+ * corresponding to an AVERROR error code in case of failure
+ */
+int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
+                int log_offset, void *log_ctx);
+
+/**
+ * Unmap or free the buffer bufptr created by av_file_map().
+ *
+ * @param size size in bytes of bufptr, must be the same as returned
+ * by av_file_map()
+ */
+void av_file_unmap(uint8_t *bufptr, size_t size);
+
+/**
+ * Wrapper to work around the lack of mkstemp() on mingw.
+ * Also, tries to create file in /tmp first, if possible.
+ * *prefix can be a character constant; *filename will be allocated internally.
+ * @return file descriptor of opened file (or -1 on error)
+ * and opened file name in **filename.
+ */
+int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);
+
+#endif /* AVUTIL_FILE_H */
diff --git a/extra_lib/include/libavutil/imgutils.h b/extra_lib/include/libavutil/imgutils.h
new file mode 100644 (file)
index 0000000..a9317a7
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_IMGUTILS_H
+#define AVUTIL_IMGUTILS_H
+
+/**
+ * @file
+ * misc image utilities
+ *
+ * @addtogroup lavu_picture
+ * @{
+ */
+
+#include "avutil.h"
+#include "pixdesc.h"
+
+/**
+ * Compute the max pixel step for each plane of an image with a
+ * format described by pixdesc.
+ *
+ * The pixel step is the distance in bytes between the first byte of
+ * the group of bytes which describe a pixel component and the first
+ * byte of the successive group in the same plane for the same
+ * component.
+ *
+ * @param max_pixsteps an array which is filled with the max pixel step
+ * for each plane. Since a plane may contain different pixel
+ * components, the computed max_pixsteps[plane] is relative to the
+ * component in the plane with the max pixel step.
+ * @param max_pixstep_comps an array which is filled with the component
+ * for each plane which has the max pixel step. May be NULL.
+ */
+void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
+                                const AVPixFmtDescriptor *pixdesc);
+
+/**
+ * Compute the size of an image line with format pix_fmt and width
+ * width for the plane plane.
+ *
+ * @return the computed size in bytes
+ */
+int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane);
+
+/**
+ * Fill plane linesizes for an image with pixel format pix_fmt and
+ * width width.
+ *
+ * @param linesizes array to be filled with the linesize for each plane
+ * @return >= 0 in case of success, a negative error code otherwise
+ */
+int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width);
+
+/**
+ * Fill plane data pointers for an image with pixel format pix_fmt and
+ * height height.
+ *
+ * @param data pointers array to be filled with the pointer for each image plane
+ * @param ptr the pointer to a buffer which will contain the image
+ * @param linesizes the array containing the linesize for each
+ * plane, should be filled by av_image_fill_linesizes()
+ * @return the size in bytes required for the image buffer, a negative
+ * error code in case of failure
+ */
+int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height,
+                           uint8_t *ptr, const int linesizes[4]);
+
+/**
+ * Allocate an image with size w and h and pixel format pix_fmt, and
+ * fill pointers and linesizes accordingly.
+ * The allocated image buffer has to be freed by using
+ * av_freep(&pointers[0]).
+ *
+ * @param align the value to use for buffer size alignment
+ * @return the size in bytes required for the image buffer, a negative
+ * error code in case of failure
+ */
+int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
+                   int w, int h, enum AVPixelFormat pix_fmt, int align);
+
+/**
+ * Copy image plane from src to dst.
+ * That is, copy "height" number of lines of "bytewidth" bytes each.
+ * The first byte of each successive line is separated by *_linesize
+ * bytes.
+ *
+ * @param dst_linesize linesize for the image plane in dst
+ * @param src_linesize linesize for the image plane in src
+ */
+void av_image_copy_plane(uint8_t       *dst, int dst_linesize,
+                         const uint8_t *src, int src_linesize,
+                         int bytewidth, int height);
+
+/**
+ * Copy image in src_data to dst_data.
+ *
+ * @param dst_linesizes linesizes for the image in dst_data
+ * @param src_linesizes linesizes for the image in src_data
+ */
+void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
+                   const uint8_t *src_data[4], const int src_linesizes[4],
+                   enum AVPixelFormat pix_fmt, int width, int height);
+
+/**
+ * Setup the data pointers and linesizes based on the specified image
+ * parameters and the provided array.
+ *
+ * The fields of the given image are filled in by using the src
+ * address which points to the image data buffer. Depending on the
+ * specified pixel format, one or multiple image data pointers and
+ * line sizes will be set.  If a planar format is specified, several
+ * pointers will be set pointing to the different picture planes and
+ * the line sizes of the different planes will be stored in the
+ * lines_sizes array. Call with src == NULL to get the required
+ * size for the src buffer.
+ *
+ * To allocate the buffer and fill in the dst_data and dst_linesize in
+ * one call, use av_image_alloc().
+ *
+ * @param dst_data      data pointers to be filled in
+ * @param dst_linesizes linesizes for the image in dst_data to be filled in
+ * @param src           buffer which will contain or contains the actual image data, can be NULL
+ * @param pix_fmt       the pixel format of the image
+ * @param width         the width of the image in pixels
+ * @param height        the height of the image in pixels
+ * @param align         the value used in src for linesize alignment
+ * @return the size in bytes required for src, a negative error code
+ * in case of failure
+ */
+int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
+                         const uint8_t *src,
+                         enum AVPixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Return the size in bytes of the amount of data required to store an
+ * image with the given parameters.
+ *
+ * @param[in] align the assumed linesize alignment
+ */
+int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Copy image data from an image into a buffer.
+ *
+ * av_image_get_buffer_size() can be used to compute the required size
+ * for the buffer to fill.
+ *
+ * @param dst           a buffer into which picture data will be copied
+ * @param dst_size      the size in bytes of dst
+ * @param src_data      pointers containing the source image data
+ * @param src_linesizes linesizes for the image in src_data
+ * @param pix_fmt       the pixel format of the source image
+ * @param width         the width of the source image in pixels
+ * @param height        the height of the source image in pixels
+ * @param align         the assumed linesize alignment for dst
+ * @return the number of bytes written to dst, or a negative value
+ * (error code) on error
+ */
+int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
+                            const uint8_t * const src_data[4], const int src_linesize[4],
+                            enum AVPixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Check if the given dimension of an image is valid, meaning that all
+ * bytes of the image can be addressed with a signed int.
+ *
+ * @param w the width of the picture
+ * @param h the height of the picture
+ * @param log_offset the offset to sum to the log level for logging with log_ctx
+ * @param log_ctx the parent logging context, it may be NULL
+ * @return >= 0 if valid, a negative error code otherwise
+ */
+int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx);
+
+int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
+
+/**
+ * @}
+ */
+
+
+#endif /* AVUTIL_IMGUTILS_H */
diff --git a/extra_lib/include/libavutil/intfloat.h b/extra_lib/include/libavutil/intfloat.h
new file mode 100644 (file)
index 0000000..38d26ad
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011 Mans Rullgard
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.1 of the License, or (at your option) any later version.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_INTFLOAT_H
+#define AVUTIL_INTFLOAT_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+union av_intfloat32 {
+    uint32_t i;
+    float    f;
+};
+
+union av_intfloat64 {
+    uint64_t i;
+    double   f;
+};
+
+/**
+ * Reinterpret a 32-bit integer as a float.
+ */
+static av_always_inline float av_int2float(uint32_t i)
+{
+    union av_intfloat32 v;
+    v.i = i;
+    return v.f;
+}
+
+/**
+ * Reinterpret a float as a 32-bit integer.
+ */
+static av_always_inline uint32_t av_float2int(float f)
+{
+    union av_intfloat32 v;
+    v.f = f;
+    return v.i;
+}
+
+/**
+ * Reinterpret a 64-bit integer as a double.
+ */
+static av_always_inline double av_int2double(uint64_t i)
+{
+    union av_intfloat64 v;
+    v.i = i;
+    return v.f;
+}
+
+/**
+ * Reinterpret a double as a 64-bit integer.
+ */
+static av_always_inline uint64_t av_double2int(double f)
+{
+    union av_intfloat64 v;
+    v.f = f;
+    return v.i;
+}
+
+#endif /* AVUTIL_INTFLOAT_H */
index 88c6f69cfbcd12460a58787ff5096d0be81c6ffc..9709f4dae434dae02412fbf5618da99d3919520a 100644 (file)
 #ifndef AVUTIL_INTFLOAT_READWRITE_H
 #define AVUTIL_INTFLOAT_READWRITE_H
 
-#if !defined(WIN32) && !defined(_WIN32_WCE)
 #include <stdint.h>
-#endif
-#include "common.h"
+#include "attributes.h"
 
 /* IEEE 80 bits extended float */
 typedef struct AVExtFloat  {
@@ -32,11 +30,11 @@ typedef struct AVExtFloat  {
     uint8_t mantissa[8];
 } AVExtFloat;
 
-double av_int2dbl(int64_t v) av_const;
-float av_int2flt(int32_t v) av_const;
-double av_ext2dbl(const AVExtFloat ext) av_const;
-int64_t av_dbl2int(double d) av_const;
-int32_t av_flt2int(float d) av_const;
-AVExtFloat av_dbl2ext(double d) av_const;
+attribute_deprecated double av_int2dbl(int64_t v) av_const;
+attribute_deprecated float av_int2flt(int32_t v) av_const;
+attribute_deprecated double av_ext2dbl(const AVExtFloat ext) av_const;
+attribute_deprecated int64_t av_dbl2int(double d) av_const;
+attribute_deprecated int32_t av_flt2int(float d) av_const;
+attribute_deprecated AVExtFloat av_dbl2ext(double d) av_const;
 
 #endif /* AVUTIL_INTFLOAT_READWRITE_H */
diff --git a/extra_lib/include/libavutil/intreadwrite.h b/extra_lib/include/libavutil/intreadwrite.h
new file mode 100644 (file)
index 0000000..7c68ead
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_INTREADWRITE_H
+#define AVUTIL_INTREADWRITE_H
+
+#include <stdint.h>
+#include "libavutil/avconfig.h"
+#include "attributes.h"
+#include "bswap.h"
+
+typedef union {
+    uint64_t u64;
+    uint32_t u32[2];
+    uint16_t u16[4];
+    uint8_t  u8 [8];
+    double   f64;
+    float    f32[2];
+} av_alias av_alias64;
+
+typedef union {
+    uint32_t u32;
+    uint16_t u16[2];
+    uint8_t  u8 [4];
+    float    f32;
+} av_alias av_alias32;
+
+typedef union {
+    uint16_t u16;
+    uint8_t  u8 [2];
+} av_alias av_alias16;
+
+/*
+ * Arch-specific headers can provide any combination of
+ * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
+ * Preprocessor symbols must be defined, even if these are implemented
+ * as inline functions.
+ */
+
+#ifdef HAVE_AV_CONFIG_H
+
+#include "config.h"
+
+#if   ARCH_ARM
+#   include "arm/intreadwrite.h"
+#elif ARCH_AVR32
+#   include "avr32/intreadwrite.h"
+#elif ARCH_MIPS
+#   include "mips/intreadwrite.h"
+#elif ARCH_PPC
+#   include "ppc/intreadwrite.h"
+#elif ARCH_TOMI
+#   include "tomi/intreadwrite.h"
+#elif ARCH_X86
+#   include "x86/intreadwrite.h"
+#endif
+
+#endif /* HAVE_AV_CONFIG_H */
+
+/*
+ * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers.
+ */
+
+#if AV_HAVE_BIGENDIAN
+
+#   if    defined(AV_RN16) && !defined(AV_RB16)
+#       define AV_RB16(p) AV_RN16(p)
+#   elif !defined(AV_RN16) &&  defined(AV_RB16)
+#       define AV_RN16(p) AV_RB16(p)
+#   endif
+
+#   if    defined(AV_WN16) && !defined(AV_WB16)
+#       define AV_WB16(p, v) AV_WN16(p, v)
+#   elif !defined(AV_WN16) &&  defined(AV_WB16)
+#       define AV_WN16(p, v) AV_WB16(p, v)
+#   endif
+
+#   if    defined(AV_RN24) && !defined(AV_RB24)
+#       define AV_RB24(p) AV_RN24(p)
+#   elif !defined(AV_RN24) &&  defined(AV_RB24)
+#       define AV_RN24(p) AV_RB24(p)
+#   endif
+
+#   if    defined(AV_WN24) && !defined(AV_WB24)
+#       define AV_WB24(p, v) AV_WN24(p, v)
+#   elif !defined(AV_WN24) &&  defined(AV_WB24)
+#       define AV_WN24(p, v) AV_WB24(p, v)
+#   endif
+
+#   if    defined(AV_RN32) && !defined(AV_RB32)
+#       define AV_RB32(p) AV_RN32(p)
+#   elif !defined(AV_RN32) &&  defined(AV_RB32)
+#       define AV_RN32(p) AV_RB32(p)
+#   endif
+
+#   if    defined(AV_WN32) && !defined(AV_WB32)
+#       define AV_WB32(p, v) AV_WN32(p, v)
+#   elif !defined(AV_WN32) &&  defined(AV_WB32)
+#       define AV_WN32(p, v) AV_WB32(p, v)
+#   endif
+
+#   if    defined(AV_RN64) && !defined(AV_RB64)
+#       define AV_RB64(p) AV_RN64(p)
+#   elif !defined(AV_RN64) &&  defined(AV_RB64)
+#       define AV_RN64(p) AV_RB64(p)
+#   endif
+
+#   if    defined(AV_WN64) && !defined(AV_WB64)
+#       define AV_WB64(p, v) AV_WN64(p, v)
+#   elif !defined(AV_WN64) &&  defined(AV_WB64)
+#       define AV_WN64(p, v) AV_WB64(p, v)
+#   endif
+
+#else /* AV_HAVE_BIGENDIAN */
+
+#   if    defined(AV_RN16) && !defined(AV_RL16)
+#       define AV_RL16(p) AV_RN16(p)
+#   elif !defined(AV_RN16) &&  defined(AV_RL16)
+#       define AV_RN16(p) AV_RL16(p)
+#   endif
+
+#   if    defined(AV_WN16) && !defined(AV_WL16)
+#       define AV_WL16(p, v) AV_WN16(p, v)
+#   elif !defined(AV_WN16) &&  defined(AV_WL16)
+#       define AV_WN16(p, v) AV_WL16(p, v)
+#   endif
+
+#   if    defined(AV_RN24) && !defined(AV_RL24)
+#       define AV_RL24(p) AV_RN24(p)
+#   elif !defined(AV_RN24) &&  defined(AV_RL24)
+#       define AV_RN24(p) AV_RL24(p)
+#   endif
+
+#   if    defined(AV_WN24) && !defined(AV_WL24)
+#       define AV_WL24(p, v) AV_WN24(p, v)
+#   elif !defined(AV_WN24) &&  defined(AV_WL24)
+#       define AV_WN24(p, v) AV_WL24(p, v)
+#   endif
+
+#   if    defined(AV_RN32) && !defined(AV_RL32)
+#       define AV_RL32(p) AV_RN32(p)
+#   elif !defined(AV_RN32) &&  defined(AV_RL32)
+#       define AV_RN32(p) AV_RL32(p)
+#   endif
+
+#   if    defined(AV_WN32) && !defined(AV_WL32)
+#       define AV_WL32(p, v) AV_WN32(p, v)
+#   elif !defined(AV_WN32) &&  defined(AV_WL32)
+#       define AV_WN32(p, v) AV_WL32(p, v)
+#   endif
+
+#   if    defined(AV_RN64) && !defined(AV_RL64)
+#       define AV_RL64(p) AV_RN64(p)
+#   elif !defined(AV_RN64) &&  defined(AV_RL64)
+#       define AV_RN64(p) AV_RL64(p)
+#   endif
+
+#   if    defined(AV_WN64) && !defined(AV_WL64)
+#       define AV_WL64(p, v) AV_WN64(p, v)
+#   elif !defined(AV_WN64) &&  defined(AV_WL64)
+#       define AV_WN64(p, v) AV_WL64(p, v)
+#   endif
+
+#endif /* !AV_HAVE_BIGENDIAN */
+
+/*
+ * Define AV_[RW]N helper macros to simplify definitions not provided
+ * by per-arch headers.
+ */
+
+#if defined(__GNUC__) && !defined(__TI_COMPILER_VERSION__)
+
+union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias;
+union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias;
+union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
+
+#   define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
+#   define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v))
+
+#elif defined(__DECC)
+
+#   define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
+#   define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
+
+#elif AV_HAVE_FAST_UNALIGNED
+
+#   define AV_RN(s, p) (((const av_alias##s*)(p))->u##s)
+#   define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v))
+
+#else
+
+#ifndef AV_RB16
+#   define AV_RB16(x)                           \
+    ((((const uint8_t*)(x))[0] << 8) |          \
+      ((const uint8_t*)(x))[1])
+#endif
+#ifndef AV_WB16
+#   define AV_WB16(p, darg) do {                \
+        unsigned d = (darg);                    \
+        ((uint8_t*)(p))[1] = (d);               \
+        ((uint8_t*)(p))[0] = (d)>>8;            \
+    } while(0)
+#endif
+
+#ifndef AV_RL16
+#   define AV_RL16(x)                           \
+    ((((const uint8_t*)(x))[1] << 8) |          \
+      ((const uint8_t*)(x))[0])
+#endif
+#ifndef AV_WL16
+#   define AV_WL16(p, darg) do {                \
+        unsigned d = (darg);                    \
+        ((uint8_t*)(p))[0] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+    } while(0)
+#endif
+
+#ifndef AV_RB32
+#   define AV_RB32(x)                                \
+    (((uint32_t)((const uint8_t*)(x))[0] << 24) |    \
+               (((const uint8_t*)(x))[1] << 16) |    \
+               (((const uint8_t*)(x))[2] <<  8) |    \
+                ((const uint8_t*)(x))[3])
+#endif
+#ifndef AV_WB32
+#   define AV_WB32(p, darg) do {                \
+        unsigned d = (darg);                    \
+        ((uint8_t*)(p))[3] = (d);               \
+        ((uint8_t*)(p))[2] = (d)>>8;            \
+        ((uint8_t*)(p))[1] = (d)>>16;           \
+        ((uint8_t*)(p))[0] = (d)>>24;           \
+    } while(0)
+#endif
+
+#ifndef AV_RL32
+#   define AV_RL32(x)                                \
+    (((uint32_t)((const uint8_t*)(x))[3] << 24) |    \
+               (((const uint8_t*)(x))[2] << 16) |    \
+               (((const uint8_t*)(x))[1] <<  8) |    \
+                ((const uint8_t*)(x))[0])
+#endif
+#ifndef AV_WL32
+#   define AV_WL32(p, darg) do {                \
+        unsigned d = (darg);                    \
+        ((uint8_t*)(p))[0] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+        ((uint8_t*)(p))[2] = (d)>>16;           \
+        ((uint8_t*)(p))[3] = (d)>>24;           \
+    } while(0)
+#endif
+
+#ifndef AV_RB64
+#   define AV_RB64(x)                                   \
+    (((uint64_t)((const uint8_t*)(x))[0] << 56) |       \
+     ((uint64_t)((const uint8_t*)(x))[1] << 48) |       \
+     ((uint64_t)((const uint8_t*)(x))[2] << 40) |       \
+     ((uint64_t)((const uint8_t*)(x))[3] << 32) |       \
+     ((uint64_t)((const uint8_t*)(x))[4] << 24) |       \
+     ((uint64_t)((const uint8_t*)(x))[5] << 16) |       \
+     ((uint64_t)((const uint8_t*)(x))[6] <<  8) |       \
+      (uint64_t)((const uint8_t*)(x))[7])
+#endif
+#ifndef AV_WB64
+#   define AV_WB64(p, darg) do {                \
+        uint64_t d = (darg);                    \
+        ((uint8_t*)(p))[7] = (d);               \
+        ((uint8_t*)(p))[6] = (d)>>8;            \
+        ((uint8_t*)(p))[5] = (d)>>16;           \
+        ((uint8_t*)(p))[4] = (d)>>24;           \
+        ((uint8_t*)(p))[3] = (d)>>32;           \
+        ((uint8_t*)(p))[2] = (d)>>40;           \
+        ((uint8_t*)(p))[1] = (d)>>48;           \
+        ((uint8_t*)(p))[0] = (d)>>56;           \
+    } while(0)
+#endif
+
+#ifndef AV_RL64
+#   define AV_RL64(x)                                   \
+    (((uint64_t)((const uint8_t*)(x))[7] << 56) |       \
+     ((uint64_t)((const uint8_t*)(x))[6] << 48) |       \
+     ((uint64_t)((const uint8_t*)(x))[5] << 40) |       \
+     ((uint64_t)((const uint8_t*)(x))[4] << 32) |       \
+     ((uint64_t)((const uint8_t*)(x))[3] << 24) |       \
+     ((uint64_t)((const uint8_t*)(x))[2] << 16) |       \
+     ((uint64_t)((const uint8_t*)(x))[1] <<  8) |       \
+      (uint64_t)((const uint8_t*)(x))[0])
+#endif
+#ifndef AV_WL64
+#   define AV_WL64(p, darg) do {                \
+        uint64_t d = (darg);                    \
+        ((uint8_t*)(p))[0] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+        ((uint8_t*)(p))[2] = (d)>>16;           \
+        ((uint8_t*)(p))[3] = (d)>>24;           \
+        ((uint8_t*)(p))[4] = (d)>>32;           \
+        ((uint8_t*)(p))[5] = (d)>>40;           \
+        ((uint8_t*)(p))[6] = (d)>>48;           \
+        ((uint8_t*)(p))[7] = (d)>>56;           \
+    } while(0)
+#endif
+
+#if AV_HAVE_BIGENDIAN
+#   define AV_RN(s, p)    AV_RB##s(p)
+#   define AV_WN(s, p, v) AV_WB##s(p, v)
+#else
+#   define AV_RN(s, p)    AV_RL##s(p)
+#   define AV_WN(s, p, v) AV_WL##s(p, v)
+#endif
+
+#endif /* HAVE_FAST_UNALIGNED */
+
+#ifndef AV_RN16
+#   define AV_RN16(p) AV_RN(16, p)
+#endif
+
+#ifndef AV_RN32
+#   define AV_RN32(p) AV_RN(32, p)
+#endif
+
+#ifndef AV_RN64
+#   define AV_RN64(p) AV_RN(64, p)
+#endif
+
+#ifndef AV_WN16
+#   define AV_WN16(p, v) AV_WN(16, p, v)
+#endif
+
+#ifndef AV_WN32
+#   define AV_WN32(p, v) AV_WN(32, p, v)
+#endif
+
+#ifndef AV_WN64
+#   define AV_WN64(p, v) AV_WN(64, p, v)
+#endif
+
+#if AV_HAVE_BIGENDIAN
+#   define AV_RB(s, p)    AV_RN##s(p)
+#   define AV_WB(s, p, v) AV_WN##s(p, v)
+#   define AV_RL(s, p)    av_bswap##s(AV_RN##s(p))
+#   define AV_WL(s, p, v) AV_WN##s(p, av_bswap##s(v))
+#else
+#   define AV_RB(s, p)    av_bswap##s(AV_RN##s(p))
+#   define AV_WB(s, p, v) AV_WN##s(p, av_bswap##s(v))
+#   define AV_RL(s, p)    AV_RN##s(p)
+#   define AV_WL(s, p, v) AV_WN##s(p, v)
+#endif
+
+#define AV_RB8(x)     (((const uint8_t*)(x))[0])
+#define AV_WB8(p, d)  do { ((uint8_t*)(p))[0] = (d); } while(0)
+
+#define AV_RL8(x)     AV_RB8(x)
+#define AV_WL8(p, d)  AV_WB8(p, d)
+
+#ifndef AV_RB16
+#   define AV_RB16(p)    AV_RB(16, p)
+#endif
+#ifndef AV_WB16
+#   define AV_WB16(p, v) AV_WB(16, p, v)
+#endif
+
+#ifndef AV_RL16
+#   define AV_RL16(p)    AV_RL(16, p)
+#endif
+#ifndef AV_WL16
+#   define AV_WL16(p, v) AV_WL(16, p, v)
+#endif
+
+#ifndef AV_RB32
+#   define AV_RB32(p)    AV_RB(32, p)
+#endif
+#ifndef AV_WB32
+#   define AV_WB32(p, v) AV_WB(32, p, v)
+#endif
+
+#ifndef AV_RL32
+#   define AV_RL32(p)    AV_RL(32, p)
+#endif
+#ifndef AV_WL32
+#   define AV_WL32(p, v) AV_WL(32, p, v)
+#endif
+
+#ifndef AV_RB64
+#   define AV_RB64(p)    AV_RB(64, p)
+#endif
+#ifndef AV_WB64
+#   define AV_WB64(p, v) AV_WB(64, p, v)
+#endif
+
+#ifndef AV_RL64
+#   define AV_RL64(p)    AV_RL(64, p)
+#endif
+#ifndef AV_WL64
+#   define AV_WL64(p, v) AV_WL(64, p, v)
+#endif
+
+#ifndef AV_RB24
+#   define AV_RB24(x)                           \
+    ((((const uint8_t*)(x))[0] << 16) |         \
+     (((const uint8_t*)(x))[1] <<  8) |         \
+      ((const uint8_t*)(x))[2])
+#endif
+#ifndef AV_WB24
+#   define AV_WB24(p, d) do {                   \
+        ((uint8_t*)(p))[2] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+        ((uint8_t*)(p))[0] = (d)>>16;           \
+    } while(0)
+#endif
+
+#ifndef AV_RL24
+#   define AV_RL24(x)                           \
+    ((((const uint8_t*)(x))[2] << 16) |         \
+     (((const uint8_t*)(x))[1] <<  8) |         \
+      ((const uint8_t*)(x))[0])
+#endif
+#ifndef AV_WL24
+#   define AV_WL24(p, d) do {                   \
+        ((uint8_t*)(p))[0] = (d);               \
+        ((uint8_t*)(p))[1] = (d)>>8;            \
+        ((uint8_t*)(p))[2] = (d)>>16;           \
+    } while(0)
+#endif
+
+/*
+ * The AV_[RW]NA macros access naturally aligned data
+ * in a type-safe way.
+ */
+
+#define AV_RNA(s, p)    (((const av_alias##s*)(p))->u##s)
+#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v))
+
+#ifndef AV_RN16A
+#   define AV_RN16A(p) AV_RNA(16, p)
+#endif
+
+#ifndef AV_RN32A
+#   define AV_RN32A(p) AV_RNA(32, p)
+#endif
+
+#ifndef AV_RN64A
+#   define AV_RN64A(p) AV_RNA(64, p)
+#endif
+
+#ifndef AV_WN16A
+#   define AV_WN16A(p, v) AV_WNA(16, p, v)
+#endif
+
+#ifndef AV_WN32A
+#   define AV_WN32A(p, v) AV_WNA(32, p, v)
+#endif
+
+#ifndef AV_WN64A
+#   define AV_WN64A(p, v) AV_WNA(64, p, v)
+#endif
+
+/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
+ * naturally aligned. They may be implemented using MMX,
+ * so emms_c() must be called before using any float code
+ * afterwards.
+ */
+
+#define AV_COPY(n, d, s) \
+    (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n)
+
+#ifndef AV_COPY16
+#   define AV_COPY16(d, s) AV_COPY(16, d, s)
+#endif
+
+#ifndef AV_COPY32
+#   define AV_COPY32(d, s) AV_COPY(32, d, s)
+#endif
+
+#ifndef AV_COPY64
+#   define AV_COPY64(d, s) AV_COPY(64, d, s)
+#endif
+
+#ifndef AV_COPY128
+#   define AV_COPY128(d, s)                    \
+    do {                                       \
+        AV_COPY64(d, s);                       \
+        AV_COPY64((char*)(d)+8, (char*)(s)+8); \
+    } while(0)
+#endif
+
+#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b))
+
+#ifndef AV_SWAP64
+#   define AV_SWAP64(a, b) AV_SWAP(64, a, b)
+#endif
+
+#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0)
+
+#ifndef AV_ZERO16
+#   define AV_ZERO16(d) AV_ZERO(16, d)
+#endif
+
+#ifndef AV_ZERO32
+#   define AV_ZERO32(d) AV_ZERO(32, d)
+#endif
+
+#ifndef AV_ZERO64
+#   define AV_ZERO64(d) AV_ZERO(64, d)
+#endif
+
+#ifndef AV_ZERO128
+#   define AV_ZERO128(d)         \
+    do {                         \
+        AV_ZERO64(d);            \
+        AV_ZERO64((char*)(d)+8); \
+    } while(0)
+#endif
+
+#endif /* AVUTIL_INTREADWRITE_H */
diff --git a/extra_lib/include/libavutil/lfg.h b/extra_lib/include/libavutil/lfg.h
new file mode 100644 (file)
index 0000000..ec90562
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Lagged Fibonacci PRNG
+ * Copyright (c) 2008 Michael Niedermayer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_LFG_H
+#define AVUTIL_LFG_H
+
+typedef struct AVLFG {
+    unsigned int state[64];
+    int index;
+} AVLFG;
+
+void av_lfg_init(AVLFG *c, unsigned int seed);
+
+/**
+ * Get the next random unsigned 32-bit number using an ALFG.
+ *
+ * Please also consider a simple LCG like state= state*1664525+1013904223,
+ * it may be good enough and faster for your specific use case.
+ */
+static inline unsigned int av_lfg_get(AVLFG *c){
+    c->state[c->index & 63] = c->state[(c->index-24) & 63] + c->state[(c->index-55) & 63];
+    return c->state[c->index++ & 63];
+}
+
+/**
+ * Get the next random unsigned 32-bit number using a MLFG.
+ *
+ * Please also consider av_lfg_get() above, it is faster.
+ */
+static inline unsigned int av_mlfg_get(AVLFG *c){
+    unsigned int a= c->state[(c->index-55) & 63];
+    unsigned int b= c->state[(c->index-24) & 63];
+    return c->state[c->index++ & 63] = 2*a*b+a+b;
+}
+
+/**
+ * Get the next two numbers generated by a Box-Muller Gaussian
+ * generator using the random numbers issued by lfg.
+ *
+ * @param out array where the two generated numbers are placed
+ */
+void av_bmg_get(AVLFG *lfg, double out[2]);
+
+#endif /* AVUTIL_LFG_H */
index 1206a2fc3866fd831063150f7a0362bc9c0a49d1..ba7315fa64594a8d2dd3825952d78c255a8a5945 100644 (file)
 
 #include <stdarg.h>
 #include "avutil.h"
+#include "attributes.h"
+
+typedef enum {
+    AV_CLASS_CATEGORY_NA = 0,
+    AV_CLASS_CATEGORY_INPUT,
+    AV_CLASS_CATEGORY_OUTPUT,
+    AV_CLASS_CATEGORY_MUXER,
+    AV_CLASS_CATEGORY_DEMUXER,
+    AV_CLASS_CATEGORY_ENCODER,
+    AV_CLASS_CATEGORY_DECODER,
+    AV_CLASS_CATEGORY_FILTER,
+    AV_CLASS_CATEGORY_BITSTREAM_FILTER,
+    AV_CLASS_CATEGORY_SWSCALER,
+    AV_CLASS_CATEGORY_SWRESAMPLER,
+    AV_CLASS_CATEGORY_NB, ///< not part of ABI/API
+}AVClassCategory;
 
 /**
- * Describes the class of an AVClass context structure. That is an
+ * Describe the class of an AVClass context structure. That is an
  * arbitrary struct of which the first field is a pointer to an
  * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
  */
-typedef struct AVCLASS AVClass;
-struct AVCLASS {
+typedef struct AVClass {
     /**
      * The name of the class; usually it is the same name as the
      * context structure type to which the AVClass is associated.
@@ -39,7 +54,7 @@ struct AVCLASS {
 
     /**
      * A pointer to a function which returns the name of a context
-     * instance \p ctx associated with the class.
+     * instance ctx associated with the class.
      */
     const char* (*item_name)(void* ctx);
 
@@ -49,7 +64,57 @@ struct AVCLASS {
      * @see av_set_default_options()
      */
     const struct AVOption *option;
-};
+
+    /**
+     * LIBAVUTIL_VERSION with which this structure was created.
+     * This is used to allow fields to be added without requiring major
+     * version bumps everywhere.
+     */
+
+    int version;
+
+    /**
+     * Offset in the structure where log_level_offset is stored.
+     * 0 means there is no such variable
+     */
+    int log_level_offset_offset;
+
+    /**
+     * Offset in the structure where a pointer to the parent context for loging is stored.
+     * for example a decoder that uses eval.c could pass its AVCodecContext to eval as such
+     * parent context. And a av_log() implementation could then display the parent context
+     * can be NULL of course
+     */
+    int parent_log_context_offset;
+
+    /**
+     * Return next AVOptions-enabled child or NULL
+     */
+    void* (*child_next)(void *obj, void *prev);
+
+    /**
+     * Return an AVClass corresponding to next potential
+     * AVOptions-enabled child.
+     *
+     * The difference between child_next and this is that
+     * child_next iterates over _already existing_ objects, while
+     * child_class_next iterates over _all possible_ children.
+     */
+    const struct AVClass* (*child_class_next)(const struct AVClass *prev);
+
+    /**
+     * Category used for visualization (like color)
+     * This is only set if the category is equal for all objects using this class.
+     * available since version (51 << 16 | 56 << 8 | 100)
+     */
+    AVClassCategory category;
+
+    /**
+     * Callback to return the category.
+     * available since version (51 << 16 | 59 << 8 | 100)
+     */
+    AVClassCategory (*get_category)(void* ctx);
+} AVClass;
 
 /* av_log API */
 
@@ -87,8 +152,10 @@ struct AVCLASS {
  */
 #define AV_LOG_DEBUG    48
 
+#define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET)
+
 /**
- * Sends the specified message to the log if the level is less than or equal
+ * Send the specified message to the log if the level is less than or equal
  * to the current av_log_level. By default, all logging messages are sent to
  * stderr. This behavior can be altered by setting a different av_vlog callback
  * function.
@@ -101,16 +168,46 @@ struct AVCLASS {
  * subsequent arguments are converted to output.
  * @see av_vlog
  */
-#ifdef __GNUC__
-void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4)));
-#else
-void av_log(void*, int level, const char *fmt, ...);
-#endif
+void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
 
-void av_vlog(void*, int level, const char *fmt, va_list);
+void av_vlog(void *avcl, int level, const char *fmt, va_list);
 int av_log_get_level(void);
 void av_log_set_level(int);
 void av_log_set_callback(void (*)(void*, int, const char*, va_list));
 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl);
+const char* av_default_item_name(void* ctx);
+AVClassCategory av_default_get_category(void *ptr);
+
+/**
+ * Format a line of log the same way as the default callback.
+ * @param line          buffer to receive the formated line
+ * @param line_size     size of the buffer
+ * @param print_prefix  used to store whether the prefix must be printed;
+ *                      must point to a persistent integer initially set to 1
+ */
+void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl,
+                        char *line, int line_size, int *print_prefix);
+
+/**
+ * av_dlog macros
+ * Useful to print debug messages that shouldn't get compiled in normally.
+ */
+
+#ifdef DEBUG
+#    define av_dlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__)
+#else
+#    define av_dlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
+#endif
+
+/**
+ * Skip repeated messages, this requires the user app to use av_log() instead of
+ * (f)printf as the 2 would otherwise interfere and lead to
+ * "Last message repeated x times" messages below (f)printf messages with some
+ * bad luck.
+ * Also to receive the last, "last repeated" line if any, the user app must
+ * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end
+ */
+#define AV_LOG_SKIP_REPEATED 1
+void av_log_set_flags(int arg);
 
 #endif /* AVUTIL_LOG_H */
diff --git a/extra_lib/include/libavutil/lzo.h b/extra_lib/include/libavutil/lzo.h
new file mode 100644 (file)
index 0000000..060b5c9
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * LZO 1x decompression
+ * copyright (c) 2006 Reimar Doeffinger
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_LZO_H
+#define AVUTIL_LZO_H
+
+/**
+ * @defgroup lavu_lzo LZO
+ * @ingroup lavu_crypto
+ *
+ * @{
+ */
+
+#include <stdint.h>
+
+/** @name Error flags returned by av_lzo1x_decode
+  * @{ */
+/// end of the input buffer reached before decoding finished
+#define AV_LZO_INPUT_DEPLETED 1
+/// decoded data did not fit into output buffer
+#define AV_LZO_OUTPUT_FULL 2
+/// a reference to previously decoded data was wrong
+#define AV_LZO_INVALID_BACKPTR 4
+/// a non-specific error in the compressed bitstream
+#define AV_LZO_ERROR 8
+/** @} */
+
+#define AV_LZO_INPUT_PADDING 8
+#define AV_LZO_OUTPUT_PADDING 12
+
+/**
+ * @brief Decodes LZO 1x compressed data.
+ * @param out output buffer
+ * @param outlen size of output buffer, number of bytes left are returned here
+ * @param in input buffer
+ * @param inlen size of input buffer, number of bytes left are returned here
+ * @return 0 on success, otherwise a combination of the error flags above
+ *
+ * Make sure all buffers are appropriately padded, in must provide
+ * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes.
+ */
+int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen);
+
+/**
+ * @brief deliberately overlapping memcpy implementation
+ * @param dst destination buffer; must be padded with 12 additional bytes
+ * @param back how many bytes back we start (the initial size of the overlapping window), must be > 0
+ * @param cnt number of bytes to copy, must be >= 0
+ *
+ * cnt > back is valid, this will copy the bytes we just copied,
+ * thus creating a repeating pattern with a period length of back.
+ */
+void av_memcpy_backptr(uint8_t *dst, int back, int cnt);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_LZO_H */
index f4374040bf17dc6eaee760930a4e21239760815d..5458d2f850d5563c5c3bbca228059a74ccd332ae 100644 (file)
 #ifndef AVUTIL_MATHEMATICS_H
 #define AVUTIL_MATHEMATICS_H
 
-#if !defined(WIN32) && !defined(_WIN32_WCE)
 #include <stdint.h>
-#endif
 #include <math.h>
-#include "common.h"
+#include "attributes.h"
 #include "rational.h"
+#include "intfloat.h"
 
 #ifndef M_E
 #define M_E            2.7182818284590452354   /* e */
 #ifndef M_LN10
 #define M_LN10         2.30258509299404568402  /* log_e 10 */
 #endif
+#ifndef M_LOG2_10
+#define M_LOG2_10      3.32192809488736234787  /* log_2 10 */
+#endif
+#ifndef M_PHI
+#define M_PHI          1.61803398874989484820   /* phi / golden ratio */
+#endif
 #ifndef M_PI
 #define M_PI           3.14159265358979323846  /* pi */
 #endif
 #ifndef M_SQRT1_2
 #define M_SQRT1_2      0.70710678118654752440  /* 1/sqrt(2) */
 #endif
+#ifndef M_SQRT2
+#define M_SQRT2        1.41421356237309504880  /* sqrt(2) */
+#endif
+#ifndef NAN
+#define NAN            av_int2float(0x7fc00000)
+#endif
+#ifndef INFINITY
+#define INFINITY       av_int2float(0x7f800000)
+#endif
+
+/**
+ * @addtogroup lavu_math
+ * @{
+ */
+
 
 enum AVRounding {
     AV_ROUND_ZERO     = 0, ///< Round toward zero.
@@ -52,23 +72,58 @@ enum AVRounding {
     AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero.
 };
 
+/**
+ * Return the greatest common divisor of a and b.
+ * If both a and b are 0 or either or both are <0 then behavior is
+ * undefined.
+ */
 int64_t av_const av_gcd(int64_t a, int64_t b);
 
 /**
- * Rescales a 64-bit integer with rounding to nearest.
+ * Rescale a 64-bit integer with rounding to nearest.
  * A simple a*b/c isn't possible as it can overflow.
  */
 int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const;
 
 /**
- * Rescales a 64-bit integer with specified rounding.
+ * Rescale a 64-bit integer with specified rounding.
  * A simple a*b/c isn't possible as it can overflow.
  */
 int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const;
 
 /**
- * Rescales a 64-bit integer by 2 rational numbers.
+ * Rescale a 64-bit integer by 2 rational numbers.
  */
 int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;
 
+/**
+ * Rescale a 64-bit integer by 2 rational numbers with specified rounding.
+ */
+int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,
+                         enum AVRounding) av_const;
+
+/**
+ * Compare 2 timestamps each in its own timebases.
+ * The result of the function is undefined if one of the timestamps
+ * is outside the int64_t range when represented in the others timebase.
+ * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position
+ */
+int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);
+
+/**
+ * Compare 2 integers modulo mod.
+ * That is we compare integers a and b for which only the least
+ * significant log2(mod) bits are known.
+ *
+ * @param mod must be a power of 2
+ * @return a negative value if a is smaller than b
+ *         a positive value if a is greater than b
+ *         0                if a equals          b
+ */
+int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod);
+
+/**
+ * @}
+ */
+
 #endif /* AVUTIL_MATHEMATICS_H */
diff --git a/extra_lib/include/libavutil/md5.h b/extra_lib/include/libavutil/md5.h
new file mode 100644 (file)
index 0000000..69199cc
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_MD5_H
+#define AVUTIL_MD5_H
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "version.h"
+
+/**
+ * @defgroup lavu_md5 MD5
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+#if FF_API_CONTEXT_SIZE
+extern attribute_deprecated const int av_md5_size;
+#endif
+
+struct AVMD5;
+
+struct AVMD5 *av_md5_alloc(void);
+void av_md5_init(struct AVMD5 *ctx);
+void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len);
+void av_md5_final(struct AVMD5 *ctx, uint8_t *dst);
+void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_MD5_H */
index e50553aefee85bfdd3f7c382fb4200924206bb6a..212dbf1773425802a92c5292a0580bd32774d470 100644 (file)
  */
 
 /**
- * @file libavutil/mem.h
+ * @file
  * memory handling functions
  */
 
 #ifndef AVUTIL_MEM_H
 #define AVUTIL_MEM_H
 
-#include "common.h"
+#include <limits.h>
+
+#include "attributes.h"
+#include "error.h"
+#include "avutil.h"
+
+/**
+ * @addtogroup lavu_mem
+ * @{
+ */
+
+
+#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C)
+    #define DECLARE_ALIGNED(n,t,v)      t __attribute__ ((aligned (n))) v
+    #define DECLARE_ASM_CONST(n,t,v)    const t __attribute__ ((aligned (n))) v
+#elif defined(__TI_COMPILER_VERSION__)
+    #define DECLARE_ALIGNED(n,t,v)                      \
+        AV_PRAGMA(DATA_ALIGN(v,n))                      \
+        t __attribute__((aligned(n))) v
+    #define DECLARE_ASM_CONST(n,t,v)                    \
+        AV_PRAGMA(DATA_ALIGN(v,n))                      \
+        static const t __attribute__((aligned(n))) v
+#elif defined(__GNUC__)
+    #define DECLARE_ALIGNED(n,t,v)      t __attribute__ ((aligned (n))) v
+    #define DECLARE_ASM_CONST(n,t,v)    static const t av_used __attribute__ ((aligned (n))) v
+#elif defined(_MSC_VER)
+    #define DECLARE_ALIGNED(n,t,v)      __declspec(align(n)) t v
+    #define DECLARE_ASM_CONST(n,t,v)    __declspec(align(n)) static const t v
+#else
+    #define DECLARE_ALIGNED(n,t,v)      t v
+    #define DECLARE_ASM_CONST(n,t,v)    static const t v
+#endif
 
 #if AV_GCC_VERSION_AT_LEAST(3,1)
     #define av_malloc_attrib __attribute__((__malloc__))
     #define av_malloc_attrib
 #endif
 
-#if (!defined(__ICC) || __ICC > 1100) && AV_GCC_VERSION_AT_LEAST(4,3)
-    #define av_alloc_size(n) __attribute__((alloc_size(n)))
+#if AV_GCC_VERSION_AT_LEAST(4,3)
+    #define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
 #else
-    #define av_alloc_size(n)
+    #define av_alloc_size(...)
 #endif
 
 /**
- * Allocates a block of \p size bytes with alignment suitable for all
+ * Allocate a block of size bytes with alignment suitable for all
  * memory accesses (including vectors if available on the CPU).
  * @param size Size in bytes for the memory block to be allocated.
  * @return Pointer to the allocated block, NULL if the block cannot
  * be allocated.
  * @see av_mallocz()
  */
-void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1);
+void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
 
 /**
- * Allocates or reallocates a block of memory.
- * If \p ptr is NULL and \p size > 0, allocates a new block. If \p
- * size is zero, frees the memory block pointed to by \p ptr.
- * @param size Size in bytes for the memory block to be allocated or
- * reallocated.
+ * Helper function to allocate a block of size * nmemb bytes with
+ * using av_malloc()
+ * @param nmemb Number of elements
+ * @param size Size of the single element
+ * @return Pointer to the allocated block, NULL if the block cannot
+ * be allocated.
+ * @see av_malloc()
+ */
+av_alloc_size(1,2) static inline void *av_malloc_array(size_t nmemb, size_t size)
+{
+    if (size <= 0 || nmemb >= INT_MAX / size)
+        return NULL;
+    return av_malloc(nmemb * size);
+}
+
+/**
+ * Allocate or reallocate a block of memory.
+ * If ptr is NULL and size > 0, allocate a new block. If
+ * size is zero, free the memory block pointed to by ptr.
  * @param ptr Pointer to a memory block already allocated with
  * av_malloc(z)() or av_realloc() or NULL.
+ * @param size Size in bytes for the memory block to be allocated or
+ * reallocated.
  * @return Pointer to a newly reallocated block or NULL if the block
  * cannot be reallocated or the function is used to free the memory block.
  * @see av_fast_realloc()
  */
-void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2);
+void *av_realloc(void *ptr, size_t size) av_alloc_size(2);
 
 /**
- * Frees a memory block which has been allocated with av_malloc(z)() or
+ * Allocate or reallocate a block of memory.
+ * This function does the same thing as av_realloc, except:
+ * - It takes two arguments and checks the result of the multiplication for
+ *   integer overflow.
+ * - It frees the input block in case of failure, thus avoiding the memory
+ *   leak with the classic "buf = realloc(buf); if (!buf) return -1;".
+ */
+void *av_realloc_f(void *ptr, size_t nelem, size_t elsize);
+
+/**
+ * Free a memory block which has been allocated with av_malloc(z)() or
  * av_realloc().
  * @param ptr Pointer to the memory block which should be freed.
  * @note ptr = NULL is explicitly allowed.
@@ -75,25 +132,54 @@ void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2);
 void av_free(void *ptr);
 
 /**
- * Allocates a block of \p size bytes with alignment suitable for all
+ * Allocate a block of size bytes with alignment suitable for all
  * memory accesses (including vectors if available on the CPU) and
- * zeroes all the bytes of the block.
+ * zero all the bytes of the block.
  * @param size Size in bytes for the memory block to be allocated.
  * @return Pointer to the allocated block, NULL if it cannot be allocated.
  * @see av_malloc()
  */
-void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1);
+void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1);
 
 /**
- * Duplicates the string \p s.
+ * Allocate a block of nmemb * size bytes with alignment suitable for all
+ * memory accesses (including vectors if available on the CPU) and
+ * zero all the bytes of the block.
+ * The allocation will fail if nmemb * size is greater than or equal
+ * to INT_MAX.
+ * @param nmemb
+ * @param size
+ * @return Pointer to the allocated block, NULL if it cannot be allocated.
+ */
+void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib;
+
+/**
+ * Helper function to allocate a block of size * nmemb bytes with
+ * using av_mallocz()
+ * @param nmemb Number of elements
+ * @param size Size of the single element
+ * @return Pointer to the allocated block, NULL if the block cannot
+ * be allocated.
+ * @see av_mallocz()
+ * @see av_malloc_array()
+ */
+av_alloc_size(1,2) static inline void *av_mallocz_array(size_t nmemb, size_t size)
+{
+    if (size <= 0 || nmemb >= INT_MAX / size)
+        return NULL;
+    return av_mallocz(nmemb * size);
+}
+
+/**
+ * Duplicate the string s.
  * @param s string to be duplicated
  * @return Pointer to a newly allocated string containing a
- * copy of \p s or NULL if the string cannot be allocated.
+ * copy of s or NULL if the string cannot be allocated.
  */
 char *av_strdup(const char *s) av_malloc_attrib;
 
 /**
- * Frees a memory block which has been allocated with av_malloc(z)() or
+ * Free a memory block which has been allocated with av_malloc(z)() or
  * av_realloc() and set the pointer pointing to it to NULL.
  * @param ptr Pointer to the pointer to the memory block which should
  * be freed.
@@ -101,4 +187,37 @@ char *av_strdup(const char *s) av_malloc_attrib;
  */
 void av_freep(void *ptr);
 
+/**
+ * Add an element to a dynamic array.
+ *
+ * @param tab_ptr Pointer to the array.
+ * @param nb_ptr  Pointer to the number of elements in the array.
+ * @param elem    Element to be added.
+ */
+void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem);
+
+/**
+ * Multiply two size_t values checking for overflow.
+ * @return  0 if success, AVERROR(EINVAL) if overflow.
+ */
+static inline int av_size_mult(size_t a, size_t b, size_t *r)
+{
+    size_t t = a * b;
+    /* Hack inspired from glibc: only try the division if nelem and elsize
+     * are both greater than sqrt(SIZE_MAX). */
+    if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b)
+        return AVERROR(EINVAL);
+    *r = t;
+    return 0;
+}
+
+/**
+ * Set the maximum size that may me allocated in one block.
+ */
+void av_max_alloc(size_t max);
+
+/**
+ * @}
+ */
+
 #endif /* AVUTIL_MEM_H */
diff --git a/extra_lib/include/libavutil/old_pix_fmts.h b/extra_lib/include/libavutil/old_pix_fmts.h
new file mode 100644 (file)
index 0000000..57b6992
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * copyright (c) 2006-2012 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_OLD_PIX_FMTS_H
+#define AVUTIL_OLD_PIX_FMTS_H
+
+/*
+ * This header exists to prevent new pixel formats from being accidentally added
+ * to the deprecated list.
+ * Do not include it directly. It will be removed on next major bump
+ *
+ * Do not add new items to this list. Use the AVPixelFormat enum instead.
+ */
+    PIX_FMT_NONE = AV_PIX_FMT_NONE,
+    PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
+    PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
+    PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
+    PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
+    PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
+    PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
+    PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
+    PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
+    PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
+    PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
+    PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
+    PIX_FMT_PAL8,      ///< 8 bit with PIX_FMT_RGB32 palette
+    PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
+    PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
+    PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+    PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
+    PIX_FMT_XVMC_MPEG2_IDCT,
+    PIX_FMT_UYVY422,   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
+    PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
+    PIX_FMT_BGR8,      ///< packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
+    PIX_FMT_BGR4,      ///< packed RGB 1:2:1 bitstream,  4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+    PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1B 2G 1R(lsb)
+    PIX_FMT_RGB8,      ///< packed RGB 3:3:2,  8bpp, (msb)2R 3G 3B(lsb)
+    PIX_FMT_RGB4,      ///< packed RGB 1:2:1 bitstream,  4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+    PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1R 2G 1B(lsb)
+    PIX_FMT_NV12,      ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)
+    PIX_FMT_NV21,      ///< as above, but U and V bytes are swapped
+
+    PIX_FMT_ARGB,      ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
+    PIX_FMT_RGBA,      ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
+    PIX_FMT_ABGR,      ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
+    PIX_FMT_BGRA,      ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
+
+    PIX_FMT_GRAY16BE,  ///<        Y        , 16bpp, big-endian
+    PIX_FMT_GRAY16LE,  ///<        Y        , 16bpp, little-endian
+    PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
+    PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
+    PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+    PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
+    PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
+
+    PIX_FMT_RGB565BE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), big-endian
+    PIX_FMT_RGB565LE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), little-endian
+    PIX_FMT_RGB555BE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0
+    PIX_FMT_RGB555LE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0
+
+    PIX_FMT_BGR565BE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), big-endian
+    PIX_FMT_BGR565LE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), little-endian
+    PIX_FMT_BGR555BE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1
+    PIX_FMT_BGR555LE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1
+
+    PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers
+    PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers
+    PIX_FMT_VAAPI_VLD,  ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+
+    PIX_FMT_YUV420P16LE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV420P16BE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV422P16LE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
+
+    PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
+    PIX_FMT_RGB444BE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
+    PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
+    PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
+    PIX_FMT_GRAY8A,    ///< 8bit gray, 8bit alpha
+    PIX_FMT_BGR48BE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian
+    PIX_FMT_BGR48LE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian
+
+    //the following 10 formats have the disadvantage of needing 1 format for each bit depth, thus
+    //If you want to support multiple bit depths, then using PIX_FMT_YUV420P16* with the bpp stored separately
+    //is better
+    PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_VDA_VLD,    ///< hardware decoding through VDA
+
+#ifdef AV_PIX_FMT_ABI_GIT_MASTER
+    PIX_FMT_RGBA64BE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    PIX_FMT_RGBA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+    PIX_FMT_BGRA64BE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    PIX_FMT_BGRA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+#endif
+    PIX_FMT_GBRP,      ///< planar GBR 4:4:4 24bpp
+    PIX_FMT_GBRP9BE,   ///< planar GBR 4:4:4 27bpp, big endian
+    PIX_FMT_GBRP9LE,   ///< planar GBR 4:4:4 27bpp, little endian
+    PIX_FMT_GBRP10BE,  ///< planar GBR 4:4:4 30bpp, big endian
+    PIX_FMT_GBRP10LE,  ///< planar GBR 4:4:4 30bpp, little endian
+    PIX_FMT_GBRP16BE,  ///< planar GBR 4:4:4 48bpp, big endian
+    PIX_FMT_GBRP16LE,  ///< planar GBR 4:4:4 48bpp, little endian
+
+#ifndef AV_PIX_FMT_ABI_GIT_MASTER
+    PIX_FMT_RGBA64BE=0x123,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    PIX_FMT_RGBA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+    PIX_FMT_BGRA64BE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    PIX_FMT_BGRA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+#endif
+    PIX_FMT_0RGB=0x123+4,      ///< packed RGB 8:8:8, 32bpp, 0RGB0RGB...
+    PIX_FMT_RGB0,      ///< packed RGB 8:8:8, 32bpp, RGB0RGB0...
+    PIX_FMT_0BGR,      ///< packed BGR 8:8:8, 32bpp, 0BGR0BGR...
+    PIX_FMT_BGR0,      ///< packed BGR 8:8:8, 32bpp, BGR0BGR0...
+    PIX_FMT_YUVA444P,  ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
+    PIX_FMT_YUVA422P,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
+
+    PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_GBRP12BE,    ///< planar GBR 4:4:4 36bpp, big endian
+    PIX_FMT_GBRP12LE,    ///< planar GBR 4:4:4 36bpp, little endian
+    PIX_FMT_GBRP14BE,    ///< planar GBR 4:4:4 42bpp, big endian
+    PIX_FMT_GBRP14LE,    ///< planar GBR 4:4:4 42bpp, little endian
+
+    PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
+#endif /* AVUTIL_OLD_PIX_FMTS_H */
diff --git a/extra_lib/include/libavutil/opt.h b/extra_lib/include/libavutil/opt.h
new file mode 100644 (file)
index 0000000..81fefd9
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+ * AVOptions
+ * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_OPT_H
+#define AVUTIL_OPT_H
+
+/**
+ * @file
+ * AVOptions
+ */
+
+#include "rational.h"
+#include "avutil.h"
+#include "dict.h"
+#include "log.h"
+
+/**
+ * @defgroup avoptions AVOptions
+ * @ingroup lavu_data
+ * @{
+ * AVOptions provide a generic system to declare options on arbitrary structs
+ * ("objects"). An option can have a help text, a type and a range of possible
+ * values. Options may then be enumerated, read and written to.
+ *
+ * @section avoptions_implement Implementing AVOptions
+ * This section describes how to add AVOptions capabilities to a struct.
+ *
+ * All AVOptions-related information is stored in an AVClass. Therefore
+ * the first member of the struct should be a pointer to an AVClass describing it.
+ * The option field of the AVClass must be set to a NULL-terminated static array
+ * of AVOptions. Each AVOption must have a non-empty name, a type, a default
+ * value and for number-type AVOptions also a range of allowed values. It must
+ * also declare an offset in bytes from the start of the struct, where the field
+ * associated with this AVOption is located. Other fields in the AVOption struct
+ * should also be set when applicable, but are not required.
+ *
+ * The following example illustrates an AVOptions-enabled struct:
+ * @code
+ * typedef struct test_struct {
+ *     AVClass *class;
+ *     int      int_opt;
+ *     char    *str_opt;
+ *     uint8_t *bin_opt;
+ *     int      bin_len;
+ * } test_struct;
+ *
+ * static const AVOption options[] = {
+ *   { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
+ *     AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX },
+ *   { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
+ *     AV_OPT_TYPE_STRING },
+ *   { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt),
+ *     AV_OPT_TYPE_BINARY },
+ *   { NULL },
+ * };
+ *
+ * static const AVClass test_class = {
+ *     .class_name = "test class",
+ *     .item_name  = av_default_item_name,
+ *     .option     = options,
+ *     .version    = LIBAVUTIL_VERSION_INT,
+ * };
+ * @endcode
+ *
+ * Next, when allocating your struct, you must ensure that the AVClass pointer
+ * is set to the correct value. Then, av_opt_set_defaults() can be called to
+ * initialize defaults. After that the struct is ready to be used with the
+ * AVOptions API.
+ *
+ * When cleaning up, you may use the av_opt_free() function to automatically
+ * free all the allocated string and binary options.
+ *
+ * Continuing with the above example:
+ *
+ * @code
+ * test_struct *alloc_test_struct(void)
+ * {
+ *     test_struct *ret = av_malloc(sizeof(*ret));
+ *     ret->class = &test_class;
+ *     av_opt_set_defaults(ret);
+ *     return ret;
+ * }
+ * void free_test_struct(test_struct **foo)
+ * {
+ *     av_opt_free(*foo);
+ *     av_freep(foo);
+ * }
+ * @endcode
+ *
+ * @subsection avoptions_implement_nesting Nesting
+ *      It may happen that an AVOptions-enabled struct contains another
+ *      AVOptions-enabled struct as a member (e.g. AVCodecContext in
+ *      libavcodec exports generic options, while its priv_data field exports
+ *      codec-specific options). In such a case, it is possible to set up the
+ *      parent struct to export a child's options. To do that, simply
+ *      implement AVClass.child_next() and AVClass.child_class_next() in the
+ *      parent struct's AVClass.
+ *      Assuming that the test_struct from above now also contains a
+ *      child_struct field:
+ *
+ *      @code
+ *      typedef struct child_struct {
+ *          AVClass *class;
+ *          int flags_opt;
+ *      } child_struct;
+ *      static const AVOption child_opts[] = {
+ *          { "test_flags", "This is a test option of flags type.",
+ *            offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX },
+ *          { NULL },
+ *      };
+ *      static const AVClass child_class = {
+ *          .class_name = "child class",
+ *          .item_name  = av_default_item_name,
+ *          .option     = child_opts,
+ *          .version    = LIBAVUTIL_VERSION_INT,
+ *      };
+ *
+ *      void *child_next(void *obj, void *prev)
+ *      {
+ *          test_struct *t = obj;
+ *          if (!prev && t->child_struct)
+ *              return t->child_struct;
+ *          return NULL
+ *      }
+ *      const AVClass child_class_next(const AVClass *prev)
+ *      {
+ *          return prev ? NULL : &child_class;
+ *      }
+ *      @endcode
+ *      Putting child_next() and child_class_next() as defined above into
+ *      test_class will now make child_struct's options accessible through
+ *      test_struct (again, proper setup as described above needs to be done on
+ *      child_struct right after it is created).
+ *
+ *      From the above example it might not be clear why both child_next()
+ *      and child_class_next() are needed. The distinction is that child_next()
+ *      iterates over actually existing objects, while child_class_next()
+ *      iterates over all possible child classes. E.g. if an AVCodecContext
+ *      was initialized to use a codec which has private options, then its
+ *      child_next() will return AVCodecContext.priv_data and finish
+ *      iterating. OTOH child_class_next() on AVCodecContext.av_class will
+ *      iterate over all available codecs with private options.
+ *
+ * @subsection avoptions_implement_named_constants Named constants
+ *      It is possible to create named constants for options. Simply set the unit
+ *      field of the option the constants should apply to to a string and
+ *      create the constants themselves as options of type AV_OPT_TYPE_CONST
+ *      with their unit field set to the same string.
+ *      Their default_val field should contain the value of the named
+ *      constant.
+ *      For example, to add some named constants for the test_flags option
+ *      above, put the following into the child_opts array:
+ *      @code
+ *      { "test_flags", "This is a test option of flags type.",
+ *        offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, "test_unit" },
+ *      { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { .i64 = 16 }, 0, 0, "test_unit" },
+ *      @endcode
+ *
+ * @section avoptions_use Using AVOptions
+ * This section deals with accessing options in an AVOptions-enabled struct.
+ * Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or
+ * AVFormatContext in libavformat.
+ *
+ * @subsection avoptions_use_examine Examining AVOptions
+ * The basic functions for examining options are av_opt_next(), which iterates
+ * over all options defined for one object, and av_opt_find(), which searches
+ * for an option with the given name.
+ *
+ * The situation is more complicated with nesting. An AVOptions-enabled struct
+ * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag
+ * to av_opt_find() will make the function search children recursively.
+ *
+ * For enumerating there are basically two cases. The first is when you want to
+ * get all options that may potentially exist on the struct and its children
+ * (e.g.  when constructing documentation). In that case you should call
+ * av_opt_child_class_next() recursively on the parent struct's AVClass.  The
+ * second case is when you have an already initialized struct with all its
+ * children and you want to get all options that can be actually written or read
+ * from it. In that case you should call av_opt_child_next() recursively (and
+ * av_opt_next() on each result).
+ *
+ * @subsection avoptions_use_get_set Reading and writing AVOptions
+ * When setting options, you often have a string read directly from the
+ * user. In such a case, simply passing it to av_opt_set() is enough. For
+ * non-string type options, av_opt_set() will parse the string according to the
+ * option type.
+ *
+ * Similarly av_opt_get() will read any option type and convert it to a string
+ * which will be returned. Do not forget that the string is allocated, so you
+ * have to free it with av_free().
+ *
+ * In some cases it may be more convenient to put all options into an
+ * AVDictionary and call av_opt_set_dict() on it. A specific case of this
+ * are the format/codec open functions in lavf/lavc which take a dictionary
+ * filled with option as a parameter. This allows to set some options
+ * that cannot be set otherwise, since e.g. the input file format is not known
+ * before the file is actually opened.
+ */
+
+enum AVOptionType{
+    AV_OPT_TYPE_FLAGS,
+    AV_OPT_TYPE_INT,
+    AV_OPT_TYPE_INT64,
+    AV_OPT_TYPE_DOUBLE,
+    AV_OPT_TYPE_FLOAT,
+    AV_OPT_TYPE_STRING,
+    AV_OPT_TYPE_RATIONAL,
+    AV_OPT_TYPE_BINARY,  ///< offset must point to a pointer immediately followed by an int for the length
+    AV_OPT_TYPE_CONST = 128,
+    AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers
+    AV_OPT_TYPE_PIXEL_FMT  = MKBETAG('P','F','M','T'),
+#if FF_API_OLD_AVOPTIONS
+    FF_OPT_TYPE_FLAGS = 0,
+    FF_OPT_TYPE_INT,
+    FF_OPT_TYPE_INT64,
+    FF_OPT_TYPE_DOUBLE,
+    FF_OPT_TYPE_FLOAT,
+    FF_OPT_TYPE_STRING,
+    FF_OPT_TYPE_RATIONAL,
+    FF_OPT_TYPE_BINARY,  ///< offset must point to a pointer immediately followed by an int for the length
+    FF_OPT_TYPE_CONST=128,
+#endif
+};
+
+/**
+ * AVOption
+ */
+typedef struct AVOption {
+    const char *name;
+
+    /**
+     * short English help text
+     * @todo What about other languages?
+     */
+    const char *help;
+
+    /**
+     * The offset relative to the context structure where the option
+     * value is stored. It should be 0 for named constants.
+     */
+    int offset;
+    enum AVOptionType type;
+
+    /**
+     * the default value for scalar options
+     */
+    union {
+        int64_t i64;
+        double dbl;
+        const char *str;
+        /* TODO those are unused now */
+        AVRational q;
+    } default_val;
+    double min;                 ///< minimum valid value for the option
+    double max;                 ///< maximum valid value for the option
+
+    int flags;
+#define AV_OPT_FLAG_ENCODING_PARAM  1   ///< a generic parameter which can be set by the user for muxing or encoding
+#define AV_OPT_FLAG_DECODING_PARAM  2   ///< a generic parameter which can be set by the user for demuxing or decoding
+#define AV_OPT_FLAG_METADATA        4   ///< some data extracted or inserted into the file like title, comment, ...
+#define AV_OPT_FLAG_AUDIO_PARAM     8
+#define AV_OPT_FLAG_VIDEO_PARAM     16
+#define AV_OPT_FLAG_SUBTITLE_PARAM  32
+#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
+//FIXME think about enc-audio, ... style flags
+
+    /**
+     * The logical unit to which the option belongs. Non-constant
+     * options and corresponding named constants share the same
+     * unit. May be NULL.
+     */
+    const char *unit;
+} AVOption;
+
+#if FF_API_FIND_OPT
+/**
+ * Look for an option in obj. Look only for the options which
+ * have the flags set as specified in mask and flags (that is,
+ * for which it is the case that opt->flags & mask == flags).
+ *
+ * @param[in] obj a pointer to a struct whose first element is a
+ * pointer to an AVClass
+ * @param[in] name the name of the option to look for
+ * @param[in] unit the unit of the option to look for, or any if NULL
+ * @return a pointer to the option found, or NULL if no option
+ * has been found
+ *
+ * @deprecated use av_opt_find.
+ */
+attribute_deprecated
+const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags);
+#endif
+
+#if FF_API_OLD_AVOPTIONS
+/**
+ * Set the field of obj with the given name to value.
+ *
+ * @param[in] obj A struct whose first element is a pointer to an
+ * AVClass.
+ * @param[in] name the name of the field to set
+ * @param[in] val The value to set. If the field is not of a string
+ * type, then the given string is parsed.
+ * SI postfixes and some named scalars are supported.
+ * If the field is of a numeric type, it has to be a numeric or named
+ * scalar. Behavior with more than one scalar and +- infix operators
+ * is undefined.
+ * If the field is of a flags type, it has to be a sequence of numeric
+ * scalars or named flags separated by '+' or '-'. Prefixing a flag
+ * with '+' causes it to be set without affecting the other flags;
+ * similarly, '-' unsets a flag.
+ * @param[out] o_out if non-NULL put here a pointer to the AVOption
+ * found
+ * @param alloc this parameter is currently ignored
+ * @return 0 if the value has been set, or an AVERROR code in case of
+ * error:
+ * AVERROR_OPTION_NOT_FOUND if no matching option exists
+ * AVERROR(ERANGE) if the value is out of range
+ * AVERROR(EINVAL) if the value is not valid
+ * @deprecated use av_opt_set()
+ */
+attribute_deprecated
+int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out);
+
+attribute_deprecated const AVOption *av_set_double(void *obj, const char *name, double n);
+attribute_deprecated const AVOption *av_set_q(void *obj, const char *name, AVRational n);
+attribute_deprecated const AVOption *av_set_int(void *obj, const char *name, int64_t n);
+
+double av_get_double(void *obj, const char *name, const AVOption **o_out);
+AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
+int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
+attribute_deprecated const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len);
+attribute_deprecated const AVOption *av_next_option(void *obj, const AVOption *last);
+#endif
+
+/**
+ * Show the obj options.
+ *
+ * @param req_flags requested flags for the options to show. Show only the
+ * options for which it is opt->flags & req_flags.
+ * @param rej_flags rejected flags for the options to show. Show only the
+ * options for which it is !(opt->flags & req_flags).
+ * @param av_log_obj log context to use for showing the options
+ */
+int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
+
+/**
+ * Set the values of all AVOption fields to their default values.
+ *
+ * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
+ */
+void av_opt_set_defaults(void *s);
+
+#if FF_API_OLD_AVOPTIONS
+attribute_deprecated
+void av_opt_set_defaults2(void *s, int mask, int flags);
+#endif
+
+/**
+ * Parse the key/value pairs list in opts. For each key/value pair
+ * found, stores the value in the field in ctx that is named like the
+ * key. ctx must be an AVClass context, storing is done using
+ * AVOptions.
+ *
+ * @param opts options string to parse, may be NULL
+ * @param key_val_sep a 0-terminated list of characters used to
+ * separate key from value
+ * @param pairs_sep a 0-terminated list of characters used to separate
+ * two pairs from each other
+ * @return the number of successfully set key/value pairs, or a negative
+ * value corresponding to an AVERROR code in case of error:
+ * AVERROR(EINVAL) if opts cannot be parsed,
+ * the error code issued by av_set_string3() if a key/value pair
+ * cannot be set
+ */
+int av_set_options_string(void *ctx, const char *opts,
+                          const char *key_val_sep, const char *pairs_sep);
+
+/**
+ * Parse the key-value pairs list in opts. For each key=value pair found,
+ * set the value of the corresponding option in ctx.
+ *
+ * @param ctx          the AVClass object to set options on
+ * @param opts         the options string, key-value pairs separated by a
+ *                     delimiter
+ * @param shorthand    a NULL-terminated array of options names for shorthand
+ *                     notation: if the first field in opts has no key part,
+ *                     the key is taken from the first element of shorthand;
+ *                     then again for the second, etc., until either opts is
+ *                     finished, shorthand is finished or a named option is
+ *                     found; after that, all options must be named
+ * @param key_val_sep  a 0-terminated list of characters used to separate
+ *                     key from value, for example '='
+ * @param pairs_sep    a 0-terminated list of characters used to separate
+ *                     two pairs from each other, for example ':' or ','
+ * @return  the number of successfully set key=value pairs, or a negative
+ *          value corresponding to an AVERROR code in case of error:
+ *          AVERROR(EINVAL) if opts cannot be parsed,
+ *          the error code issued by av_set_string3() if a key/value pair
+ *          cannot be set
+ *
+ * Options names must use only the following characters: a-z A-Z 0-9 - . / _
+ * Separators must use characters distinct from option names and from each
+ * other.
+ */
+int av_opt_set_from_string(void *ctx, const char *opts,
+                           const char *const *shorthand,
+                           const char *key_val_sep, const char *pairs_sep);
+/**
+ * Free all string and binary options in obj.
+ */
+void av_opt_free(void *obj);
+
+/**
+ * Check whether a particular flag is set in a flags field.
+ *
+ * @param field_name the name of the flag field option
+ * @param flag_name the name of the flag to check
+ * @return non-zero if the flag is set, zero if the flag isn't set,
+ *         isn't of the right type, or the flags field doesn't exist.
+ */
+int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
+
+/*
+ * Set all the options from a given dictionary on an object.
+ *
+ * @param obj a struct whose first element is a pointer to AVClass
+ * @param options options to process. This dictionary will be freed and replaced
+ *                by a new one containing all options not found in obj.
+ *                Of course this new dictionary needs to be freed by caller
+ *                with av_dict_free().
+ *
+ * @return 0 on success, a negative AVERROR if some option was found in obj,
+ *         but could not be set.
+ *
+ * @see av_dict_copy()
+ */
+int av_opt_set_dict(void *obj, struct AVDictionary **options);
+
+/**
+ * @defgroup opt_eval_funcs Evaluating option strings
+ * @{
+ * This group of functions can be used to evaluate option strings
+ * and get numbers out of them. They do the same thing as av_opt_set(),
+ * except the result is written into the caller-supplied pointer.
+ *
+ * @param obj a struct whose first element is a pointer to AVClass.
+ * @param o an option for which the string is to be evaluated.
+ * @param val string to be evaluated.
+ * @param *_out value of the string will be written here.
+ *
+ * @return 0 on success, a negative number on failure.
+ */
+int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int        *flags_out);
+int av_opt_eval_int   (void *obj, const AVOption *o, const char *val, int        *int_out);
+int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t    *int64_out);
+int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float      *float_out);
+int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double     *double_out);
+int av_opt_eval_q     (void *obj, const AVOption *o, const char *val, AVRational *q_out);
+/**
+ * @}
+ */
+
+#define AV_OPT_SEARCH_CHILDREN   0x0001 /**< Search in possible children of the
+                                             given object first. */
+/**
+ *  The obj passed to av_opt_find() is fake -- only a double pointer to AVClass
+ *  instead of a required pointer to a struct containing AVClass. This is
+ *  useful for searching for options without needing to allocate the corresponding
+ *  object.
+ */
+#define AV_OPT_SEARCH_FAKE_OBJ   0x0002
+
+/**
+ * Look for an option in an object. Consider only options which
+ * have all the specified flags set.
+ *
+ * @param[in] obj A pointer to a struct whose first element is a
+ *                pointer to an AVClass.
+ *                Alternatively a double pointer to an AVClass, if
+ *                AV_OPT_SEARCH_FAKE_OBJ search flag is set.
+ * @param[in] name The name of the option to look for.
+ * @param[in] unit When searching for named constants, name of the unit
+ *                 it belongs to.
+ * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
+ * @param search_flags A combination of AV_OPT_SEARCH_*.
+ *
+ * @return A pointer to the option found, or NULL if no option
+ *         was found.
+ *
+ * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable
+ * directly with av_set_string3(). Use special calls which take an options
+ * AVDictionary (e.g. avformat_open_input()) to set options found with this
+ * flag.
+ */
+const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
+                            int opt_flags, int search_flags);
+
+/**
+ * Look for an option in an object. Consider only options which
+ * have all the specified flags set.
+ *
+ * @param[in] obj A pointer to a struct whose first element is a
+ *                pointer to an AVClass.
+ *                Alternatively a double pointer to an AVClass, if
+ *                AV_OPT_SEARCH_FAKE_OBJ search flag is set.
+ * @param[in] name The name of the option to look for.
+ * @param[in] unit When searching for named constants, name of the unit
+ *                 it belongs to.
+ * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
+ * @param search_flags A combination of AV_OPT_SEARCH_*.
+ * @param[out] target_obj if non-NULL, an object to which the option belongs will be
+ * written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present
+ * in search_flags. This parameter is ignored if search_flags contain
+ * AV_OPT_SEARCH_FAKE_OBJ.
+ *
+ * @return A pointer to the option found, or NULL if no option
+ *         was found.
+ */
+const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
+                             int opt_flags, int search_flags, void **target_obj);
+
+/**
+ * Iterate over all AVOptions belonging to obj.
+ *
+ * @param obj an AVOptions-enabled struct or a double pointer to an
+ *            AVClass describing it.
+ * @param prev result of the previous call to av_opt_next() on this object
+ *             or NULL
+ * @return next AVOption or NULL
+ */
+const AVOption *av_opt_next(void *obj, const AVOption *prev);
+
+/**
+ * Iterate over AVOptions-enabled children of obj.
+ *
+ * @param prev result of a previous call to this function or NULL
+ * @return next AVOptions-enabled child or NULL
+ */
+void *av_opt_child_next(void *obj, void *prev);
+
+/**
+ * Iterate over potential AVOptions-enabled children of parent.
+ *
+ * @param prev result of a previous call to this function or NULL
+ * @return AVClass corresponding to next potential child or NULL
+ */
+const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev);
+
+/**
+ * @defgroup opt_set_funcs Option setting functions
+ * @{
+ * Those functions set the field of obj with the given name to value.
+ *
+ * @param[in] obj A struct whose first element is a pointer to an AVClass.
+ * @param[in] name the name of the field to set
+ * @param[in] val The value to set. In case of av_opt_set() if the field is not
+ * of a string type, then the given string is parsed.
+ * SI postfixes and some named scalars are supported.
+ * If the field is of a numeric type, it has to be a numeric or named
+ * scalar. Behavior with more than one scalar and +- infix operators
+ * is undefined.
+ * If the field is of a flags type, it has to be a sequence of numeric
+ * scalars or named flags separated by '+' or '-'. Prefixing a flag
+ * with '+' causes it to be set without affecting the other flags;
+ * similarly, '-' unsets a flag.
+ * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
+ * is passed here, then the option may be set on a child of obj.
+ *
+ * @return 0 if the value has been set, or an AVERROR code in case of
+ * error:
+ * AVERROR_OPTION_NOT_FOUND if no matching option exists
+ * AVERROR(ERANGE) if the value is out of range
+ * AVERROR(EINVAL) if the value is not valid
+ */
+int av_opt_set       (void *obj, const char *name, const char *val, int search_flags);
+int av_opt_set_int   (void *obj, const char *name, int64_t     val, int search_flags);
+int av_opt_set_double(void *obj, const char *name, double      val, int search_flags);
+int av_opt_set_q     (void *obj, const char *name, AVRational  val, int search_flags);
+int av_opt_set_bin   (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup opt_get_funcs Option getting functions
+ * @{
+ * Those functions get a value of the option with the given name from an object.
+ *
+ * @param[in] obj a struct whose first element is a pointer to an AVClass.
+ * @param[in] name name of the option to get.
+ * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
+ * is passed here, then the option may be found in a child of obj.
+ * @param[out] out_val value of the option will be written here
+ * @return 0 on success, a negative error code otherwise
+ */
+/**
+ * @note the returned string will av_malloc()ed and must be av_free()ed by the caller
+ */
+int av_opt_get       (void *obj, const char *name, int search_flags, uint8_t   **out_val);
+int av_opt_get_int   (void *obj, const char *name, int search_flags, int64_t    *out_val);
+int av_opt_get_double(void *obj, const char *name, int search_flags, double     *out_val);
+int av_opt_get_q     (void *obj, const char *name, int search_flags, AVRational *out_val);
+/**
+ * @}
+ */
+/**
+ * Gets a pointer to the requested field in a struct.
+ * This function allows accessing a struct even when its fields are moved or
+ * renamed since the application making the access has been compiled,
+ *
+ * @returns a pointer to the field, it can be cast to the correct type and read
+ *          or written to.
+ */
+void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_OPT_H */
diff --git a/extra_lib/include/libavutil/parseutils.h b/extra_lib/include/libavutil/parseutils.h
new file mode 100644 (file)
index 0000000..da7d345
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PARSEUTILS_H
+#define AVUTIL_PARSEUTILS_H
+
+#include <time.h>
+
+#include "rational.h"
+
+/**
+ * @file
+ * misc parsing utilities
+ */
+
+/**
+ * Parse str and store the parsed ratio in q.
+ *
+ * Note that a ratio with infinite (1/0) or negative value is
+ * considered valid, so you should check on the returned value if you
+ * want to exclude those values.
+ *
+ * The undefined value can be expressed using the "0:0" string.
+ *
+ * @param[in,out] q pointer to the AVRational which will contain the ratio
+ * @param[in] str the string to parse: it has to be a string in the format
+ * num:den, a float number or an expression
+ * @param[in] max the maximum allowed numerator and denominator
+ * @param[in] log_offset log level offset which is applied to the log
+ * level of log_ctx
+ * @param[in] log_ctx parent logging context
+ * @return >= 0 on success, a negative error code otherwise
+ */
+int av_parse_ratio(AVRational *q, const char *str, int max,
+                   int log_offset, void *log_ctx);
+
+#define av_parse_ratio_quiet(rate, str, max) \
+    av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL)
+
+/**
+ * Parse str and put in width_ptr and height_ptr the detected values.
+ *
+ * @param[in,out] width_ptr pointer to the variable which will contain the detected
+ * width value
+ * @param[in,out] height_ptr pointer to the variable which will contain the detected
+ * height value
+ * @param[in] str the string to parse: it has to be a string in the format
+ * width x height or a valid video size abbreviation.
+ * @return >= 0 on success, a negative error code otherwise
+ */
+int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str);
+
+/**
+ * Parse str and store the detected values in *rate.
+ *
+ * @param[in,out] rate pointer to the AVRational which will contain the detected
+ * frame rate
+ * @param[in] str the string to parse: it has to be a string in the format
+ * rate_num / rate_den, a float number or a valid video rate abbreviation
+ * @return >= 0 on success, a negative error code otherwise
+ */
+int av_parse_video_rate(AVRational *rate, const char *str);
+
+/**
+ * Put the RGBA values that correspond to color_string in rgba_color.
+ *
+ * @param color_string a string specifying a color. It can be the name of
+ * a color (case insensitive match) or a [0x|#]RRGGBB[AA] sequence,
+ * possibly followed by "@" and a string representing the alpha
+ * component.
+ * The alpha component may be a string composed by "0x" followed by an
+ * hexadecimal number or a decimal number between 0.0 and 1.0, which
+ * represents the opacity value (0x00/0.0 means completely transparent,
+ * 0xff/1.0 completely opaque).
+ * If the alpha component is not specified then 0xff is assumed.
+ * The string "random" will result in a random color.
+ * @param slen length of the initial part of color_string containing the
+ * color. It can be set to -1 if color_string is a null terminated string
+ * containing nothing else than the color.
+ * @return >= 0 in case of success, a negative value in case of
+ * failure (for example if color_string cannot be parsed).
+ */
+int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
+                   void *log_ctx);
+
+/**
+ * Parse timestr and return in *time a corresponding number of
+ * microseconds.
+ *
+ * @param timeval puts here the number of microseconds corresponding
+ * to the string in timestr. If the string represents a duration, it
+ * is the number of microseconds contained in the time interval.  If
+ * the string is a date, is the number of microseconds since 1st of
+ * January, 1970 up to the time of the parsed date.  If timestr cannot
+ * be successfully parsed, set *time to INT64_MIN.
+
+ * @param timestr a string representing a date or a duration.
+ * - If a date the syntax is:
+ * @code
+ * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH:MM:SS[.m...]]]}|{HHMMSS[.m...]]]}}[Z]
+ * now
+ * @endcode
+ * If the value is "now" it takes the current time.
+ * Time is local time unless Z is appended, in which case it is
+ * interpreted as UTC.
+ * If the year-month-day part is not specified it takes the current
+ * year-month-day.
+ * - If a duration the syntax is:
+ * @code
+ * [-]HH:MM:SS[.m...]]]
+ * [-]S+[.m...]
+ * @endcode
+ * @param duration flag which tells how to interpret timestr, if not
+ * zero timestr is interpreted as a duration, otherwise as a date
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code otherwise
+ */
+int av_parse_time(int64_t *timeval, const char *timestr, int duration);
+
+/**
+ * Parse the input string p according to the format string fmt and
+ * store its results in the structure dt.
+ * This implementation supports only a subset of the formats supported
+ * by the standard strptime().
+ *
+ * In particular it actually supports the parameters:
+ * - %H: the hour as a decimal number, using a 24-hour clock, in the
+ * range '00' through '23'
+ * - %M: the minute as a decimal number, using a 24-hour clock, in the
+ * range '00' through '59'
+ * - %S: the second as a decimal number, using a 24-hour clock, in the
+ * range '00' through '59'
+ * - %Y: the year as a decimal number, using the Gregorian calendar
+ * - %m: the month as a decimal number, in the range '1' through '12'
+ * - %d: the day of the month as a decimal number, in the range '1'
+ * through '31'
+ * - %%: a literal '%'
+ *
+ * @return a pointer to the first character not processed in this
+ * function call, or NULL in case the function fails to match all of
+ * the fmt string and therefore an error occurred
+ */
+char *av_small_strptime(const char *p, const char *fmt, struct tm *dt);
+
+/**
+ * Attempt to find a specific tag in a URL.
+ *
+ * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done.
+ * Return 1 if found.
+ */
+int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info);
+
+/**
+ * Convert the decomposed UTC time in tm to a time_t value.
+ */
+time_t av_timegm(struct tm *tm);
+
+#endif /* AVUTIL_PARSEUTILS_H */
diff --git a/extra_lib/include/libavutil/pixdesc.h b/extra_lib/include/libavutil/pixdesc.h
new file mode 100644 (file)
index 0000000..ccbee9b
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * pixel format descriptor
+ * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PIXDESC_H
+#define AVUTIL_PIXDESC_H
+
+#include <inttypes.h>
+#include "pixfmt.h"
+
+typedef struct AVComponentDescriptor{
+    uint16_t plane        :2;            ///< which of the 4 planes contains the component
+
+    /**
+     * Number of elements between 2 horizontally consecutive pixels minus 1.
+     * Elements are bits for bitstream formats, bytes otherwise.
+     */
+    uint16_t step_minus1  :3;
+
+    /**
+     * Number of elements before the component of the first pixel plus 1.
+     * Elements are bits for bitstream formats, bytes otherwise.
+     */
+    uint16_t offset_plus1 :3;
+    uint16_t shift        :3;            ///< number of least significant bits that must be shifted away to get the value
+    uint16_t depth_minus1 :4;            ///< number of bits in the component minus 1
+}AVComponentDescriptor;
+
+/**
+ * Descriptor that unambiguously describes how the bits of a pixel are
+ * stored in the up to 4 data planes of an image. It also stores the
+ * subsampling factors and number of components.
+ *
+ * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV
+ *       and all the YUV variants) AVPixFmtDescriptor just stores how values
+ *       are stored not what these values represent.
+ */
+typedef struct AVPixFmtDescriptor{
+    const char *name;
+    uint8_t nb_components;      ///< The number of components each pixel has, (1-4)
+
+    /**
+     * Amount to shift the luma width right to find the chroma width.
+     * For YV12 this is 1 for example.
+     * chroma_width = -((-luma_width) >> log2_chroma_w)
+     * The note above is needed to ensure rounding up.
+     * This value only refers to the chroma components.
+     */
+    uint8_t log2_chroma_w;      ///< chroma_width = -((-luma_width )>>log2_chroma_w)
+
+    /**
+     * Amount to shift the luma height right to find the chroma height.
+     * For YV12 this is 1 for example.
+     * chroma_height= -((-luma_height) >> log2_chroma_h)
+     * The note above is needed to ensure rounding up.
+     * This value only refers to the chroma components.
+     */
+    uint8_t log2_chroma_h;
+    uint8_t flags;
+
+    /**
+     * Parameters that describe how pixels are packed.
+     * If the format has 2 or 4 components, then alpha is last.
+     * If the format has 1 or 2 components, then luma is 0.
+     * If the format has 3 or 4 components,
+     * if the RGB flag is set then 0 is red, 1 is green and 2 is blue;
+     * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V.
+     */
+    AVComponentDescriptor comp[4];
+}AVPixFmtDescriptor;
+
+#define PIX_FMT_BE        1 ///< Pixel format is big-endian.
+#define PIX_FMT_PAL       2 ///< Pixel format has a palette in data[1], values are indexes in this palette.
+#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end.
+#define PIX_FMT_HWACCEL   8 ///< Pixel format is an HW accelerated format.
+#define PIX_FMT_PLANAR   16 ///< At least one pixel component is not in the first data plane
+#define PIX_FMT_RGB      32 ///< The pixel format contains RGB-like data (as opposed to YUV/grayscale)
+/**
+ * The pixel format is "pseudo-paletted". This means that FFmpeg treats it as
+ * paletted internally, but the palette is generated by the decoder and is not
+ * stored in the file.
+ */
+#define PIX_FMT_PSEUDOPAL 64
+
+#if FF_API_PIX_FMT_DESC
+/**
+ * The array of all the pixel format descriptors.
+ */
+extern const AVPixFmtDescriptor av_pix_fmt_descriptors[];
+#endif
+
+/**
+ * Read a line from an image, and write the values of the
+ * pixel format component c to dst.
+ *
+ * @param data the array containing the pointers to the planes of the image
+ * @param linesize the array containing the linesizes of the image
+ * @param desc the pixel format descriptor for the image
+ * @param x the horizontal coordinate of the first pixel to read
+ * @param y the vertical coordinate of the first pixel to read
+ * @param w the width of the line to read, that is the number of
+ * values to write to dst
+ * @param read_pal_component if not zero and the format is a paletted
+ * format writes the values corresponding to the palette
+ * component c in data[1] to dst, rather than the palette indexes in
+ * data[0]. The behavior is undefined if the format is not paletted.
+ */
+void av_read_image_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4],
+                        const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component);
+
+/**
+ * Write the values from src to the pixel format component c of an
+ * image line.
+ *
+ * @param src array containing the values to write
+ * @param data the array containing the pointers to the planes of the
+ * image to write into. It is supposed to be zeroed.
+ * @param linesize the array containing the linesizes of the image
+ * @param desc the pixel format descriptor for the image
+ * @param x the horizontal coordinate of the first pixel to write
+ * @param y the vertical coordinate of the first pixel to write
+ * @param w the width of the line to write, that is the number of
+ * values to write to the image line
+ */
+void av_write_image_line(const uint16_t *src, uint8_t *data[4], const int linesize[4],
+                         const AVPixFmtDescriptor *desc, int x, int y, int c, int w);
+
+/**
+ * Return the pixel format corresponding to name.
+ *
+ * If there is no pixel format with name name, then looks for a
+ * pixel format with the name corresponding to the native endian
+ * format of name.
+ * For example in a little-endian system, first looks for "gray16",
+ * then for "gray16le".
+ *
+ * Finally if no pixel format has been found, returns AV_PIX_FMT_NONE.
+ */
+enum AVPixelFormat av_get_pix_fmt(const char *name);
+
+/**
+ * Return the short name for a pixel format, NULL in case pix_fmt is
+ * unknown.
+ *
+ * @see av_get_pix_fmt(), av_get_pix_fmt_string()
+ */
+const char *av_get_pix_fmt_name(enum AVPixelFormat pix_fmt);
+
+/**
+ * Print in buf the string corresponding to the pixel format with
+ * number pix_fmt, or an header if pix_fmt is negative.
+ *
+ * @param buf the buffer where to write the string
+ * @param buf_size the size of buf
+ * @param pix_fmt the number of the pixel format to print the
+ * corresponding info string, or a negative value to print the
+ * corresponding header.
+ */
+char *av_get_pix_fmt_string (char *buf, int buf_size, enum AVPixelFormat pix_fmt);
+
+/**
+ * Return the number of bits per pixel used by the pixel format
+ * described by pixdesc.
+ *
+ * The returned number of bits refers to the number of bits actually
+ * used for storing the pixel information, that is padding bits are
+ * not counted.
+ */
+int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc);
+
+/**
+ * @return a pixel format descriptor for provided pixel format or NULL if
+ * this pixel format is unknown.
+ */
+const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt);
+
+/**
+ * Iterate over all pixel format descriptors known to libavutil.
+ *
+ * @param prev previous descriptor. NULL to get the first descriptor.
+ *
+ * @return next descriptor or NULL after the last descriptor
+ */
+const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev);
+
+/**
+ * @return an AVPixelFormat id described by desc, or AV_PIX_FMT_NONE if desc
+ * is not a valid pointer to a pixel format descriptor.
+ */
+enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc);
+
+#endif /* AVUTIL_PIXDESC_H */
index 4995a4da196ab3a80fbe7e43f7508f258419d53d..ef7a16ae062e44f2cca1e0cd823f499b270408cc 100644 (file)
 #define AVUTIL_PIXFMT_H
 
 /**
- * @file libavutil/pixfmt.h
+ * @file
  * pixel format definitions
  *
- * @warning This file has to be considered an internal but installed
- * header, so it should not be directly included in your projects.
  */
 
+#include "libavutil/avconfig.h"
+#include "libavutil/version.h"
+
+#define AVPALETTE_SIZE 1024
+#define AVPALETTE_COUNT 256
+
 /**
- * Pixel format. Notes:
+ * Pixel format.
  *
+ * @note
  * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
  * color is put together as:
  *  (A << 24) | (R << 16) | (G << 8) | B
  * This is stored as BGRA on little-endian CPU architectures and ARGB on
  * big-endian CPUs.
  *
+ * @par
  * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized
  * image data is stored in AVFrame.data[0]. The palette is transported in
  * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
  * This is important as many custom PAL8 video codecs that were designed
  * to run on the IBM VGA graphics adapter use 6-bit palette components.
  *
+ * @par
  * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like
  * for pal8. This palette is filled in automatically by the function
  * allocating the picture.
  *
- * Note, make sure that all newly added big endian formats have pix_fmt&1==1
- *       and that all newly added little endian formats have pix_fmt&1==0
- *       this allows simpler detection of big vs little endian.
+ * @note
+ * make sure that all newly added big endian formats have pix_fmt&1==1
+ * and that all newly added little endian formats have pix_fmt&1==0
+ * this allows simpler detection of big vs little endian.
  */
-enum PixelFormat {
-    PIX_FMT_NONE= -1,
-    PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
-    PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
-    PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
-    PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
-    PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
-    PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
-    PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
-    PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
-    PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
-    PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black
-    PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white
-    PIX_FMT_PAL8,      ///< 8 bit with PIX_FMT_RGB32 palette
-    PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG)
-    PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG)
-    PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG)
-    PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
-    PIX_FMT_XVMC_MPEG2_IDCT,
-    PIX_FMT_UYVY422,   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
-    PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
-    PIX_FMT_BGR8,      ///< packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
-    PIX_FMT_BGR4,      ///< packed RGB 1:2:1,  4bpp, (msb)1B 2G 1R(lsb)
-    PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1B 2G 1R(lsb)
-    PIX_FMT_RGB8,      ///< packed RGB 3:3:2,  8bpp, (msb)2R 3G 3B(lsb)
-    PIX_FMT_RGB4,      ///< packed RGB 1:2:1,  4bpp, (msb)1R 2G 1B(lsb)
-    PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1R 2G 1B(lsb)
-    PIX_FMT_NV12,      ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV
-    PIX_FMT_NV21,      ///< as above, but U and V bytes are swapped
-
-    PIX_FMT_ARGB,      ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
-    PIX_FMT_RGBA,      ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
-    PIX_FMT_ABGR,      ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
-    PIX_FMT_BGRA,      ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
-
-    PIX_FMT_GRAY16BE,  ///<        Y        , 16bpp, big-endian
-    PIX_FMT_GRAY16LE,  ///<        Y        , 16bpp, little-endian
-    PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
-    PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG)
-    PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
-    PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
-    PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
-    PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
-    PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
-    PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
-    PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian
-    PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian
-
-    PIX_FMT_RGB565BE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), big-endian
-    PIX_FMT_RGB565LE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), little-endian
-    PIX_FMT_RGB555BE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0
-    PIX_FMT_RGB555LE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0
-
-    PIX_FMT_BGR565BE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), big-endian
-    PIX_FMT_BGR565LE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), little-endian
-    PIX_FMT_BGR555BE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1
-    PIX_FMT_BGR555LE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1
-
-    PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers
-    PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers
-    PIX_FMT_VAAPI_VLD,  ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
-
-    PIX_FMT_YUV420PLE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
-    PIX_FMT_YUV420PBE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
-    PIX_FMT_YUV422PLE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
-    PIX_FMT_YUV422PBE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
-    PIX_FMT_YUV444PLE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
-    PIX_FMT_YUV444PBE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
-    PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
+enum AVPixelFormat {
+    AV_PIX_FMT_NONE = -1,
+    AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
+    AV_PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
+    AV_PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
+    AV_PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
+    AV_PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
+    AV_PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
+    AV_PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
+    AV_PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
+    AV_PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
+    AV_PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
+    AV_PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
+    AV_PIX_FMT_PAL8,      ///< 8 bit with PIX_FMT_RGB32 palette
+    AV_PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
+    AV_PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
+    AV_PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+    AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
+    AV_PIX_FMT_XVMC_MPEG2_IDCT,
+    AV_PIX_FMT_UYVY422,   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
+    AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
+    AV_PIX_FMT_BGR8,      ///< packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
+    AV_PIX_FMT_BGR4,      ///< packed RGB 1:2:1 bitstream,  4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+    AV_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1B 2G 1R(lsb)
+    AV_PIX_FMT_RGB8,      ///< packed RGB 3:3:2,  8bpp, (msb)2R 3G 3B(lsb)
+    AV_PIX_FMT_RGB4,      ///< packed RGB 1:2:1 bitstream,  4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+    AV_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1R 2G 1B(lsb)
+    AV_PIX_FMT_NV12,      ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)
+    AV_PIX_FMT_NV21,      ///< as above, but U and V bytes are swapped
+
+    AV_PIX_FMT_ARGB,      ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
+    AV_PIX_FMT_RGBA,      ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
+    AV_PIX_FMT_ABGR,      ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
+    AV_PIX_FMT_BGRA,      ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
+
+    AV_PIX_FMT_GRAY16BE,  ///<        Y        , 16bpp, big-endian
+    AV_PIX_FMT_GRAY16LE,  ///<        Y        , 16bpp, little-endian
+    AV_PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
+    AV_PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
+    AV_PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+    AV_PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    AV_PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    AV_PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    AV_PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    AV_PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    AV_PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
+    AV_PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
+
+    AV_PIX_FMT_RGB565BE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), big-endian
+    AV_PIX_FMT_RGB565LE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), little-endian
+    AV_PIX_FMT_RGB555BE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0
+    AV_PIX_FMT_RGB555LE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0
+
+    AV_PIX_FMT_BGR565BE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), big-endian
+    AV_PIX_FMT_BGR565LE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), little-endian
+    AV_PIX_FMT_BGR555BE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1
+    AV_PIX_FMT_BGR555LE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1
+
+    AV_PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers
+    AV_PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers
+    AV_PIX_FMT_VAAPI_VLD,  ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+
+    AV_PIX_FMT_YUV420P16LE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV420P16BE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV422P16LE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    AV_PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    AV_PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    AV_PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
+
+    AV_PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
+    AV_PIX_FMT_RGB444BE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
+    AV_PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
+    AV_PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
+    AV_PIX_FMT_GRAY8A,    ///< 8bit gray, 8bit alpha
+    AV_PIX_FMT_BGR48BE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian
+    AV_PIX_FMT_BGR48LE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian
+
+    //the following 10 formats have the disadvantage of needing 1 format for each bit depth, thus
+    //If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately
+    //is better
+    AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    AV_PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    AV_PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_VDA_VLD,    ///< hardware decoding through VDA
+
+#ifdef AV_PIX_FMT_ABI_GIT_MASTER
+    AV_PIX_FMT_RGBA64BE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    AV_PIX_FMT_RGBA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+    AV_PIX_FMT_BGRA64BE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    AV_PIX_FMT_BGRA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+#endif
+    AV_PIX_FMT_GBRP,      ///< planar GBR 4:4:4 24bpp
+    AV_PIX_FMT_GBRP9BE,   ///< planar GBR 4:4:4 27bpp, big endian
+    AV_PIX_FMT_GBRP9LE,   ///< planar GBR 4:4:4 27bpp, little endian
+    AV_PIX_FMT_GBRP10BE,  ///< planar GBR 4:4:4 30bpp, big endian
+    AV_PIX_FMT_GBRP10LE,  ///< planar GBR 4:4:4 30bpp, little endian
+    AV_PIX_FMT_GBRP16BE,  ///< planar GBR 4:4:4 48bpp, big endian
+    AV_PIX_FMT_GBRP16LE,  ///< planar GBR 4:4:4 48bpp, little endian
+
+    /**
+     * duplicated pixel formats for compatibility with libav.
+     * FFmpeg supports these formats since May 8 2012 and Jan 28 2012 (commits f9ca1ac7 and 143a5c55)
+     * Libav added them Oct 12 2012 with incompatible values (commit 6d5600e85)
+     */
+    AV_PIX_FMT_YUVA422P_LIBAV,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
+    AV_PIX_FMT_YUVA444P_LIBAV,  ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
+
+#ifndef AV_PIX_FMT_ABI_GIT_MASTER
+    AV_PIX_FMT_RGBA64BE=0x123,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    AV_PIX_FMT_RGBA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+    AV_PIX_FMT_BGRA64BE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
+    AV_PIX_FMT_BGRA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
+#endif
+    AV_PIX_FMT_0RGB=0x123+4,      ///< packed RGB 8:8:8, 32bpp, 0RGB0RGB...
+    AV_PIX_FMT_RGB0,      ///< packed RGB 8:8:8, 32bpp, RGB0RGB0...
+    AV_PIX_FMT_0BGR,      ///< packed BGR 8:8:8, 32bpp, 0BGR0BGR...
+    AV_PIX_FMT_BGR0,      ///< packed BGR 8:8:8, 32bpp, BGR0BGR0...
+    AV_PIX_FMT_YUVA444P,  ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
+    AV_PIX_FMT_YUVA422P,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
+
+    AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    AV_PIX_FMT_GBRP12BE,    ///< planar GBR 4:4:4 36bpp, big endian
+    AV_PIX_FMT_GBRP12LE,    ///< planar GBR 4:4:4 36bpp, little endian
+    AV_PIX_FMT_GBRP14BE,    ///< planar GBR 4:4:4 42bpp, big endian
+    AV_PIX_FMT_GBRP14LE,    ///< planar GBR 4:4:4 42bpp, little endian
+
+    AV_PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
+
+#if FF_API_PIX_FMT
+#include "old_pix_fmts.h"
+#endif
 };
 
-#ifdef WORDS_BIGENDIAN
-#   define PIX_FMT_NE(be, le) PIX_FMT_##be
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+#define AV_PIX_FMT_YUVA422P AV_PIX_FMT_YUVA422P_LIBAV
+#define AV_PIX_FMT_YUVA444P AV_PIX_FMT_YUVA444P_LIBAV
+#endif
+
+
+#define AV_PIX_FMT_Y400A AV_PIX_FMT_GRAY8A
+#define AV_PIX_FMT_GBR24P AV_PIX_FMT_GBRP
+
+#if AV_HAVE_BIGENDIAN
+#   define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be
 #else
-#   define PIX_FMT_NE(be, le) PIX_FMT_##le
+#   define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##le
 #endif
 
-#define PIX_FMT_RGB32   PIX_FMT_NE(ARGB, BGRA)
-#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR)
-#define PIX_FMT_BGR32   PIX_FMT_NE(ABGR, RGBA)
-#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB)
-
-#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE)
-#define PIX_FMT_RGB48  PIX_FMT_NE(RGB48BE,  RGB48LE)
-#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE)
-#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE)
-#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE)
-#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE)
-
-#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420PBE, YUV420PLE)
-#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422PBE, YUV422PLE)
-#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444PBE, YUV444PLE)
+#define AV_PIX_FMT_RGB32   AV_PIX_FMT_NE(ARGB, BGRA)
+#define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR)
+#define AV_PIX_FMT_BGR32   AV_PIX_FMT_NE(ABGR, RGBA)
+#define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB)
+#define AV_PIX_FMT_0RGB32  AV_PIX_FMT_NE(0RGB, BGR0)
+#define AV_PIX_FMT_0BGR32  AV_PIX_FMT_NE(0BGR, RGB0)
+
+#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE)
+#define AV_PIX_FMT_RGB48  AV_PIX_FMT_NE(RGB48BE,  RGB48LE)
+#define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE)
+#define AV_PIX_FMT_RGB555 AV_PIX_FMT_NE(RGB555BE, RGB555LE)
+#define AV_PIX_FMT_RGB444 AV_PIX_FMT_NE(RGB444BE, RGB444LE)
+#define AV_PIX_FMT_BGR48  AV_PIX_FMT_NE(BGR48BE,  BGR48LE)
+#define AV_PIX_FMT_BGR565 AV_PIX_FMT_NE(BGR565BE, BGR565LE)
+#define AV_PIX_FMT_BGR555 AV_PIX_FMT_NE(BGR555BE, BGR555LE)
+#define AV_PIX_FMT_BGR444 AV_PIX_FMT_NE(BGR444BE, BGR444LE)
+
+#define AV_PIX_FMT_YUV420P9  AV_PIX_FMT_NE(YUV420P9BE , YUV420P9LE)
+#define AV_PIX_FMT_YUV422P9  AV_PIX_FMT_NE(YUV422P9BE , YUV422P9LE)
+#define AV_PIX_FMT_YUV444P9  AV_PIX_FMT_NE(YUV444P9BE , YUV444P9LE)
+#define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE)
+#define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE)
+#define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE)
+#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE)
+#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE)
+#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE)
+#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE)
+#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE)
+#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE)
+#define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE)
+#define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE)
+#define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
+
+#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE)
+#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE)
+#define AV_PIX_FMT_GBRP9     AV_PIX_FMT_NE(GBRP9BE ,    GBRP9LE)
+#define AV_PIX_FMT_GBRP10    AV_PIX_FMT_NE(GBRP10BE,    GBRP10LE)
+#define AV_PIX_FMT_GBRP12    AV_PIX_FMT_NE(GBRP12BE,    GBRP12LE)
+#define AV_PIX_FMT_GBRP14    AV_PIX_FMT_NE(GBRP14BE,    GBRP14LE)
+#define AV_PIX_FMT_GBRP16    AV_PIX_FMT_NE(GBRP16BE,    GBRP16LE)
+
+#if FF_API_PIX_FMT
+#define PixelFormat AVPixelFormat
+
+#define PIX_FMT_Y400A AV_PIX_FMT_Y400A
+#define PIX_FMT_GBR24P AV_PIX_FMT_GBR24P
+
+#define PIX_FMT_NE(be, le) AV_PIX_FMT_NE(be, le)
+
+#define PIX_FMT_RGB32   AV_PIX_FMT_RGB32
+#define PIX_FMT_RGB32_1 AV_PIX_FMT_RGB32_1
+#define PIX_FMT_BGR32   AV_PIX_FMT_BGR32
+#define PIX_FMT_BGR32_1 AV_PIX_FMT_BGR32_1
+#define PIX_FMT_0RGB32  AV_PIX_FMT_0RGB32
+#define PIX_FMT_0BGR32  AV_PIX_FMT_0BGR32
+
+#define PIX_FMT_GRAY16 AV_PIX_FMT_GRAY16
+#define PIX_FMT_RGB48  AV_PIX_FMT_RGB48
+#define PIX_FMT_RGB565 AV_PIX_FMT_RGB565
+#define PIX_FMT_RGB555 AV_PIX_FMT_RGB555
+#define PIX_FMT_RGB444 AV_PIX_FMT_RGB444
+#define PIX_FMT_BGR48  AV_PIX_FMT_BGR48
+#define PIX_FMT_BGR565 AV_PIX_FMT_BGR565
+#define PIX_FMT_BGR555 AV_PIX_FMT_BGR555
+#define PIX_FMT_BGR444 AV_PIX_FMT_BGR444
+
+#define PIX_FMT_YUV420P9  AV_PIX_FMT_YUV420P9
+#define PIX_FMT_YUV422P9  AV_PIX_FMT_YUV422P9
+#define PIX_FMT_YUV444P9  AV_PIX_FMT_YUV444P9
+#define PIX_FMT_YUV420P10 AV_PIX_FMT_YUV420P10
+#define PIX_FMT_YUV422P10 AV_PIX_FMT_YUV422P10
+#define PIX_FMT_YUV444P10 AV_PIX_FMT_YUV444P10
+#define PIX_FMT_YUV420P12 AV_PIX_FMT_YUV420P12
+#define PIX_FMT_YUV422P12 AV_PIX_FMT_YUV422P12
+#define PIX_FMT_YUV444P12 AV_PIX_FMT_YUV444P12
+#define PIX_FMT_YUV420P14 AV_PIX_FMT_YUV420P14
+#define PIX_FMT_YUV422P14 AV_PIX_FMT_YUV422P14
+#define PIX_FMT_YUV444P14 AV_PIX_FMT_YUV444P14
+#define PIX_FMT_YUV420P16 AV_PIX_FMT_YUV420P16
+#define PIX_FMT_YUV422P16 AV_PIX_FMT_YUV422P16
+#define PIX_FMT_YUV444P16 AV_PIX_FMT_YUV444P16
+
+#define PIX_FMT_RGBA64 AV_PIX_FMT_RGBA64
+#define PIX_FMT_BGRA64 AV_PIX_FMT_BGRA64
+#define PIX_FMT_GBRP9  AV_PIX_FMT_GBRP9
+#define PIX_FMT_GBRP10 AV_PIX_FMT_GBRP10
+#define PIX_FMT_GBRP12 AV_PIX_FMT_GBRP12
+#define PIX_FMT_GBRP14 AV_PIX_FMT_GBRP14
+#define PIX_FMT_GBRP16 AV_PIX_FMT_GBRP16
+#endif
 
 #endif /* AVUTIL_PIXFMT_H */
diff --git a/extra_lib/include/libavutil/random_seed.h b/extra_lib/include/libavutil/random_seed.h
new file mode 100644 (file)
index 0000000..0462a04
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_RANDOM_SEED_H
+#define AVUTIL_RANDOM_SEED_H
+
+#include <stdint.h>
+/**
+ * @addtogroup lavu_crypto
+ * @{
+ */
+
+/**
+ * Get a seed to use in conjunction with random functions.
+ * This function tries to provide a good seed at a best effort bases.
+ * Its possible to call this function multiple times if more bits are needed.
+ * It can be quite slow, which is why it should only be used as seed for a faster
+ * PRNG. The quality of the seed depends on the platform.
+ */
+uint32_t av_get_random_seed(void);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_RANDOM_SEED_H */
index 048202b0bcf65ba1c52717114ea19f6784ab0d17..417e29e5779fff362386781c7236db0f265854c5 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /**
- * @file libavutil/rational.h
+ * @file
  * rational numbers
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 #ifndef AVUTIL_RATIONAL_H
 #define AVUTIL_RATIONAL_H
 
-#if !defined(WIN32) && !defined(_WIN32_WCE)
 #include <stdint.h>
-#endif
-#include "common.h"
+#include <limits.h>
+#include "attributes.h"
+
+/**
+ * @addtogroup lavu_math
+ * @{
+ */
 
 /**
  * rational number numerator/denominator
@@ -42,20 +46,23 @@ typedef struct AVRational{
 } AVRational;
 
 /**
- * Compares two rationals.
+ * Compare two rationals.
  * @param a first rational
  * @param b second rational
- * @return 0 if a==b, 1 if a>b and -1 if a<b
+ * @return 0 if a==b, 1 if a>b, -1 if a<b, and INT_MIN if one of the
+ * values is of the form 0/0
  */
 static inline int av_cmp_q(AVRational a, AVRational b){
     const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;
 
-    if(tmp) return (tmp>>63)|1;
-    else    return 0;
+    if(tmp) return ((tmp ^ a.den ^ b.den)>>63)|1;
+    else if(b.den && a.den) return 0;
+    else if(a.num && b.num) return (a.num>>31) - (b.num>>31);
+    else                    return INT_MIN;
 }
 
 /**
- * Converts rational to double.
+ * Convert rational to double.
  * @param a rational to convert
  * @return (double) a
  */
@@ -64,7 +71,7 @@ static inline double av_q2d(AVRational a){
 }
 
 /**
- * Reduces a fraction.
+ * Reduce a fraction.
  * This is useful for framerate calculations.
  * @param dst_num destination numerator
  * @param dst_den destination denominator
@@ -76,7 +83,7 @@ static inline double av_q2d(AVRational a){
 int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max);
 
 /**
- * Multiplies two rationals.
+ * Multiply two rationals.
  * @param b first rational
  * @param c second rational
  * @return b*c
@@ -84,7 +91,7 @@ int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
 AVRational av_mul_q(AVRational b, AVRational c) av_const;
 
 /**
- * Divides one rational by another.
+ * Divide one rational by another.
  * @param b first rational
  * @param c second rational
  * @return b/c
@@ -92,7 +99,7 @@ AVRational av_mul_q(AVRational b, AVRational c) av_const;
 AVRational av_div_q(AVRational b, AVRational c) av_const;
 
 /**
- * Adds two rationals.
+ * Add two rationals.
  * @param b first rational
  * @param c second rational
  * @return b+c
@@ -100,7 +107,7 @@ AVRational av_div_q(AVRational b, AVRational c) av_const;
 AVRational av_add_q(AVRational b, AVRational c) av_const;
 
 /**
- * Subtracts one rational from another.
+ * Subtract one rational from another.
  * @param b first rational
  * @param c second rational
  * @return b-c
@@ -108,7 +115,20 @@ AVRational av_add_q(AVRational b, AVRational c) av_const;
 AVRational av_sub_q(AVRational b, AVRational c) av_const;
 
 /**
- * Converts a double precision floating point number to a rational.
+ * Invert a rational.
+ * @param q value
+ * @return 1 / q
+ */
+static av_always_inline AVRational av_inv_q(AVRational q)
+{
+    AVRational r = { q.den, q.num };
+    return r;
+}
+
+/**
+ * Convert a double precision floating point number to a rational.
+ * inf is expressed as {1,0} or {-1,0} depending on the sign.
+ *
  * @param d double to convert
  * @param max the maximum allowed numerator and denominator
  * @return (AVRational) d
@@ -116,16 +136,20 @@ AVRational av_sub_q(AVRational b, AVRational c) av_const;
 AVRational av_d2q(double d, int max) av_const;
 
 /**
- * @return 1 if \q1 is nearer to \p q than \p q2, -1 if \p q2 is nearer
- * than \p q1, 0 if they have the same distance.
+ * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer
+ * than q1, 0 if they have the same distance.
  */
 int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
 
 /**
- * Finds the nearest value in \p q_list to \p q.
+ * Find the nearest value in q_list to q.
  * @param q_list an array of rationals terminated by {0, 0}
  * @return the index of the nearest value found in the array
  */
 int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
 
+/**
+ * @}
+ */
+
 #endif /* AVUTIL_RATIONAL_H */
diff --git a/extra_lib/include/libavutil/samplefmt.h b/extra_lib/include/libavutil/samplefmt.h
new file mode 100644 (file)
index 0000000..17300d1
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_SAMPLEFMT_H
+#define AVUTIL_SAMPLEFMT_H
+
+#include <stdint.h>
+
+#include "avutil.h"
+#include "attributes.h"
+
+/**
+ * Audio Sample Formats
+ *
+ * @par
+ * The data described by the sample format is always in native-endian order.
+ * Sample values can be expressed by native C types, hence the lack of a signed
+ * 24-bit sample format even though it is a common raw audio data format.
+ *
+ * @par
+ * The floating-point formats are based on full volume being in the range
+ * [-1.0, 1.0]. Any values outside this range are beyond full volume level.
+ *
+ * @par
+ * The data layout as used in av_samples_fill_arrays() and elsewhere in Libav
+ * (such as AVFrame in libavcodec) is as follows:
+ *
+ * For planar sample formats, each audio channel is in a separate data plane,
+ * and linesize is the buffer size, in bytes, for a single plane. All data
+ * planes must be the same size. For packed sample formats, only the first data
+ * plane is used, and samples for each channel are interleaved. In this case,
+ * linesize is the buffer size, in bytes, for the 1 plane.
+ */
+enum AVSampleFormat {
+    AV_SAMPLE_FMT_NONE = -1,
+    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
+    AV_SAMPLE_FMT_S16,         ///< signed 16 bits
+    AV_SAMPLE_FMT_S32,         ///< signed 32 bits
+    AV_SAMPLE_FMT_FLT,         ///< float
+    AV_SAMPLE_FMT_DBL,         ///< double
+
+    AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
+    AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
+    AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
+    AV_SAMPLE_FMT_FLTP,        ///< float, planar
+    AV_SAMPLE_FMT_DBLP,        ///< double, planar
+
+    AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
+};
+
+/**
+ * Return the name of sample_fmt, or NULL if sample_fmt is not
+ * recognized.
+ */
+const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt);
+
+/**
+ * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE
+ * on error.
+ */
+enum AVSampleFormat av_get_sample_fmt(const char *name);
+
+/**
+ * Return the planar<->packed alternative form of the given sample format, or
+ * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the
+ * requested planar/packed format, the format returned is the same as the
+ * input.
+ */
+enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar);
+
+/**
+ * Get the packed alternative form of the given sample format.
+ *
+ * If the passed sample_fmt is already in packed format, the format returned is
+ * the same as the input.
+ *
+ * @return  the packed alternative form of the given sample format or
+            AV_SAMPLE_FMT_NONE on error.
+ */
+enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt);
+
+/**
+ * Get the planar alternative form of the given sample format.
+ *
+ * If the passed sample_fmt is already in planar format, the format returned is
+ * the same as the input.
+ *
+ * @return  the planar alternative form of the given sample format or
+            AV_SAMPLE_FMT_NONE on error.
+ */
+enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt);
+
+/**
+ * Generate a string corresponding to the sample format with
+ * sample_fmt, or a header if sample_fmt is negative.
+ *
+ * @param buf the buffer where to write the string
+ * @param buf_size the size of buf
+ * @param sample_fmt the number of the sample format to print the
+ * corresponding info string, or a negative value to print the
+ * corresponding header.
+ * @return the pointer to the filled buffer or NULL if sample_fmt is
+ * unknown or in case of other errors
+ */
+char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt);
+
+#if FF_API_GET_BITS_PER_SAMPLE_FMT
+/**
+ * @deprecated Use av_get_bytes_per_sample() instead.
+ */
+attribute_deprecated
+int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
+#endif
+
+/**
+ * Return number of bytes per sample.
+ *
+ * @param sample_fmt the sample format
+ * @return number of bytes per sample or zero if unknown for the given
+ * sample format
+ */
+int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);
+
+/**
+ * Check if the sample format is planar.
+ *
+ * @param sample_fmt the sample format to inspect
+ * @return 1 if the sample format is planar, 0 if it is interleaved
+ */
+int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt);
+
+/**
+ * Get the required buffer size for the given audio parameters.
+ *
+ * @param[out] linesize calculated linesize, may be NULL
+ * @param nb_channels   the number of channels
+ * @param nb_samples    the number of samples in a single channel
+ * @param sample_fmt    the sample format
+ * @param align         buffer size alignment (0 = default, 1 = no alignment)
+ * @return              required buffer size, or negative error code on failure
+ */
+int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
+                               enum AVSampleFormat sample_fmt, int align);
+
+/**
+ * Fill plane data pointers and linesize for samples with sample
+ * format sample_fmt.
+ *
+ * The audio_data array is filled with the pointers to the samples data planes:
+ * for planar, set the start point of each channel's data within the buffer,
+ * for packed, set the start point of the entire buffer only.
+ *
+ * The value pointed to by linesize is set to the aligned size of each
+ * channel's data buffer for planar layout, or to the aligned size of the
+ * buffer for all channels for packed layout.
+ *
+ * The buffer in buf must be big enough to contain all the samples
+ * (use av_samples_get_buffer_size() to compute its minimum size),
+ * otherwise the audio_data pointers will point to invalid data.
+ *
+ * @see enum AVSampleFormat
+ * The documentation for AVSampleFormat describes the data layout.
+ *
+ * @param[out] audio_data  array to be filled with the pointer for each channel
+ * @param[out] linesize    calculated linesize, may be NULL
+ * @param buf              the pointer to a buffer containing the samples
+ * @param nb_channels      the number of channels
+ * @param nb_samples       the number of samples in a single channel
+ * @param sample_fmt       the sample format
+ * @param align            buffer size alignment (0 = default, 1 = no alignment)
+ * @return                 0 on success or a negative error code on failure
+ */
+int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
+                           const uint8_t *buf,
+                           int nb_channels, int nb_samples,
+                           enum AVSampleFormat sample_fmt, int align);
+
+/**
+ * Allocate a samples buffer for nb_samples samples, and fill data pointers and
+ * linesize accordingly.
+ * The allocated samples buffer can be freed by using av_freep(&audio_data[0])
+ * Allocated data will be initialized to silence.
+ *
+ * @see enum AVSampleFormat
+ * The documentation for AVSampleFormat describes the data layout.
+ *
+ * @param[out] audio_data  array to be filled with the pointer for each channel
+ * @param[out] linesize    aligned size for audio buffer(s), may be NULL
+ * @param nb_channels      number of audio channels
+ * @param nb_samples       number of samples per channel
+ * @param align            buffer size alignment (0 = default, 1 = no alignment)
+ * @return                 0 on success or a negative error code on failure
+ * @see av_samples_fill_arrays()
+ */
+int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
+                     int nb_samples, enum AVSampleFormat sample_fmt, int align);
+
+/**
+ * Copy samples from src to dst.
+ *
+ * @param dst destination array of pointers to data planes
+ * @param src source array of pointers to data planes
+ * @param dst_offset offset in samples at which the data will be written to dst
+ * @param src_offset offset in samples at which the data will be read from src
+ * @param nb_samples number of samples to be copied
+ * @param nb_channels number of audio channels
+ * @param sample_fmt audio sample format
+ */
+int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset,
+                    int src_offset, int nb_samples, int nb_channels,
+                    enum AVSampleFormat sample_fmt);
+
+/**
+ * Fill an audio buffer with silence.
+ *
+ * @param audio_data  array of pointers to data planes
+ * @param offset      offset in samples at which to start filling
+ * @param nb_samples  number of samples to fill
+ * @param nb_channels number of audio channels
+ * @param sample_fmt  audio sample format
+ */
+int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples,
+                           int nb_channels, enum AVSampleFormat sample_fmt);
+
+#endif /* AVUTIL_SAMPLEFMT_H */
diff --git a/extra_lib/include/libavutil/sha.h b/extra_lib/include/libavutil/sha.h
new file mode 100644 (file)
index 0000000..744c66f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_SHA_H
+#define AVUTIL_SHA_H
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "version.h"
+
+/**
+ * @defgroup lavu_sha SHA
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+#if FF_API_CONTEXT_SIZE
+extern attribute_deprecated const int av_sha_size;
+#endif
+
+struct AVSHA;
+
+/**
+ * Allocate an AVSHA context.
+ */
+struct AVSHA *av_sha_alloc(void);
+
+/**
+ * Initialize SHA-1 or SHA-2 hashing.
+ *
+ * @param context pointer to the function context (of size av_sha_size)
+ * @param bits    number of bits in digest (SHA-1 - 160 bits, SHA-2 224 or 256 bits)
+ * @return        zero if initialization succeeded, -1 otherwise
+ */
+int av_sha_init(struct AVSHA* context, int bits);
+
+/**
+ * Update hash value.
+ *
+ * @param context hash function context
+ * @param data    input data to update hash with
+ * @param len     input data length
+ */
+void av_sha_update(struct AVSHA* context, const uint8_t* data, unsigned int len);
+
+/**
+ * Finish hashing and output digest value.
+ *
+ * @param context hash function context
+ * @param digest  buffer where output digest value is stored
+ */
+void av_sha_final(struct AVSHA* context, uint8_t *digest);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_SHA_H */
diff --git a/extra_lib/include/libavutil/time.h b/extra_lib/include/libavutil/time.h
new file mode 100644 (file)
index 0000000..90eb436
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2000-2003 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_TIME_H
+#define AVUTIL_TIME_H
+
+#include <stdint.h>
+
+/**
+ * Get the current time in microseconds.
+ */
+int64_t av_gettime(void);
+
+/**
+ * Sleep for a period of time.  Although the duration is expressed in
+ * microseconds, the actual delay may be rounded to the precision of the
+ * system timer.
+ *
+ * @param  usec Number of microseconds to sleep.
+ * @return zero on success or (negative) error code.
+ */
+int av_usleep(unsigned usec);
+
+#endif /* AVUTIL_TIME_H */
diff --git a/extra_lib/include/libavutil/timecode.h b/extra_lib/include/libavutil/timecode.h
new file mode 100644 (file)
index 0000000..17d6b95
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
+ * Copyright (c) 2011-2012 Smartjog S.A.S, Clément BÅ“sch <clement.boesch@smartjog.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Timecode helpers header
+ */
+
+#ifndef AVUTIL_TIMECODE_H
+#define AVUTIL_TIMECODE_H
+
+#include <stdint.h>
+#include "rational.h"
+
+#define AV_TIMECODE_STR_SIZE 16
+
+enum AVTimecodeFlag {
+    AV_TIMECODE_FLAG_DROPFRAME      = 1<<0, ///< timecode is drop frame
+    AV_TIMECODE_FLAG_24HOURSMAX     = 1<<1, ///< timecode wraps after 24 hours
+    AV_TIMECODE_FLAG_ALLOWNEGATIVE  = 1<<2, ///< negative time values are allowed
+};
+
+typedef struct {
+    int start;          ///< timecode frame start (first base frame number)
+    uint32_t flags;     ///< flags such as drop frame, +24 hours support, ...
+    AVRational rate;    ///< frame rate in rational form
+    unsigned fps;       ///< frame per second; must be consistent with the rate field
+} AVTimecode;
+
+/**
+ * Adjust frame number for NTSC drop frame time code.
+ *
+ * @param framenum frame number to adjust
+ * @return         adjusted frame number
+ * @warning        adjustment is only valid in NTSC 29.97
+ * @deprecated     use av_timecode_adjust_ntsc_framenum2 instead
+ */
+attribute_deprecated int av_timecode_adjust_ntsc_framenum(int framenum);
+
+/**
+ * Adjust frame number for NTSC drop frame time code.
+ *
+ * @param framenum frame number to adjust
+ * @param fps      frame per second, 30 or 60
+ * @return         adjusted frame number
+ * @warning        adjustment is only valid in NTSC 29.97 and 59.94
+ */
+int av_timecode_adjust_ntsc_framenum2(int framenum, int fps);
+
+/**
+ * Convert frame number to SMPTE 12M binary representation.
+ *
+ * @param tc       timecode data correctly initialized
+ * @param framenum frame number
+ * @return         the SMPTE binary representation
+ *
+ * @note Frame number adjustment is automatically done in case of drop timecode,
+ *       you do NOT have to call av_timecode_adjust_ntsc_framenum().
+ * @note The frame number is relative to tc->start.
+ * @note Color frame (CF), binary group flags (BGF) and biphase mark polarity
+ *       correction (PC) bits are set to zero.
+ */
+uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum);
+
+/**
+ * Load timecode string in buf.
+ *
+ * @param buf      destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param tc       timecode data correctly initialized
+ * @param framenum frame number
+ * @return         the buf parameter
+ *
+ * @note Timecode representation can be a negative timecode and have more than
+ *       24 hours, but will only be honored if the flags are correctly set.
+ * @note The frame number is relative to tc->start.
+ */
+char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum);
+
+/**
+ * Get the timecode string from the SMPTE timecode format.
+ *
+ * @param buf        destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param tcsmpte    the 32-bit SMPTE timecode
+ * @param prevent_df prevent the use of a drop flag when it is known the DF bit
+ *                   is arbitrary
+ * @return           the buf parameter
+ */
+char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df);
+
+/**
+ * Get the timecode string from the 25-bit timecode format (MPEG GOP format).
+ *
+ * @param buf     destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param tc25bit the 25-bits timecode
+ * @return        the buf parameter
+ */
+char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit);
+
+/**
+ * Init a timecode struct with the passed parameters.
+ *
+ * @param log_ctx     a pointer to an arbitrary struct of which the first field
+ *                    is a pointer to an AVClass struct (used for av_log)
+ * @param tc          pointer to an allocated AVTimecode
+ * @param rate        frame rate in rational form
+ * @param flags       miscellaneous flags such as drop frame, +24 hours, ...
+ *                    (see AVTimecodeFlag)
+ * @param frame_start the first frame number
+ * @return            0 on success, AVERROR otherwise
+ */
+int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx);
+
+/**
+ * Parse timecode representation (hh:mm:ss[:;.]ff).
+ *
+ * @param log_ctx a pointer to an arbitrary struct of which the first field is a
+ *                pointer to an AVClass struct (used for av_log).
+ * @param tc      pointer to an allocated AVTimecode
+ * @param rate    frame rate in rational form
+ * @param str     timecode string which will determine the frame start
+ * @return        0 on success, AVERROR otherwise
+ */
+int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx);
+
+/**
+ * Check if the timecode feature is available for the given frame rate
+ *
+ * @return 0 if supported, <0 otherwise
+ */
+int av_timecode_check_frame_rate(AVRational rate);
+
+#endif /* AVUTIL_TIMECODE_H */
diff --git a/extra_lib/include/libavutil/timestamp.h b/extra_lib/include/libavutil/timestamp.h
new file mode 100644 (file)
index 0000000..c7348d8
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * timestamp utils, mostly useful for debugging/logging purposes
+ */
+
+#ifndef AVUTIL_TIMESTAMP_H
+#define AVUTIL_TIMESTAMP_H
+
+#include "common.h"
+
+#define AV_TS_MAX_STRING_SIZE 32
+
+/**
+ * Fill the provided buffer with a string containing a timestamp
+ * representation.
+ *
+ * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
+ * @param ts the timestamp to represent
+ * @return the buffer in input
+ */
+static inline char *av_ts_make_string(char *buf, int64_t ts)
+{
+    if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
+    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%"PRId64"", ts);
+    return buf;
+}
+
+/**
+ * Convenience macro, the return value should be used only directly in
+ * function arguments but never stand-alone.
+ */
+#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts)
+
+/**
+ * Fill the provided buffer with a string containing a timestamp time
+ * representation.
+ *
+ * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
+ * @param ts the timestamp to represent
+ * @param tb the timebase of the timestamp
+ * @return the buffer in input
+ */
+static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb)
+{
+    if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
+    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts);
+    return buf;
+}
+
+/**
+ * Convenience macro, the return value should be used only directly in
+ * function arguments but never stand-alone.
+ */
+#define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb)
+
+#endif /* AVUTIL_TIMESTAMP_H */
diff --git a/extra_lib/include/libavutil/version.h b/extra_lib/include/libavutil/version.h
new file mode 100644 (file)
index 0000000..3e9c17f
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * copyright (c) 2003 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_VERSION_H
+#define AVUTIL_VERSION_H
+
+/**
+ * @defgroup preproc_misc Preprocessor String Macros
+ *
+ * String manipulation macros
+ *
+ * @{
+ */
+
+#define AV_STRINGIFY(s)         AV_TOSTRING(s)
+#define AV_TOSTRING(s) #s
+
+#define AV_GLUE(a, b) a ## b
+#define AV_JOIN(a, b) AV_GLUE(a, b)
+
+#define AV_PRAGMA(s) _Pragma(#s)
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup version_utils Library Version Macros
+ *
+ * Useful to check and match library version in order to maintain
+ * backward compatibility.
+ *
+ * @{
+ */
+
+#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c)
+#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c
+#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
+
+/**
+ * @}
+ */
+
+
+/**
+ * @file
+ * @ingroup lavu
+ * Libavutil version macros
+ */
+
+/**
+ * @defgroup lavu_ver Version and Build diagnostics
+ *
+ * Macros and function useful to check at compiletime and at runtime
+ * which version of libavutil is in use.
+ *
+ * @{
+ */
+
+#define LIBAVUTIL_VERSION_MAJOR 51
+#define LIBAVUTIL_VERSION_MINOR 76
+#define LIBAVUTIL_VERSION_MICRO 100
+
+#define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
+                                               LIBAVUTIL_VERSION_MINOR, \
+                                               LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_VERSION       AV_VERSION(LIBAVUTIL_VERSION_MAJOR,     \
+                                           LIBAVUTIL_VERSION_MINOR,     \
+                                           LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_BUILD         LIBAVUTIL_VERSION_INT
+
+#define LIBAVUTIL_IDENT         "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
+
+/**
+ * @}
+ *
+ * @defgroup depr_guards Deprecation guards
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ *
+ * @{
+ */
+
+#ifndef FF_API_OLD_EVAL_NAMES
+#define FF_API_OLD_EVAL_NAMES           (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
+#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_FIND_OPT
+#define FF_API_FIND_OPT                 (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_AV_FIFO_PEEK
+#define FF_API_AV_FIFO_PEEK             (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_OLD_AVOPTIONS
+#define FF_API_OLD_AVOPTIONS            (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_OLD_TC_ADJUST_FRAMENUM
+#define FF_API_OLD_TC_ADJUST_FRAMENUM   (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_PIX_FMT
+#define FF_API_PIX_FMT                  (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_CONTEXT_SIZE
+#define FF_API_CONTEXT_SIZE             (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_PIX_FMT_DESC
+#define FF_API_PIX_FMT_DESC             (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_AV_REVERSE
+#define FF_API_AV_REVERSE               (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_VERSION_H */
+
diff --git a/extra_lib/include/libavutil/xtea.h b/extra_lib/include/libavutil/xtea.h
new file mode 100644 (file)
index 0000000..0899c92
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * A 32-bit implementation of the XTEA algorithm
+ * Copyright (c) 2012 Samuel Pitoiset
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_XTEA_H
+#define AVUTIL_XTEA_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_xtea XTEA
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+typedef struct AVXTEA {
+    uint32_t key[16];
+} AVXTEA;
+
+/**
+ * Initialize an AVXTEA context.
+ *
+ * @param ctx an AVXTEA context
+ * @param key a key of 16 bytes used for encryption/decryption
+ */
+void av_xtea_init(struct AVXTEA *ctx, const uint8_t key[16]);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ *
+ * @param ctx an AVXTEA context
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param count number of 8 byte blocks
+ * @param iv initialization vector for CBC mode, if NULL then ECB will be used
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_xtea_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
+                   int count, uint8_t *iv, int decrypt);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_XTEA_H */
index f5856c381c25fddaf1ed891dc176888daf03fd07..ea2116c1faabf4f71cf4073c6cc025fd248cc693 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
  * This file is part of FFmpeg.
  *
 #define SWSCALE_SWSCALE_H
 
 /**
- * @file libswscale/swscale.h
+ * @file
  * @brief
  *     external api for the swscale stuff
  */
 
-#include "libavutil/avutil.h"
+#include <stdint.h>
 
-#define LIBSWSCALE_VERSION_MAJOR 0
-#define LIBSWSCALE_VERSION_MINOR 7
-#define LIBSWSCALE_VERSION_MICRO 1
+#include "libavutil/avutil.h"
+#include "libavutil/log.h"
+#include "libavutil/pixfmt.h"
+#include "version.h"
 
-#define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
-                                               LIBSWSCALE_VERSION_MINOR, \
-                                               LIBSWSCALE_VERSION_MICRO)
-#define LIBSWSCALE_VERSION      AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \
-                                           LIBSWSCALE_VERSION_MINOR, \
-                                           LIBSWSCALE_VERSION_MICRO)
-#define LIBSWSCALE_BUILD        LIBSWSCALE_VERSION_INT
+/**
+ * Return the LIBSWSCALE_VERSION_INT constant.
+ */
+unsigned swscale_version(void);
 
-#define LIBSWSCALE_IDENT        "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION)
+/**
+ * Return the libswscale build-time configuration.
+ */
+const char *swscale_configuration(void);
 
 /**
- * Returns the LIBSWSCALE_VERSION_INT constant.
+ * Return the libswscale license.
  */
-unsigned swscale_version(void);
+const char *swscale_license(void);
 
 /* values for the flags, the stuff on the command line is different */
 #define SWS_FAST_BILINEAR     1
@@ -77,11 +78,21 @@ unsigned swscale_version(void);
 #define SWS_ACCURATE_RND      0x40000
 #define SWS_BITEXACT          0x80000
 
+#if FF_API_SWS_CPU_CAPS
+/**
+ * CPU caps are autodetected now, those flags
+ * are only provided for API compatibility.
+ */
 #define SWS_CPU_CAPS_MMX      0x80000000
+#define SWS_CPU_CAPS_MMXEXT   0x20000000
+#if LIBSWSCALE_VERSION_MAJOR < 3
 #define SWS_CPU_CAPS_MMX2     0x20000000
+#endif
 #define SWS_CPU_CAPS_3DNOW    0x40000000
 #define SWS_CPU_CAPS_ALTIVEC  0x10000000
 #define SWS_CPU_CAPS_BFIN     0x01000000
+#define SWS_CPU_CAPS_SSE2     0x02000000
+#endif
 
 #define SWS_MAX_REDUCE_CUTOFF 0.002
 
@@ -93,17 +104,24 @@ unsigned swscale_version(void);
 #define SWS_CS_SMPTE240M      7
 #define SWS_CS_DEFAULT        5
 
-
+/**
+ * Return a pointer to yuv<->rgb coefficients for the given colorspace
+ * suitable for sws_setColorspaceDetails().
+ *
+ * @param colorspace One of the SWS_CS_* macros. If invalid,
+ * SWS_CS_DEFAULT is used.
+ */
+const int *sws_getCoefficients(int colorspace);
 
 // when used for filters they must have an odd number of elements
 // coeffs cannot be shared between vectors
-typedef struct {
+typedef struct SwsVector {
     double *coeff;              ///< pointer to the list of coefficients
     int length;                 ///< number of coefficients in the vector
 } SwsVector;
 
 // vectors can be shared
-typedef struct {
+typedef struct SwsFilter {
     SwsVector *lumH;
     SwsVector *lumV;
     SwsVector *chrH;
@@ -112,10 +130,42 @@ typedef struct {
 
 struct SwsContext;
 
+/**
+ * Return a positive value if pix_fmt is a supported input format, 0
+ * otherwise.
+ */
+int sws_isSupportedInput(enum AVPixelFormat pix_fmt);
+
+/**
+ * Return a positive value if pix_fmt is a supported output format, 0
+ * otherwise.
+ */
+int sws_isSupportedOutput(enum AVPixelFormat pix_fmt);
+
+/**
+ * Allocate an empty SwsContext. This must be filled and passed to
+ * sws_init_context(). For filling see AVOptions, options.c and
+ * sws_setColorspaceDetails().
+ */
+struct SwsContext *sws_alloc_context(void);
+
+/**
+ * Initialize the swscaler context sws_context.
+ *
+ * @return zero or positive value on success, a negative value on
+ * error
+ */
+int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter);
+
+/**
+ * Free the swscaler context swsContext.
+ * If swsContext is NULL, then does nothing.
+ */
 void sws_freeContext(struct SwsContext *swsContext);
 
+#if FF_API_SWS_GETCONTEXT
 /**
- * Allocates and returns a SwsContext. You need it to perform
+ * Allocate and return an SwsContext. You need it to perform
  * scaling/conversion operations using sws_scale().
  *
  * @param srcW the width of the source image
@@ -126,18 +176,26 @@ void sws_freeContext(struct SwsContext *swsContext);
  * @param dstFormat the destination image format
  * @param flags specify which algorithm and options to use for rescaling
  * @return a pointer to an allocated context, or NULL in case of error
+ * @note this function is to be removed after a saner alternative is
+ *       written
+ * @deprecated Use sws_getCachedContext() instead.
  */
-struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
-                                  int dstW, int dstH, enum PixelFormat dstFormat,
+struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
+                                  int dstW, int dstH, enum AVPixelFormat dstFormat,
                                   int flags, SwsFilter *srcFilter,
                                   SwsFilter *dstFilter, const double *param);
+#endif
 
 /**
- * Scales the image slice in \p srcSlice and puts the resulting scaled
- * slice in the image in \p dst. A slice is a sequence of consecutive
+ * Scale the image slice in srcSlice and put the resulting scaled
+ * slice in the image in dst. A slice is a sequence of consecutive
  * rows in an image.
  *
- * @param context   the scaling context previously created with
+ * Slices have to be provided in sequential order, either in
+ * top-bottom or bottom-top order. If slices are provided in
+ * non-sequential order the behavior of the function is undefined.
+ *
+ * @param c         the scaling context previously created with
  *                  sws_getContext()
  * @param srcSlice  the array containing the pointers to the planes of
  *                  the source slice
@@ -154,20 +212,18 @@ struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat
  *                  the destination image
  * @return          the height of the output slice
  */
-int sws_scale(struct SwsContext *context, uint8_t* srcSlice[], int srcStride[],
-              int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]);
-#if LIBSWSCALE_VERSION_MAJOR < 1
-/**
- * @deprecated Use sws_scale() instead.
- */
-int sws_scale_ordered(struct SwsContext *context, uint8_t* src[],
-                      int srcStride[], int srcSliceY, int srcSliceH,
-                      uint8_t* dst[], int dstStride[]) attribute_deprecated;
-#endif
+int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
+              const int srcStride[], int srcSliceY, int srcSliceH,
+              uint8_t *const dst[], const int dstStride[]);
 
 /**
- * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x]
- * @param fullRange if 1 then the luma range is 0..255 if 0 it is 16..235
+ * @param dstRange flag indicating the while-black range of the output (1=jpeg / 0=mpeg)
+ * @param srcRange flag indicating the while-black range of the input (1=jpeg / 0=mpeg)
+ * @param table the yuv2rgb coefficients describing the output yuv space, normally ff_yuv2rgb_coeffs[x]
+ * @param inv_table the yuv2rgb coefficients describing the input yuv space, normally ff_yuv2rgb_coeffs[x]
+ * @param brightness 16.16 fixed point brightness correction
+ * @param contrast 16.16 fixed point contrast correction
+ * @param saturation 16.16 fixed point saturation correction
  * @return -1 if not supported
  */
 int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
@@ -182,31 +238,35 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
                              int *brightness, int *contrast, int *saturation);
 
 /**
- * Returns a normalized Gaussian curve used to filter stuff
- * quality=3 is high quality, lower is lower quality.
+ * Allocate and return an uninitialized vector with length coefficients.
+ */
+SwsVector *sws_allocVec(int length);
+
+/**
+ * Return a normalized Gaussian curve used to filter stuff
+ * quality = 3 is high quality, lower is lower quality.
  */
 SwsVector *sws_getGaussianVec(double variance, double quality);
 
 /**
- * Allocates and returns a vector with \p length coefficients, all
- * with the same value \p c.
+ * Allocate and return a vector with length coefficients, all
+ * with the same value c.
  */
 SwsVector *sws_getConstVec(double c, int length);
 
 /**
- * Allocates and returns a vector with just one coefficient, with
+ * Allocate and return a vector with just one coefficient, with
  * value 1.0.
  */
 SwsVector *sws_getIdentityVec(void);
 
 /**
- * Scales all the coefficients of \p a by the \p scalar value.
+ * Scale all the coefficients of a by the scalar value.
  */
 void sws_scaleVec(SwsVector *a, double scalar);
 
 /**
- * Scales all the coefficients of \p a so that their sum equals \p
- * height."
+ * Scale all the coefficients of a so that their sum equals height.
  */
 void sws_normalizeVec(SwsVector *a, double height);
 void sws_convVec(SwsVector *a, SwsVector *b);
@@ -215,21 +275,14 @@ void sws_subVec(SwsVector *a, SwsVector *b);
 void sws_shiftVec(SwsVector *a, int shift);
 
 /**
- * Allocates and returns a clone of the vector \p a, that is a vector
- * with the same coefficients as \p a.
+ * Allocate and return a clone of the vector a, that is a vector
+ * with the same coefficients as a.
  */
 SwsVector *sws_cloneVec(SwsVector *a);
 
-#if LIBSWSCALE_VERSION_MAJOR < 1
-/**
- * @deprecated Use sws_printVec2() instead.
- */
-attribute_deprecated void sws_printVec(SwsVector *a);
-#endif
-
 /**
- * Prints with av_log() a textual representation of the vector \p a
- * if \p log_level <= av_log_level.
+ * Print with av_log() a textual representation of the vector a
+ * if log_level <= av_log_level.
  */
 void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level);
 
@@ -242,22 +295,53 @@ SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
 void sws_freeFilter(SwsFilter *filter);
 
 /**
- * Checks if \p context can be reused, otherwise reallocates a new
- * one.
+ * Check if context can be reused, otherwise reallocate a new one.
  *
- * If \p context is NULL, just calls sws_getContext() to get a new
+ * If context is NULL, just calls sws_getContext() to get a new
  * context. Otherwise, checks if the parameters are the ones already
- * saved in \p context. If that is the case, returns the current
- * context. Otherwise, frees \p context and gets a new context with
+ * saved in context. If that is the case, returns the current
+ * context. Otherwise, frees context and gets a new context with
  * the new parameters.
  *
- * Be warned that \p srcFilter and \p dstFilter are not checked, they
+ * Be warned that srcFilter and dstFilter are not checked, they
  * are assumed to remain the same.
  */
 struct SwsContext *sws_getCachedContext(struct SwsContext *context,
-                                        int srcW, int srcH, enum PixelFormat srcFormat,
-                                        int dstW, int dstH, enum PixelFormat dstFormat,
+                                        int srcW, int srcH, enum AVPixelFormat srcFormat,
+                                        int dstW, int dstH, enum AVPixelFormat dstFormat,
                                         int flags, SwsFilter *srcFilter,
                                         SwsFilter *dstFilter, const double *param);
 
+/**
+ * Convert an 8-bit paletted frame into a frame with a color depth of 32 bits.
+ *
+ * The output frame will have the same packed format as the palette.
+ *
+ * @param src        source frame buffer
+ * @param dst        destination frame buffer
+ * @param num_pixels number of pixels to convert
+ * @param palette    array with [256] entries, which must match color arrangement (RGB or BGR) of src
+ */
+void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette);
+
+/**
+ * Convert an 8-bit paletted frame into a frame with a color depth of 24 bits.
+ *
+ * With the palette format "ABCD", the destination frame ends up with the format "ABC".
+ *
+ * @param src        source frame buffer
+ * @param dst        destination frame buffer
+ * @param num_pixels number of pixels to convert
+ * @param palette    array with [256] entries, which must match color arrangement (RGB or BGR) of src
+ */
+void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette);
+
+/**
+ * Get the AVClass for swsContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *sws_get_class(void);
+
 #endif /* SWSCALE_SWSCALE_H */
diff --git a/extra_lib/include/libswscale/version.h b/extra_lib/include/libswscale/version.h
new file mode 100644 (file)
index 0000000..37dcc96
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SWSCALE_VERSION_H
+#define SWSCALE_VERSION_H
+
+/**
+ * @file
+ * swscale version macros
+ */
+
+#include "libavutil/avutil.h"
+
+#define LIBSWSCALE_VERSION_MAJOR 2
+#define LIBSWSCALE_VERSION_MINOR 1
+#define LIBSWSCALE_VERSION_MICRO 101
+
+#define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
+                                               LIBSWSCALE_VERSION_MINOR, \
+                                               LIBSWSCALE_VERSION_MICRO)
+#define LIBSWSCALE_VERSION      AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \
+                                           LIBSWSCALE_VERSION_MINOR, \
+                                           LIBSWSCALE_VERSION_MICRO)
+#define LIBSWSCALE_BUILD        LIBSWSCALE_VERSION_INT
+
+#define LIBSWSCALE_IDENT        "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION)
+
+/**
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ */
+
+#ifndef FF_API_SWS_GETCONTEXT
+#define FF_API_SWS_GETCONTEXT  (LIBSWSCALE_VERSION_MAJOR < 3)
+#endif
+#ifndef FF_API_SWS_CPU_CAPS
+#define FF_API_SWS_CPU_CAPS    (LIBSWSCALE_VERSION_MAJOR < 3)
+#endif
+#ifndef FF_API_SWS_FORMAT_NAME
+#define FF_API_SWS_FORMAT_NAME  (LIBSWSCALE_VERSION_MAJOR < 3)
+#endif
+
+#endif /* SWSCALE_VERSION_H */
index 034b3ec4bf6e829bce0b7984e23457bee9e04634..933c12cc23ecc977dc300d266d157671d943071e 100644 (file)
@@ -48,7 +48,7 @@ class NPT_Stack : public NPT_List<T>
 public:
     // methods
     NPT_Result Push(const T& value) {
-        return Add(value);
+        return this->Add(value);
     }
 
     NPT_Result Peek(T& value) {
index dfc5f3e3a2e021737208ccfb44ebdcde64996a69..8493fbd70da9fdc2ffb24a22c88119118dcca2c7 100644 (file)
@@ -21,17 +21,17 @@ echo:
 REM ============================================\r
 echo Retrieving version/revision information\r
 REM ============================================\r
-if not exist include/gpac/version.h echo   version couldn't be found - check include/gpac/version.h exists\r
-if not exist include/gpac/version.h goto Abort\r
+if not exist include/gpac/revision.h echo   version couldn't be found - check include/gpac/revision.h exists\r
+if not exist include/gpac/revision.h goto Abort\r
 \r
-REM execute svnversion and check if the result if found within version.h\r
+REM execute svnversion and check if the result if found within revision.h\r
 for /f "delims=" %%i in ('svnversion.exe') do Set VarRevisionSVN=%%i\r
 REM 'M', 'S', 'P', ':' are special 'svnversion' results\r
 for /f "delims=" %%i in ('echo %VarRevisionSVN% ^| findstr /i /r M^"') do goto RevisionAbort\r
 for /f "delims=" %%i in ('echo %VarRevisionSVN% ^| findstr /i /r S^"') do goto RevisionAbort\r
 for /f "delims=" %%i in ('echo %VarRevisionSVN% ^| findstr /i /r P^"') do goto RevisionAbort\r
 for /f "delims=" %%i in ('echo %VarRevisionSVN% ^| findstr /i /r :^"') do goto RevisionAbort\r
-for /f "delims=" %%i in ('type include\gpac\version.h ^| findstr /i /r "%VarRevisionSVN%"') do Set VarRevisionBuild=%%i\r
+for /f "delims=" %%i in ('type include\gpac\revision.h ^| findstr /i /r "%VarRevisionSVN%"') do Set VarRevisionBuild=%%i\r
 echo VarRevisionBuild = %VarRevisionBuild%\r
 echo VarRevisionSVN   = %VarRevisionSVN%\r
 if !"%VarRevisionBuild%"==!"%VarRevisionSVN%" echo   local revision and last build revision are not congruent - please consider rebuilding before generating an installer\r
index eeb1afa033d2ed7cc01f66cffdbc40766ae08261..3bd79e6edb003464c040069566368c694cb8294f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Authoring Tools sub-project
index ee02e9c381fb39d22bf269c85d27c4d76fa31932..7db5141127b3acf802b50dc475f07c85f614265a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 94fc4c0c388257d24d2dc7b624ff83aed2094d37..7f2b7cbc218ad80c1253c290cadc7080e1c6341a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 5186288bc6de4923fb4d0264b9d22518d68026af..69fd493be69fd6a1e5e48d909751b8f18fd6c0a2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -88,6 +89,26 @@ GF_BitStream *gf_bs_from_file(FILE *f, u32 mode);
  */
 void gf_bs_del(GF_BitStream *bs);
 
+/*!
+ *     \brief sets bitstream write cache size
+ *
+ * Sets the write cache size for file-based bitstreams.  
+ *     \param bs the target bitstream 
+ *     \param size size of the write cache in bytes
+ *     \return error if any.
+ */
+GF_Err gf_bs_set_output_buffering(GF_BitStream *bs, u32 size);
+
+
+/*!
+ *     \brief gets bitstream write cache size
+ *
+ * Gets the write cache size for file-based bitstreams.  
+ *     \param bs the target bitstream 
+ *     \return size of the write cache in bytes, 0 if no cache
+ */
+u32 gf_bs_get_output_buffering(GF_BitStream *bs);
+
 /*!
  *     \brief integer reading
  *
index e2b8cca1d1d8feddd07f4dabcc6e56843eb3576d..cf85b0269cea8b7ae1dbe1c4cd94c0e67454cb66 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                      GPAC - Multimedia Framework C SDK
  *
- *                      Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre, Pierre Souchay 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                      All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 5197062cd777d74d312eaecd353d52db21eaf381..13c8be93a30632687c73b334b523d1b31d3595bb 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools interfaces
index ea55d1f7a92bd8b90d8b883e715c18b1fb6e2000..e0ba6803f148f3bd4718e167265079c678cd2ba2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -159,6 +160,9 @@ Bool gf_sc_script_action(GF_Compositor *sr, u32 type, GF_Node *n, GF_JSAPIParam
 
 void gf_sc_reload_audio_filters(GF_Compositor *compositor);
 
+Bool gf_sc_uri_is_hardcoded_proto(GF_Compositor *compositor, const char *uri);
+
+
 #ifdef __cplusplus
 }
 #endif
index e1384a2f788193d614356bced42b3ba318c544b5..02415ea8fc6d87a7656bb27c4e3fc6cab2e2c8f0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index c4f6eb10309a183e298d7192554925e15120b5f0..320d5520aa51f1037c6caf6af3b3475727311943 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2008 - 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2008-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC 
index 601fe9351b98c25755dd3feb885aa1c8266e751c..eab19e1656206f1d8f6a788ecf72dc64b8b933b0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / exported constants
@@ -543,7 +544,8 @@ enum
 #define GF_AVC_NALU_SVC_SUBSEQ_PARAM   15
 #define GF_AVC_NALU_SLICE_AUX                  19
 
-#define GF_AVC_NALU_SVC_SLICE 0x14
+#define GF_AVC_NALU_SVC_SLICE 20       //0x14
+
 
 /*#define GF_SVC_NALU_SLICE 0x14
 #define GF_SVC_NALU_NAL_EXT_PARAM 14
index 6518c83d4125714610f708f6e479a62eb4be27c4..54ba9b21f6d2736c93bfd8abbb1f0fb1912a2ef2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Crypto Tools sub-project
diff --git a/include/gpac/dash.h b/include/gpac/dash.h
new file mode 100644 (file)
index 0000000..2f865cf
--- /dev/null
@@ -0,0 +1,228 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Jean Le Feuvre \r
+ *                     Copyright (c) Telecom ParisTech 2012\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / Adaptive HTTP Streaming sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GF_DASH_H_\r
+#define _GF_DASH_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include <gpac/tools.h>\r
+\r
+#ifndef GPAC_DISABLE_DASH_CLIENT\r
+\r
+/*!\r
+ * All the possible Mime-types for MPD files\r
+ */\r
+static const char * GF_DASH_MPD_MIME_TYPES[] = { "application/dash+xml", "video/vnd.3gpp.mpd", "audio/vnd.3gpp.mpd", NULL };\r
+\r
+/*!\r
+ * All the possible Mime-types for M3U8 files\r
+ */\r
+static const char * GF_DASH_M3U8_MIME_TYPES[] = { "video/x-mpegurl", "audio/x-mpegurl", "application/x-mpegurl", "application/vnd.apple.mpegurl", NULL};\r
+\r
+typedef enum \r
+{\r
+       /*event sent if an error occurs when setting up manifest*/\r
+       GF_DASH_EVENT_MANIFEST_INIT_ERROR,\r
+       /*event sent before groups first segment is fetched - user shall decide which group to select at this point*/\r
+       GF_DASH_EVENT_SELECT_GROUPS,\r
+       /*event sent if an error occurs during period setup - the download thread will exit at this point*/\r
+       GF_DASH_EVENT_PERIOD_SETUP_ERROR,\r
+       /*event sent once the first segment of each selected group is fetched - user should load playback chain(s) at this point*/\r
+       GF_DASH_EVENT_CREATE_PLAYBACK,\r
+       /*event sent when reseting groups at period switch or at exit - user should unload playback chain(s) at this point*/\r
+       GF_DASH_EVENT_DESTROY_PLAYBACK,\r
+} GF_DASHEventType;\r
+\r
+/*structure used for all IO operations for DASH*/\r
+typedef struct _gf_dash_io GF_DASHFileIO;\r
+typedef void *GF_DASHFileIOSession;\r
+\r
+struct _gf_dash_io\r
+{\r
+       /*user private data*/\r
+       void *udta;\r
+       \r
+       /*signals errors or specific actions to perform*/\r
+       GF_Err (*on_dash_event)(GF_DASHFileIO *dashio, GF_DASHEventType evt, GF_Err setup_error);\r
+\r
+       /*called whenever a file has to be deleted*/\r
+       void (*delete_cache_file)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session, const char *cache_url);\r
+\r
+       /*create a file download session for the given resource*/\r
+       GF_DASHFileIOSession (*create)(GF_DASHFileIO *dashio, Bool persistent, const char *url);\r
+       /*delete a file download session*/\r
+       void (*del)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*aborts downloading in the given file session*/\r
+       void (*abort)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*resetup the file session with a new resource to get - this allows persistent connection usage with HTTP servers*/\r
+       GF_Err (*setup_from_url)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session, const char *url);\r
+       /*set download range for the file session*/\r
+       GF_Err (*set_range)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session, u64 start_range, u64 end_range);\r
+       /*initialize the file session - all the headers shall be fetched before returning*/\r
+       GF_Err (*init)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*download the content - synchronous call: all the file shall be fetched before returning*/\r
+       GF_Err (*run)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+\r
+       /*get URL of the file - i tmay be different from the original one if resource relocation happened*/\r
+       const char *(*get_url)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*get the name of the cache file. If NULL is returned, the file cannot be cached and its associated UTL will be used when \r
+       the client request file to play*/\r
+       const char *(*get_cache_name)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*get the MIME type of the file*/\r
+       const char *(*get_mime)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*get the average download rate for the session*/\r
+       u32 (*get_bytes_per_sec)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+       /*get the totla size on bytes for the session*/\r
+       u32 (*get_total_size)(GF_DASHFileIO *dashio, GF_DASHFileIOSession session);\r
+};\r
+\r
+typedef struct __dash_client GF_DashClient;\r
+\r
+typedef enum\r
+{\r
+       GF_DASH_SELECT_QUALITY_LOWEST,\r
+       GF_DASH_SELECT_QUALITY_HIGHEST,\r
+       GF_DASH_SELECT_BANDWIDTH_LOWEST,\r
+       GF_DASH_SELECT_BANDWIDTH_HIGHEST\r
+} GF_DASHInitialSelectionMode;\r
+\r
+/*create a new DASH client:\r
+       @dash_io: DASH callbacks to the user\r
+       @max_cache_duration_sec: maximum duration in seconds for the cached media\r
+       @auto_switch_count: forces representation switching every auto_switch_count segments\r
+       @keep_files: do not delete files from the cache\r
+       @disable_switching: turn off bandwidth switching algorithm\r
+       @first_select_mode: indicates which representation to select upon startup\r
+*/\r
+GF_DashClient *gf_dash_new(GF_DASHFileIO *dash_io, \r
+                                                  u32 max_cache_duration_sec, \r
+                                                  u32 auto_switch_count, \r
+                                                  Bool keep_files, \r
+                                                  Bool disable_switching, \r
+                                                  GF_DASHInitialSelectionMode first_select_mode);\r
+\r
+/*delete the DASH client*/\r
+void gf_dash_del(GF_DashClient *dash);\r
+\r
+/*open the DASH client for the specific manifest file*/\r
+GF_Err gf_dash_open(GF_DashClient *dash, const char *manifest_url);\r
+/*closes the dash client*/\r
+void gf_dash_close(GF_DashClient *dash);\r
+\r
+/*returns URL of the DASH manifest file*/\r
+const char *gf_dash_get_url(GF_DashClient *dash);\r
+\r
+/*get title and source for this MPD*/\r
+void gf_dash_get_info(GF_DashClient *dash, const char **title, const char **source);\r
+\r
+/*switches quality up or down*/\r
+void gf_dash_switch_quality(GF_DashClient *dash, Bool switch_up);\r
+\r
+/*indicates whether the DASH client is running or not. For the moment, the DASH client is always run by an internal thread*/\r
+Bool gf_dash_is_running(GF_DashClient *dash);\r
+\r
+/*get duration of the presentation*/\r
+Double gf_dash_get_duration(GF_DashClient *dash);\r
+/*check that the given file has the right XML root element*/\r
+Bool gf_dash_check_mpd_root_type(const char *local_url);\r
+\r
+\r
+/*returns the number of groups. A group is a set of media resources that are alternate of each other in terms of bandwidth/quality.*/\r
+u32 gf_dash_get_group_count(GF_DashClient *dash);\r
+/*associate user data (or NULL) with this group*/\r
+GF_Err gf_dash_set_group_udta(GF_DashClient *dash, u32 group_index, void *udta);\r
+/*returns the user data associated with this group*/\r
+void *gf_dash_get_group_udta(GF_DashClient *dash, u32 group_index);\r
+/*indicates whether a group is selected for playback or not. Currently groups cannot be selected during playback*/\r
+Bool gf_dash_is_group_selected(GF_DashClient *dash, u32 group_index);\r
+\r
+/*selects a group for playback. If other groups are alternate to this group (through the @group attribute), they are automatically deselected. */\r
+void gf_dash_group_select(GF_DashClient *dash, u32 idx, Bool select);\r
+\r
+/*performs selection of representations based on language code*/\r
+void gf_dash_groups_set_language(GF_DashClient *dash, const char *lang_3cc);\r
+\r
+/*returns the mime type of the media resources in this group*/\r
+const char *gf_dash_group_get_segment_mime(GF_DashClient *dash, u32 idx);\r
+/*returns the URL of tyhe first media resource to play (init segment or first media segment depending on format). start_range and end_range are optional*/\r
+const char *gf_dash_group_get_segment_init_url(GF_DashClient *dash, u32 idx, u64 *start_range, u64 *end_range);\r
+\r
+/*returns the URL and byte range of the next media resource to play in this group. \r
+If switching occured and no bitstream switching is possible, also set the url and byte range of the media file required to intialize the playback\r
+original_url is optional and may be used to het the URI of the segment\r
+*/\r
+GF_Err gf_dash_group_get_next_segment_location(GF_DashClient *dash, u32 idx, const char **url, u64 *start_range, u64 *end_range, \r
+                                                                                       const char **switching_url, u64 *switching_start_range, u64 *switching_end_range, \r
+                                                                                       const char **original_url);\r
+/*discards the first media resource in the queue of this group*/\r
+void gf_dash_group_discard_segment(GF_DashClient *dash, u32 idx);\r
+/*get the number of media resources available in the cache for this group*/\r
+u32 gf_dash_group_get_num_segments_ready(GF_DashClient *dash, u32 idx, Bool *group_is_done);\r
+/*get the maximum number of media resources  that can be put in the cache for this group*/\r
+u32 gf_dash_group_get_max_segments_in_cache(GF_DashClient *dash, u32 idx);\r
+/*indicates to the DASH engine that the group playback has been stopped by the user*/\r
+void gf_dash_set_group_done(GF_DashClient *dash, u32 idx, Bool done);\r
+/*gets presentationTimeOffset and timescale for the active representation*/\r
+GF_Err gf_dash_group_get_presentation_time_offset(GF_DashClient *dash, u32 idx, u64 *presentation_time_offset, u32 *timescale);\r
+\r
+/*returns 1 if the playback position is in the last period of the presentation*/\r
+Bool gf_dash_in_last_period(GF_DashClient *dash);\r
+/*return value: \r
+       1 if the period switching has been requested (due to seeking), \r
+       2 if the switching is in progress (all groups will soon be destroyed and plyback will be stoped and restarted)\r
+       0 if no switching is requested\r
+*/\r
+u32 gf_dash_get_period_switch_status(GF_DashClient *dash);\r
+/*request period switch - this is typically called when the media engine signals that no more data is available for playback*/\r
+void gf_dash_request_period_switch(GF_DashClient *dash);\r
+/*returns 1 if the DASH engine is currently setting up a period (creating groups and fetching initial segments)*/\r
+Bool gf_dash_in_period_setup(GF_DashClient *dash);\r
+/*seeks playback to the given time. If period changes, all playback is stopped and restarted*/\r
+void gf_dash_seek(GF_DashClient *dash, Double start_range);\r
+/*gets playback start range for the first segment to play after the seek has been done. This is the amount of data to skip from the first segment to be played*/\r
+Double gf_dash_get_playback_start_range(GF_DashClient *dash);\r
+/*when seeking, this flag is set when the seek is outside of the previously playing segment.*/\r
+Bool gf_dash_group_segment_switch_forced(GF_DashClient *dash, u32 idx);\r
+\r
+/*returns the start_time of the first segment in the queue (usually the one being played)*/\r
+Double gf_dash_group_current_segment_start_time(GF_DashClient *dash, u32 idx);\r
+\r
+/*allow reloading of MPD on the local file system - usefull for testing live generators*/\r
+void gf_dash_allow_local_mpd_update(GF_DashClient *dash, Bool allow_local_mpd_update);\r
+\r
+\r
+#endif //GPAC_DISABLE_DASH_CLIENT\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*_GF_DASH_H_*/\r
+\r
index 5d5380f14362bc462411dd3b3b3b5a9c85f1a4bf..a28f9d21e8d1ca051ea560f91add73d11a4c6cfd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -47,7 +48,7 @@ extern "C" {
 #endif
 
 #include <gpac/tools.h>
-#include <gpac/module.h>
+#include <gpac/config_file.h>
 #include <gpac/cache.h>
 
 
@@ -413,7 +414,7 @@ extern "C" {
      * \return GF_OK if everything went fine, an error otherwise
      */
     GF_Err gf_dm_wget_with_cache(GF_DownloadManager * dm,
-                                const char *url, const char *filename);
+                                const char *url, const char *filename, u64 start_range, u64 end_range);
 
     /*!
      * \brief Same as gf_dm_wget_with_cache, but initializes the GF_DownloadManager by itself.
@@ -422,7 +423,7 @@ extern "C" {
      * \param filename The filename to download
      * \return GF_OK if everything went fine, an error otherwise
      */
-    GF_Err gf_dm_wget(const char *url, const char *filename);
+    GF_Err gf_dm_wget(const char *url, const char *filename, u64 start_range, u64 end_range);
 
     /*!
      *\brief Reset session
index 38127612178da78a0942e6489c592c402d665c2e..ae43750e0bfac98e4b48f963d0912f46c30199bc 100644 (file)
@@ -1,9 +1,29 @@
-/* \r
- * Copyright (c) TELECOM ParisTech 2011\r
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Jonathan Sillan\r
+ *                     Copyright (c) Telecom ParisTech 2011-2012\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / common tools sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *\r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ *\r
  */\r
 \r
 \r
-\r
 #ifndef _GF_DSMCC_H_\r
 #define _GF_DSMCC_H_\r
 \r
index f96664eed5ce1252171d3780c3fda2f0f7d64078..215183694cd894653950bf25fa861fb1eedc570a 100644 (file)
@@ -1,12 +1,13 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Walid B.H - Jean Le Feuvre
- *    Copyright (c)2006-200X ENST - All rights reserved
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2006-2012
+ *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG2-TS sub-project
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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 gf_free Software Foundation; either version 2, or (at your option)
  *  any later version.
index e2f8e774c62fed30661af61a84b98bacf2021eae..bb110d3042c5ff0aed3ca1b5f9e84cfb3648bb72 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Elementary Stream Interface sub-project
index 2fbe8edb4cf560f17f2fabacdbc445d3a463f5f7..ef586009a5302abf56bccf054c4172dab244fd7b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Events management
index f1693fdc27e10180fc9493c3859dc3a321653903..56b35493c708ea696f196767fba3709803720085 100644 (file)
-/*
- *                     GPAC - Multimedia Framework C SDK
- *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
- *                     Copyright (c) Telecom-Paristech 2005-20xx
- *                                     All rights reserved
- *
- *  This file is part of GPAC / Events management
- *
- *  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_EVENTS_CONSTANTS_H_
-#define _GF_EVENTS_CONSTANTS_H_
-
-
-
-/*
-               minimal event system
-
-       DO NOT CHANGE THEIR POSITION IN THE LIST, USED TO SPEED UP FILTERING OF USER INPUT EVENTS
-*/
-
-/*events*/
-enum {
-
-       /******************************************************
-
-               Events used for both GPAC internals and DOM Events
-
-       *******************************************************/
-       /*MouseEvents*/
-       GF_EVENT_CLICK,
-       GF_EVENT_MOUSEUP,
-       GF_EVENT_MOUSEDOWN,
-       GF_EVENT_MOUSEOVER,
-       GF_EVENT_MOUSEOUT,
-       /*!! ALL MOUSE EVENTS SHALL BE DECLARED BEFORE MOUSEMOVE !! */
-       GF_EVENT_MOUSEMOVE,
-       /*mouse wheel event*/
-       GF_EVENT_MOUSEWHEEL,
-
-       /*Key Events*/
-       GF_EVENT_KEYUP,
-       GF_EVENT_KEYDOWN, /* covers KeyDown, KeyPress and AccessKey */
-       GF_EVENT_LONGKEYPRESS,
-       /*character input*/
-       GF_EVENT_TEXTINPUT,
-
-
-       /******************************************************
-
-               Events used for DOM Events only
-
-       *******************************************************/
-       GF_EVENT_TEXTSELECT,
-
-       /*DOM UIEvents*/
-       GF_EVENT_FOCUSIN,
-       GF_EVENT_FOCUSOUT,
-       GF_EVENT_ACTIVATE,
-       GF_EVENT_CHANGE,
-       GF_EVENT_FOCUS,
-       GF_EVENT_BLUR,
-       /*SVG (HTML) Events*/
-       GF_EVENT_LOAD,
-       GF_EVENT_UNLOAD,
-       GF_EVENT_ABORT,
-       GF_EVENT_ERROR,
-       GF_EVENT_RESIZE,
-       GF_EVENT_SCROLL,
-       GF_EVENT_ZOOM,
-       GF_EVENT_BEGIN, /*this is a fake event, it is NEVER fired, only used in SMIL begin*/
-       GF_EVENT_BEGIN_EVENT,
-       GF_EVENT_END, /*this is a fake event, it is NEVER fired, only used in SMIL end*/
-       GF_EVENT_END_EVENT,
-       GF_EVENT_REPEAT, /*this is a fake event, it is NEVER fired, only used in SMIL repeat*/
-       GF_EVENT_REPEAT_EVENT,
-
-       /*DOM MutationEvents - NOT SUPPORTED YET*/
-       GF_EVENT_TREE_MODIFIED,
-       GF_EVENT_NODE_INSERTED,
-       GF_EVENT_NODE_REMOVED,
-       GF_EVENT_NODE_INSERTED_DOC,
-       GF_EVENT_NODE_REMOVED_DOC,
-       GF_EVENT_ATTR_MODIFIED,
-       GF_EVENT_CHAR_DATA_MODIFIED,
-       GF_EVENT_NODE_NAME_CHANGED,
-       GF_EVENT_ATTR_NAME_CHANGED,
-
-       GF_EVENT_DCCI_PROP_CHANGE,
-
-       /*LASeR events*/
-       GF_EVENT_ACTIVATED,
-       GF_EVENT_DEACTIVATED,
-       GF_EVENT_PAUSE,
-       GF_EVENT_PAUSED_EVENT,
-       GF_EVENT_PLAY,
-       GF_EVENT_REPEAT_KEY,
-       GF_EVENT_RESUME_EVENT,
-       GF_EVENT_SHORT_ACCESSKEY,
-       /*pseudo-event, only used in LASeR coding*/
-       GF_EVENT_EXECUTION_TIME,
-
-       /*MediaAccess events - cf http://www.w3.org/TR/MediaAccessEvents*/
-#if 0
-       GF_EVENT_MEDIA_BEGIN_SESSION_SETUP,
-       GF_EVENT_MEDIA_END_SESSION_SETUP,
-       GF_EVENT_MEDIA_DATA_REQUEST,
-       GF_EVENT_MEDIA_PLAYABLE,
-       GF_EVENT_MEDIA_NOT_PLAYABLE,
-       GF_EVENT_MEDIA_DATA_PROGRESS,
-       GF_EVENT_MEDIA_END_OF_DATA,
-       GF_EVENT_MEDIA_STOP,
-       GF_EVENT_MEDIA_ERROR,
-#endif
-
-       /*HTML5 media events*/
-
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Jean Le Feuvre \r
+ *                     Copyright (c) Telecom ParisTech 2000-2012\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / Events management\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *\r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GF_EVENTS_CONSTANTS_H_\r
+#define _GF_EVENTS_CONSTANTS_H_\r
+\r
+\r
+\r
+/*\r
+               minimal event system\r
+\r
+       DO NOT CHANGE THEIR POSITION IN THE LIST, USED TO SPEED UP FILTERING OF USER INPUT EVENTS\r
+*/\r
+\r
+/*events*/\r
+enum {\r
+\r
+       /******************************************************\r
+\r
+               Events used for both GPAC internals and DOM Events\r
+\r
+       *******************************************************/\r
+       /*MouseEvents*/\r
+       GF_EVENT_CLICK,\r
+       GF_EVENT_MOUSEUP,\r
+       GF_EVENT_MOUSEDOWN,\r
+       GF_EVENT_MOUSEOVER,\r
+       GF_EVENT_MOUSEOUT,\r
+       /*!! ALL MOUSE EVENTS SHALL BE DECLARED BEFORE MOUSEMOVE !! */\r
+       GF_EVENT_MOUSEMOVE,\r
+       /*mouse wheel event*/\r
+       GF_EVENT_MOUSEWHEEL,\r
+\r
+       /*Key Events*/\r
+       GF_EVENT_KEYUP,\r
+       GF_EVENT_KEYDOWN, /* covers KeyDown, KeyPress and AccessKey */\r
+       GF_EVENT_LONGKEYPRESS,\r
+       /*character input*/\r
+       GF_EVENT_TEXTINPUT,\r
+\r
+\r
+       /******************************************************\r
+\r
+               Events used for DOM Events only\r
+\r
+       *******************************************************/\r
+       GF_EVENT_TEXTSELECT,\r
+\r
+       /*DOM UIEvents*/\r
+       GF_EVENT_FOCUSIN,\r
+       GF_EVENT_FOCUSOUT,\r
+       GF_EVENT_ACTIVATE,\r
+       GF_EVENT_CHANGE,\r
+       GF_EVENT_FOCUS,\r
+       GF_EVENT_BLUR,\r
+       /*SVG (HTML) Events*/\r
+       GF_EVENT_LOAD,\r
+       GF_EVENT_UNLOAD,\r
+       GF_EVENT_ABORT,\r
+       GF_EVENT_ERROR,\r
+       GF_EVENT_RESIZE,\r
+       GF_EVENT_SCROLL,\r
+       GF_EVENT_ZOOM,\r
+       GF_EVENT_BEGIN, /*this is a fake event, it is NEVER fired, only used in SMIL begin*/\r
+       GF_EVENT_BEGIN_EVENT,\r
+       GF_EVENT_END, /*this is a fake event, it is NEVER fired, only used in SMIL end*/\r
+       GF_EVENT_END_EVENT,\r
+       GF_EVENT_REPEAT, /*this is a fake event, it is NEVER fired, only used in SMIL repeat*/\r
+       GF_EVENT_REPEAT_EVENT,\r
+\r
+       /*DOM MutationEvents - NOT SUPPORTED YET*/\r
+       GF_EVENT_TREE_MODIFIED,\r
+       GF_EVENT_NODE_INSERTED,\r
+       GF_EVENT_NODE_REMOVED,\r
+       GF_EVENT_NODE_INSERTED_DOC,\r
+       GF_EVENT_NODE_REMOVED_DOC,\r
+       GF_EVENT_ATTR_MODIFIED,\r
+       GF_EVENT_CHAR_DATA_MODIFIED,\r
+       GF_EVENT_NODE_NAME_CHANGED,\r
+       GF_EVENT_ATTR_NAME_CHANGED,\r
+\r
+       GF_EVENT_DCCI_PROP_CHANGE,\r
+\r
+       /*LASeR events*/\r
+       GF_EVENT_ACTIVATED,\r
+       GF_EVENT_DEACTIVATED,\r
+       GF_EVENT_PAUSE,\r
+       GF_EVENT_PAUSED_EVENT,\r
+       GF_EVENT_PLAY,\r
+       GF_EVENT_REPEAT_KEY,\r
+       GF_EVENT_RESUME_EVENT,\r
+       GF_EVENT_SHORT_ACCESSKEY,\r
+       /*pseudo-event, only used in LASeR coding*/\r
+       GF_EVENT_EXECUTION_TIME,\r
+\r
+       /*MediaAccess events - cf http://www.w3.org/TR/MediaAccessEvents*/\r
+#if 0\r
+       GF_EVENT_MEDIA_BEGIN_SESSION_SETUP,\r
+       GF_EVENT_MEDIA_END_SESSION_SETUP,\r
+       GF_EVENT_MEDIA_DATA_REQUEST,\r
+       GF_EVENT_MEDIA_PLAYABLE,\r
+       GF_EVENT_MEDIA_NOT_PLAYABLE,\r
+       GF_EVENT_MEDIA_DATA_PROGRESS,\r
+       GF_EVENT_MEDIA_END_OF_DATA,\r
+       GF_EVENT_MEDIA_STOP,\r
+       GF_EVENT_MEDIA_ERROR,\r
+#endif\r
+\r
+       /*HTML5 media events*/\r
+\r
        GF_EVENT_MEDIA_SETUP_BEGIN,     /*not HTML5 but should be :)*/\r
        GF_EVENT_MEDIA_SETUP_DONE,      /*not HTML5 but should be :)*/\r
        GF_EVENT_MEDIA_LOAD_START,\r
@@ -152,349 +152,349 @@ enum {
        GF_EVENT_MEDIA_TIME_UPDATE, \r
        GF_EVENT_MEDIA_RATECHANGE, \r
        GF_EVENT_MEDIA_VOLUME_CHANGED, \r
-
-       GF_EVENT_BATTERY,
-       GF_EVENT_CPU,
-       GF_EVENT_UNKNOWN,
-
-
-       /******************************************************
-
-               Events used for GPAC internals only
-
-       *******************************************************/
-
-       /*same as mousedown, generated internally by GPAC*/
-       GF_EVENT_DBLCLICK,
-
-       /*scene attached event, dispatched when the root node of a scene is loaded and
-       attached to the window or parent object (animation, inline, ...)*/
-       GF_EVENT_SCENE_ATTACHED,
-
-       /*VP resize attached event, dispatched when viewport of a scene is being modified
-       attached to the window or parent object (animation, inline, ...)*/
-       GF_EVENT_VP_RESIZE,
-
-       /*window events*/
-       /*size has changed - indicate new w & h in .x end .y fields of event.
-       When sent from gpac to a video plugin, indicates the output size should be changed. This is only sent when the plugin
-       manages the output video himself
-       When sent from a video plugin to gpac, indicates the output size has been changed. This is only sent when the plugin
-       manages the output video himself
-       */
-       GF_EVENT_SIZE,
-       /*signals the scene size (if indicated in scene) upon connection (sent to the user event proc only)
-               if scene size hasn't changed (seeking or other) this event is not sent
-       */
-       GF_EVENT_SCENE_SIZE,
-       GF_EVENT_SHOWHIDE,      /*window show/hide (minimized or other). This is also sent to the user to signal focus switch in fullscreen*/
-       GF_EVENT_SET_CURSOR,    /*set mouse cursor*/
-       GF_EVENT_SET_CAPTION,   /*set window caption*/
-       GF_EVENT_MOVE,          /*move window*/
-       GF_EVENT_REFRESH, /*window needs repaint (whenever needed, eg restore, hide->show, background refresh, paint)*/
-       GF_EVENT_QUIT,  /*window is being closed*/
-       /*video hw setup message:
-               - when sent from gpac to plugin, indicates that the plugin should re-setup hardware context due to a window resize:
-                       * for 2D output, this means resizing the backbuffer if needed (depending on HW constraints)
-                       * for 3D output, this means re-setup of OpenGL context (depending on HW constraints). Depending on windowing systems
-                       and implementations, it could be possible to resize a window without destroying the GL context.
-
-               - when sent from plugin to gpac, indicates that hardware resources must be resetup before next render step (this is mainly
-               due to discard all openGL textures and cached objects)
-       */
-       GF_EVENT_VIDEO_SETUP,
-       /*queries the list of system colors - only exchanged between compositor and video output*/
-       GF_EVENT_SYS_COLORS,
-
-       /*indicates some text has been pasted - from video output to compositor only*/
-       GF_EVENT_PASTE_TEXT,
-       /*queries for text to be copied - from video output to compositor only*/
-       GF_EVENT_COPY_TEXT,
-
-       /*terminal events*/
-       GF_EVENT_CONNECT,       /*signal URL is connected*/
-       GF_EVENT_DURATION,      /*signal duration of presentation*/
-       GF_EVENT_EOS,   /*signal End of scene playback*/
-       GF_EVENT_AUTHORIZATION, /*indicates a user and pass is queried*/
-       GF_EVENT_NAVIGATE, /*indicates the user app should load or jump to the given URL.*/
-       GF_EVENT_NAVIGATE_INFO, /*indicates the link or its description under the mouse pointer*/
-       GF_EVENT_MESSAGE, /*message from the MPEG-4 terminal*/
-       GF_EVENT_PROGRESS, /*progress message from the MPEG-4 terminal*/
-       GF_EVENT_FORWARDED, /*event forwarded by service (MPEG-2, RTP, ...)*/
-       GF_EVENT_VIEWPOINTS,    /*indicates viewpoint list has changed - no struct associated*/
-       GF_EVENT_STREAMLIST,    /*indicates stream list has changed - no struct associated - only used when no scene info is present*/
-       GF_EVENT_METADATA, /*indicates a change in associated metadata*/
-       GF_EVENT_MIGRATE, /*indicates a session migration request*/
-       GF_EVENT_DISCONNECT, /*indicates the current url should be disconnected*/
-       GF_EVENT_RESOLUTION, /*indicates the screen resolution has changed*/
-       GF_EVENT_OPENFILE,
-    /* Events for Keyboad */
-    GF_EVENT_TEXT_EDITING_START,
-    GF_EVENT_TEXT_EDITING_END
-};
-
-/*GPAC/DOM3 key codes*/
-enum {
-       GF_KEY_UNIDENTIFIED = 0,
-       GF_KEY_ACCEPT = 1, /* "Accept"    The Accept (Commit) key.*/
-       GF_KEY_AGAIN, /* "Again"  The Again key.*/
-       GF_KEY_ALLCANDIDATES, /* "AllCandidates"    The All Candidates key.*/
-       GF_KEY_ALPHANUM, /*"Alphanumeric"    The Alphanumeric key.*/
-       GF_KEY_ALT, /*"Alt"    The Alt (Menu) key.*/
-       GF_KEY_ALTGRAPH, /*"AltGraph"    The Alt-Graph key.*/
-       GF_KEY_APPS, /*"Apps"    The Application key.*/
-       GF_KEY_ATTN, /*"Attn"    The ATTN key.*/
-       GF_KEY_BROWSERBACK, /*"BrowserBack"    The Browser Back key.*/
-       GF_KEY_BROWSERFAVORITES, /*"BrowserFavorites"    The Browser Favorites key.*/
-       GF_KEY_BROWSERFORWARD, /*"BrowserForward"    The Browser Forward key.*/
-       GF_KEY_BROWSERHOME, /*"BrowserHome"    The Browser Home key.*/
-       GF_KEY_BROWSERREFRESH, /*"BrowserRefresh"    The Browser Refresh key.*/
-       GF_KEY_BROWSERSEARCH, /*"BrowserSearch"    The Browser Search key.*/
-       GF_KEY_BROWSERSTOP, /*"BrowserStop"    The Browser Stop key.*/
-       GF_KEY_CAPSLOCK, /*"CapsLock"    The Caps Lock (Capital) key.*/
-       GF_KEY_CLEAR, /*"Clear"    The Clear key.*/
-       GF_KEY_CODEINPUT, /*"CodeInput"    The Code Input key.*/
-       GF_KEY_COMPOSE, /*"Compose"    The Compose key.*/
-       GF_KEY_CONTROL, /*"Control"    The Control (Ctrl) key.*/
-       GF_KEY_CRSEL, /*"Crsel"    The Crsel key.*/
-       GF_KEY_CONVERT, /*"Convert"    The Convert key.*/
-       GF_KEY_COPY, /*"Copy"    The Copy key.*/
-       GF_KEY_CUT, /*"Cut"    The Cut key.*/
-       GF_KEY_DOWN, /*"Down"    The Down Arrow key.*/
-       GF_KEY_END, /*"End"    The End key.*/
-       GF_KEY_ENTER, /*"Enter"    The Enter key.
-                   Note: This key identifier is also used for the Return (Macintosh numpad) key.*/
-       GF_KEY_ERASEEOF, /*"EraseEof"    The Erase EOF key.*/
-       GF_KEY_EXECUTE, /*"Execute"    The Execute key.*/
-       GF_KEY_EXSEL, /*"Exsel"    The Exsel key.*/
-       GF_KEY_F1, /*"F1"    The F1 key.*/
-       GF_KEY_F2, /*"F2"    The F2 key.*/
-       GF_KEY_F3, /*"F3"    The F3 key.*/
-       GF_KEY_F4, /*"F4"    The F4 key.*/
-       GF_KEY_F5, /*"F5"    The F5 key.*/
-       GF_KEY_F6, /*"F6"    The F6 key.*/
-       GF_KEY_F7, /*"F7"    The F7 key.*/
-       GF_KEY_F8, /*"F8"    The F8 key.*/
-       GF_KEY_F9, /*"F9"    The F9 key.*/
-       GF_KEY_F10, /*"F10"    The F10 key.*/
-       GF_KEY_F11, /*"F11"    The F11 key.*/
-       GF_KEY_F12, /*"F12"    The F12 key.*/
-       GF_KEY_F13, /*"F13"    The F13 key.*/
-       GF_KEY_F14, /*"F14"    The F14 key.*/
-       GF_KEY_F15, /*"F15"    The F15 key.*/
-       GF_KEY_F16, /*"F16"    The F16 key.*/
-       GF_KEY_F17, /*"F17"    The F17 key.*/
-       GF_KEY_F18, /*"F18"    The F18 key.*/
-       GF_KEY_F19, /*"F19"    The F19 key.*/
-       GF_KEY_F20, /*"F20"    The F20 key.*/
-       GF_KEY_F21, /*"F21"    The F21 key.*/
-       GF_KEY_F22, /*"F22"    The F22 key.*/
-       GF_KEY_F23, /*"F23"    The F23 key.*/
-       GF_KEY_F24, /*"F24"    The F24 key.*/
-       GF_KEY_FINALMODE, /*"FinalMode"    The Final Mode (Final) key used on some asian keyboards.*/
-       GF_KEY_FIND, /*"Find"    The Find key.*/
-       GF_KEY_FULLWIDTH, /*"FullWidth"    The Full-Width Characters key.*/
-       GF_KEY_HALFWIDTH, /*"HalfWidth"    The Half-Width Characters key.*/
-       GF_KEY_HANGULMODE, /*"HangulMode"    The Hangul (Korean characters) Mode key.*/
-       GF_KEY_HANJAMODE, /*"HanjaMode"    The Hanja (Korean characters) Mode key.*/
-       GF_KEY_HELP, /*"Help"    The Help key.*/
-       GF_KEY_HIRAGANA, /*"Hiragana"    The Hiragana (Japanese Kana characters) key.*/
-       GF_KEY_HOME, /*"Home"    The Home key.*/
-       GF_KEY_INSERT, /*"Insert"    The Insert (Ins) key.*/
-       GF_KEY_JAPANESEHIRAGANA, /*"JapaneseHiragana"    The Japanese-Hiragana key.*/
-       GF_KEY_JAPANESEKATAKANA, /*"JapaneseKatakana"    The Japanese-Katakana key.*/
-       GF_KEY_JAPANESEROMAJI, /*"JapaneseRomaji"    The Japanese-Romaji key.*/
-       GF_KEY_JUNJAMODE, /*"JunjaMode"    The Junja Mode key.*/
-       GF_KEY_KANAMODE, /*"KanaMode"    The Kana Mode (Kana Lock) key.*/
-       GF_KEY_KANJIMODE, /*"KanjiMode"    The Kanji (Japanese name for ideographic characters of Chinese origin) Mode key.*/
-       GF_KEY_KATAKANA, /*"Katakana"    The Katakana (Japanese Kana characters) key.*/
-       GF_KEY_LAUNCHAPPLICATION1, /*"LaunchApplication1"    The Start Application One key.*/
-       GF_KEY_LAUNCHAPPLICATION2, /*"LaunchApplication2"    The Start Application Two key.*/
-       GF_KEY_LAUNCHMAIL, /*"LaunchMail"    The Start Mail key.*/
-       GF_KEY_LEFT, /*"Left"    The Left Arrow key.*/
-       GF_KEY_META, /*"Meta"    The Meta key.*/
-       GF_KEY_MEDIANEXTTRACK, /*"MediaNextTrack"    The Media Next Track key.*/
-       GF_KEY_MEDIAPLAYPAUSE, /*"MediaPlayPause"    The Media Play Pause key.*/
-       GF_KEY_MEDIAPREVIOUSTRACK, /*"MediaPreviousTrack"    The Media Previous Track key.*/
-       GF_KEY_MEDIASTOP, /*"MediaStop"    The Media Stok key.*/
-       GF_KEY_MODECHANGE, /*"ModeChange"    The Mode Change key.*/
-       GF_KEY_NONCONVERT, /*"Nonconvert"    The Nonconvert (Don't Convert) key.*/
-       GF_KEY_NUMLOCK, /*"NumLock"    The Num Lock key.*/
-       GF_KEY_PAGEDOWN, /*"PageDown"    The Page Down (Next) key.*/
-       GF_KEY_PAGEUP, /*"PageUp"    The Page Up key.*/
-       GF_KEY_PASTE, /*"Paste"    The Paste key.*/
-       GF_KEY_PAUSE, /*"Pause"    The Pause key.*/
-       GF_KEY_PLAY, /*"Play"    The Play key.*/
-       GF_KEY_PREVIOUSCANDIDATE, /*"PreviousCandidate"    The Previous Candidate function key.*/
-       GF_KEY_PRINTSCREEN, /*"PrintScreen"    The Print Screen (PrintScrn, SnapShot) key.*/
-       GF_KEY_PROCESS, /*"Process"    The Process key.*/
-       GF_KEY_PROPS, /*"Props"    The Props key.*/
-       GF_KEY_RIGHT, /*"Right"    The Right Arrow key.*/
-       GF_KEY_ROMANCHARACTERS, /*"RomanCharacters"    The Roman Characters function key.*/
-       GF_KEY_SCROLL, /*"Scroll"    The Scroll Lock key.*/
-       GF_KEY_SELECT, /*"Select"    The Select key.*/
-       GF_KEY_SELECTMEDIA, /*"SelectMedia"    The Select Media key.*/
-       GF_KEY_SHIFT, /*"Shift"    The Shift key.*/
-       GF_KEY_STOP, /*"Stop"    The Stop key.*/
-       GF_KEY_UP, /*"Up"    The Up Arrow key.*/
-       GF_KEY_UNDO, /*"Undo"    The Undo key.*/
-       GF_KEY_VOLUMEDOWN, /*"VolumeDown"    The Volume Down key.*/
-       GF_KEY_VOLUMEMUTE, /*"VolumeMute"    The Volume Mute key.*/
-       GF_KEY_VOLUMEUP, /*"VolumeUp"    The Volume Up key.*/
-       GF_KEY_WIN, /*"Win"    The Windows Logo key.*/
-       GF_KEY_ZOOM, /*"Zoom"    The Zoom key.*/
-       GF_KEY_BACKSPACE, /*"U+0008"    The Backspace (Back) key.*/
-       GF_KEY_TAB, /*"U+0009"    The Horizontal Tabulation (Tab) key.*/
-       GF_KEY_CANCEL, /*"U+0018"    The Cancel key.*/
-       GF_KEY_ESCAPE, /*"U+001B"    The Escape (Esc) key.*/
-       GF_KEY_SPACE, /*"U+0020"    The Space (Spacebar) key.*/
-       GF_KEY_EXCLAMATION, /*"U+0021"    The Exclamation Mark (Factorial, Bang) key (!).*/
-       GF_KEY_QUOTATION, /*"U+0022"    The Quotation Mark (Quote Double) key (").*/
-       GF_KEY_NUMBER, /*"U+0023"    The Number Sign (Pound Sign, Hash, Crosshatch, Octothorpe) key (#).*/
-       GF_KEY_DOLLAR, /*"U+0024"    The Dollar Sign (milreis, escudo) key ($).*/
-       GF_KEY_AMPERSAND, /*"U+0026"    The Ampersand key (&).*/
-       GF_KEY_APOSTROPHE, /*"U+0027"    The Apostrophe (Apostrophe-Quote, APL Quote) key (').*/
-       GF_KEY_LEFTPARENTHESIS, /*"U+0028"    The Left Parenthesis (Opening Parenthesis) key (().*/
-       GF_KEY_RIGHTPARENTHESIS, /*"U+0029"    The Right Parenthesis (Closing Parenthesis) key ()).*/
-       GF_KEY_STAR, /*"U+002A"    The Asterix (Star) key (*).*/
-       GF_KEY_PLUS, /*"U+002B"    The Plus Sign (Plus) key (+).*/
-       GF_KEY_COMMA, /*"U+002C"    The Comma (decimal separator) sign key (,).*/
-       GF_KEY_HYPHEN, /*"U+002D"    The Hyphen-minus (hyphen or minus sign) key (-).*/
-       GF_KEY_FULLSTOP, /*"U+002E"    The Full Stop (period, dot, decimal point) key (.).*/
-       GF_KEY_SLASH, /*"U+002F"    The Solidus (slash, virgule, shilling) key (/).*/
-       GF_KEY_0, /*"U+0030"    The Digit Zero key (0).*/
-       GF_KEY_1, /*"U+0031"    The Digit One key (1).*/
-       GF_KEY_2, /*"U+0032"    The Digit Two key (2).*/
-       GF_KEY_3, /*"U+0033"    The Digit Three key (3).*/
-       GF_KEY_4, /*"U+0034"    The Digit Four key (4).*/
-       GF_KEY_5, /*"U+0035"    The Digit Five key (5).*/
-       GF_KEY_6, /*"U+0036"    The Digit Six key (6).*/
-       GF_KEY_7, /*"U+0037"    The Digit Seven key (7).*/
-       GF_KEY_8, /*"U+0038"    The Digit Eight key (8).*/
-       GF_KEY_9, /*"U+0039"    The Digit Nine key (9).*/
-       GF_KEY_COLON, /*"U+003A"    The Colon key (:).*/
-       GF_KEY_SEMICOLON, /*"U+003B"    The Semicolon key (;).*/
-       GF_KEY_LESSTHAN, /*"U+003C"    The Less-Than Sign key (<).*/
-       GF_KEY_EQUALS, /*"U+003D"    The Equals Sign key (=).*/
-       GF_KEY_GREATERTHAN, /*"U+003E"    The Greater-Than Sign key (>).*/
-       GF_KEY_QUESTION, /*"U+003F"    The Question Mark key (?).*/
-       GF_KEY_AT, /*"U+0040"    The Commercial At (@) key.*/
-       GF_KEY_A, /*"U+0041"    The Latin Capital Letter A key (A).*/
-       GF_KEY_B, /*"U+0042"    The Latin Capital Letter B key (B).*/
-       GF_KEY_C, /*"U+0043"    The Latin Capital Letter C key (C).*/
-       GF_KEY_D, /*"U+0044"    The Latin Capital Letter D key (D).*/
-       GF_KEY_E, /*"U+0045"    The Latin Capital Letter E key (E).*/
-       GF_KEY_F, /*"U+0046"    The Latin Capital Letter F key (F).*/
-       GF_KEY_G, /*"U+0047"    The Latin Capital Letter G key (G).*/
-       GF_KEY_H, /*"U+0048"    The Latin Capital Letter H key (H).*/
-       GF_KEY_I, /*"U+0049"    The Latin Capital Letter I key (I).*/
-       GF_KEY_J, /*"U+004A"    The Latin Capital Letter J key (J).*/
-       GF_KEY_K, /*"U+004B"    The Latin Capital Letter K key (K).*/
-       GF_KEY_L, /*"U+004C"    The Latin Capital Letter L key (L).*/
-       GF_KEY_M, /*"U+004D"    The Latin Capital Letter M key (M).*/
-       GF_KEY_N, /*"U+004E"    The Latin Capital Letter N key (N).*/
-       GF_KEY_O, /*"U+004F"    The Latin Capital Letter O key (O).*/
-       GF_KEY_P, /*"U+0050"    The Latin Capital Letter P key (P).*/
-       GF_KEY_Q, /*"U+0051"    The Latin Capital Letter Q key (Q).*/
-       GF_KEY_R, /*"U+0052"    The Latin Capital Letter R key (R).*/
-       GF_KEY_S, /*"U+0053"    The Latin Capital Letter S key (S).*/
-       GF_KEY_T, /*"U+0054"    The Latin Capital Letter T key (T).*/
-       GF_KEY_U, /*"U+0055"    The Latin Capital Letter U key (U).*/
-       GF_KEY_V, /*"U+0056"    The Latin Capital Letter V key (V).*/
-       GF_KEY_W, /*"U+0057"    The Latin Capital Letter W key (W).*/
-       GF_KEY_X, /*"U+0058"    The Latin Capital Letter X key (X).*/
-       GF_KEY_Y, /*"U+0059"    The Latin Capital Letter Y key (Y).*/
-       GF_KEY_Z, /*"U+005A"    The Latin Capital Letter Z key (Z).*/
-       GF_KEY_LEFTSQUAREBRACKET, /*"U+005B"    The Left Square Bracket (Opening Square Bracket) key ([).*/
-       GF_KEY_BACKSLASH, /*"U+005C"    The Reverse Solidus (Backslash) key (\).*/
-       GF_KEY_RIGHTSQUAREBRACKET, /*"U+005D"    The Right Square Bracket (Closing Square Bracket) key (]).*/
-       GF_KEY_CIRCUM, /*"U+005E"    The Circumflex Accent key (^).*/
-       GF_KEY_UNDERSCORE, /*"U+005F"    The Low Sign (Spacing Underscore, Underscore) key (_).*/
-       GF_KEY_GRAVEACCENT, /*"U+0060"    The Grave Accent (Back Quote) key (`).*/
-       GF_KEY_LEFTCURLYBRACKET, /*"U+007B"    The Left Curly Bracket (Opening Curly Bracket, Opening Brace, Brace Left) key ({).*/
-       GF_KEY_PIPE, /*"U+007C"    The Vertical Line (Vertical Bar, Pipe) key (|).*/
-       GF_KEY_RIGHTCURLYBRACKET, /*"U+007D"    The Right Curly Bracket (Closing Curly Bracket, Closing Brace, Brace Right) key (}).*/
-       GF_KEY_DEL, /*"U+007F"    The Delete (Del) Key.*/
-       GF_KEY_INVERTEXCLAMATION, /*"U+00A1"    The Inverted Exclamation Mark key (�).*/
-       GF_KEY_DEADGRAVE, /*"U+0300"    The Combining Grave Accent (Greek Varia, Dead Grave) key.*/
-       GF_KEY_DEADEACUTE, /*"U+0301"    The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute) key.*/
-       GF_KEY_DEADCIRCUM, /*"U+0302"    The Combining Circumflex Accent (Hat, Dead Circumflex) key.*/
-       GF_KEY_DEADTILDE, /*"U+0303"    The Combining Tilde (Dead Tilde) key.*/
-       GF_KEY_DEADMACRON, /*"U+0304"    The Combining Macron (Long, Dead Macron) key.*/
-       GF_KEY_DEADBREVE, /*"U+0306"    The Combining Breve (Short, Dead Breve) key.*/
-       GF_KEY_DEADABOVEDOT, /*"U+0307"    The Combining Dot Above (Derivative, Dead Above Dot) key.*/
-       GF_KEY_DEADDIARESIS, /*"U+0308"    The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika, Double Derivative, Dead Diaeresis) key.*/
-       GF_KEY_DEADRINGABOVE, /*"U+030A"    The Combining Ring Above (Dead Above Ring) key.*/
-       GF_KEY_DEADDOUBLEACUTE, /*"U+030B"    The Combining Double Acute Accent (Dead Doubleacute) key.*/
-       GF_KEY_DEADCARON, /*"U+030C"    The Combining Caron (Hacek, V Above, Dead Caron) key.*/
-       GF_KEY_DEADCEDILLA, /*"U+0327"    The Combining Cedilla (Dead Cedilla) key.*/
-       GF_KEY_DEADOGONEK, /*"U+0328"    The Combining Ogonek (Nasal Hook, Dead Ogonek) key.*/
-       GF_KEY_DEADIOTA, /*"U+0345"    The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota Subscript, Dead Iota) key.*/
-       GF_KEY_EURO, /*"U+20AC"    The Euro Currency Sign key (�).*/
-       GF_KEY_DEADVOICESOUND, /*"U+3099"    The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key.*/
-       GF_KEY_DEADSEMIVOICESOUND, /*"U+309A"    The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced Sound) key. */
-       /* STB */
-       GF_KEY_CHANNELUP, /*ChannelUp*/
-       GF_KEY_CHANNELDOWN, /*ChannelDown*/
-       GF_KEY_TEXT, /*Text*/
-       GF_KEY_INFO, /*Info*/
-       GF_KEY_EPG, /*EPG*/
-       GF_KEY_RECORD, /*Record*/
-       GF_KEY_BEGINPAGE, /*BeginPage*/
-    /* end STB */
-
-       /*non-dom keys, used in LASeR*/
-       GF_KEY_CELL_SOFT1,      /*soft1 key of cell phones*/
-       GF_KEY_CELL_SOFT2,      /*soft2 key of cell phones*/
-
-       /*for joystick handling*/
-       GF_KEY_JOYSTICK
-};
-
-
-/*key modifiers state - set by terminal (not set by video driver)*/
-enum
-{
-       GF_KEY_MOD_SHIFT = (1),
-       GF_KEY_MOD_CTRL = (1<<2),
-       GF_KEY_MOD_ALT = (1<<3),
-
-       GF_KEY_EXT_NUMPAD = (1<<4),
-       GF_KEY_EXT_LEFT = (1<<5),
-       GF_KEY_EXT_RIGHT = (1<<6)
-};
-
-/*sensor signaling*/
-enum
-{
-       GF_CURSOR_NORMAL = 0x00,
-       GF_CURSOR_ANCHOR,
-       GF_CURSOR_TOUCH,
-       /*discSensor, cylinderSensor, sphereSensor*/
-       GF_CURSOR_ROTATE,
-       /*proximitySensor & proximitySensor2D*/
-       GF_CURSOR_PROXIMITY,
-       /*planeSensor & planeSensor2D*/
-       GF_CURSOR_PLANE,
-       /*collision*/
-       GF_CURSOR_COLLIDE,
-       GF_CURSOR_HIDE,
-};
-
-/*Mutation AttrChangeType Signaling*/
-enum
-{
-       GF_MUTATION_ATTRCHANGE_MODIFICATION = 0x01,
-       GF_MUTATION_ATTRCHANGE_ADDITION = 0x02,
-       GF_MUTATION_ATTRCHANGE_REMOVAL = 0x03,
-};
-
-enum
-{
-       /*events forwarded from MPEG-2 stack*/
-       GF_EVT_FORWARDED_MPEG2 = 0,
-       /*events forwarded from RTP/RTSP/IP stack (not used yet)*/
-       GF_EVT_FORWARDED_RTP_RTSP
-};
-
-#endif
+\r
+       GF_EVENT_BATTERY,\r
+       GF_EVENT_CPU,\r
+       GF_EVENT_UNKNOWN,\r
+\r
+\r
+       /******************************************************\r
+\r
+               Events used for GPAC internals only\r
+\r
+       *******************************************************/\r
+\r
+       /*same as mousedown, generated internally by GPAC*/\r
+       GF_EVENT_DBLCLICK,\r
+\r
+       /*scene attached event, dispatched when the root node of a scene is loaded and\r
+       attached to the window or parent object (animation, inline, ...)*/\r
+       GF_EVENT_SCENE_ATTACHED,\r
+\r
+       /*VP resize attached event, dispatched when viewport of a scene is being modified\r
+       attached to the window or parent object (animation, inline, ...)*/\r
+       GF_EVENT_VP_RESIZE,\r
+\r
+       /*window events*/\r
+       /*size has changed - indicate new w & h in .x end .y fields of event.\r
+       When sent from gpac to a video plugin, indicates the output size should be changed. This is only sent when the plugin\r
+       manages the output video himself\r
+       When sent from a video plugin to gpac, indicates the output size has been changed. This is only sent when the plugin\r
+       manages the output video himself\r
+       */\r
+       GF_EVENT_SIZE,\r
+       /*signals the scene size (if indicated in scene) upon connection (sent to the user event proc only)\r
+               if scene size hasn't changed (seeking or other) this event is not sent\r
+       */\r
+       GF_EVENT_SCENE_SIZE,\r
+       GF_EVENT_SHOWHIDE,      /*window show/hide (minimized or other). This is also sent to the user to signal focus switch in fullscreen*/\r
+       GF_EVENT_SET_CURSOR,    /*set mouse cursor*/\r
+       GF_EVENT_SET_CAPTION,   /*set window caption*/\r
+       GF_EVENT_MOVE,          /*move window*/\r
+       GF_EVENT_REFRESH, /*window needs repaint (whenever needed, eg restore, hide->show, background refresh, paint)*/\r
+       GF_EVENT_QUIT,  /*window is being closed*/\r
+       /*video hw setup message:\r
+               - when sent from gpac to plugin, indicates that the plugin should re-setup hardware context due to a window resize:\r
+                       * for 2D output, this means resizing the backbuffer if needed (depending on HW constraints)\r
+                       * for 3D output, this means re-setup of OpenGL context (depending on HW constraints). Depending on windowing systems\r
+                       and implementations, it could be possible to resize a window without destroying the GL context.\r
+\r
+               - when sent from plugin to gpac, indicates that hardware resources must be resetup before next render step (this is mainly\r
+               due to discard all openGL textures and cached objects)\r
+       */\r
+       GF_EVENT_VIDEO_SETUP,\r
+       /*queries the list of system colors - only exchanged between compositor and video output*/\r
+       GF_EVENT_SYS_COLORS,\r
+\r
+       /*indicates some text has been pasted - from video output to compositor only*/\r
+       GF_EVENT_PASTE_TEXT,\r
+       /*queries for text to be copied - from video output to compositor only*/\r
+       GF_EVENT_COPY_TEXT,\r
+\r
+       /*terminal events*/\r
+       GF_EVENT_CONNECT,       /*signal URL is connected*/\r
+       GF_EVENT_DURATION,      /*signal duration of presentation*/\r
+       GF_EVENT_EOS,   /*signal End of scene playback*/\r
+       GF_EVENT_AUTHORIZATION, /*indicates a user and pass is queried*/\r
+       GF_EVENT_NAVIGATE, /*indicates the user app should load or jump to the given URL.*/\r
+       GF_EVENT_NAVIGATE_INFO, /*indicates the link or its description under the mouse pointer*/\r
+       GF_EVENT_MESSAGE, /*message from the MPEG-4 terminal*/\r
+       GF_EVENT_PROGRESS, /*progress message from the MPEG-4 terminal*/\r
+       GF_EVENT_FORWARDED, /*event forwarded by service (MPEG-2, RTP, ...)*/\r
+       GF_EVENT_VIEWPOINTS,    /*indicates viewpoint list has changed - no struct associated*/\r
+       GF_EVENT_STREAMLIST,    /*indicates stream list has changed - no struct associated - only used when no scene info is present*/\r
+       GF_EVENT_METADATA, /*indicates a change in associated metadata*/\r
+       GF_EVENT_MIGRATE, /*indicates a session migration request*/\r
+       GF_EVENT_DISCONNECT, /*indicates the current url should be disconnected*/\r
+       GF_EVENT_RESOLUTION, /*indicates the screen resolution has changed*/\r
+       GF_EVENT_OPENFILE,\r
+    /* Events for Keyboad */\r
+    GF_EVENT_TEXT_EDITING_START,\r
+    GF_EVENT_TEXT_EDITING_END\r
+};\r
+\r
+/*GPAC/DOM3 key codes*/\r
+enum {\r
+       GF_KEY_UNIDENTIFIED = 0,\r
+       GF_KEY_ACCEPT = 1, /* "Accept"    The Accept (Commit) key.*/\r
+       GF_KEY_AGAIN, /* "Again"  The Again key.*/\r
+       GF_KEY_ALLCANDIDATES, /* "AllCandidates"    The All Candidates key.*/\r
+       GF_KEY_ALPHANUM, /*"Alphanumeric"    The Alphanumeric key.*/\r
+       GF_KEY_ALT, /*"Alt"    The Alt (Menu) key.*/\r
+       GF_KEY_ALTGRAPH, /*"AltGraph"    The Alt-Graph key.*/\r
+       GF_KEY_APPS, /*"Apps"    The Application key.*/\r
+       GF_KEY_ATTN, /*"Attn"    The ATTN key.*/\r
+       GF_KEY_BROWSERBACK, /*"BrowserBack"    The Browser Back key.*/\r
+       GF_KEY_BROWSERFAVORITES, /*"BrowserFavorites"    The Browser Favorites key.*/\r
+       GF_KEY_BROWSERFORWARD, /*"BrowserForward"    The Browser Forward key.*/\r
+       GF_KEY_BROWSERHOME, /*"BrowserHome"    The Browser Home key.*/\r
+       GF_KEY_BROWSERREFRESH, /*"BrowserRefresh"    The Browser Refresh key.*/\r
+       GF_KEY_BROWSERSEARCH, /*"BrowserSearch"    The Browser Search key.*/\r
+       GF_KEY_BROWSERSTOP, /*"BrowserStop"    The Browser Stop key.*/\r
+       GF_KEY_CAPSLOCK, /*"CapsLock"    The Caps Lock (Capital) key.*/\r
+       GF_KEY_CLEAR, /*"Clear"    The Clear key.*/\r
+       GF_KEY_CODEINPUT, /*"CodeInput"    The Code Input key.*/\r
+       GF_KEY_COMPOSE, /*"Compose"    The Compose key.*/\r
+       GF_KEY_CONTROL, /*"Control"    The Control (Ctrl) key.*/\r
+       GF_KEY_CRSEL, /*"Crsel"    The Crsel key.*/\r
+       GF_KEY_CONVERT, /*"Convert"    The Convert key.*/\r
+       GF_KEY_COPY, /*"Copy"    The Copy key.*/\r
+       GF_KEY_CUT, /*"Cut"    The Cut key.*/\r
+       GF_KEY_DOWN, /*"Down"    The Down Arrow key.*/\r
+       GF_KEY_END, /*"End"    The End key.*/\r
+       GF_KEY_ENTER, /*"Enter"    The Enter key.\r
+                   Note: This key identifier is also used for the Return (Macintosh numpad) key.*/\r
+       GF_KEY_ERASEEOF, /*"EraseEof"    The Erase EOF key.*/\r
+       GF_KEY_EXECUTE, /*"Execute"    The Execute key.*/\r
+       GF_KEY_EXSEL, /*"Exsel"    The Exsel key.*/\r
+       GF_KEY_F1, /*"F1"    The F1 key.*/\r
+       GF_KEY_F2, /*"F2"    The F2 key.*/\r
+       GF_KEY_F3, /*"F3"    The F3 key.*/\r
+       GF_KEY_F4, /*"F4"    The F4 key.*/\r
+       GF_KEY_F5, /*"F5"    The F5 key.*/\r
+       GF_KEY_F6, /*"F6"    The F6 key.*/\r
+       GF_KEY_F7, /*"F7"    The F7 key.*/\r
+       GF_KEY_F8, /*"F8"    The F8 key.*/\r
+       GF_KEY_F9, /*"F9"    The F9 key.*/\r
+       GF_KEY_F10, /*"F10"    The F10 key.*/\r
+       GF_KEY_F11, /*"F11"    The F11 key.*/\r
+       GF_KEY_F12, /*"F12"    The F12 key.*/\r
+       GF_KEY_F13, /*"F13"    The F13 key.*/\r
+       GF_KEY_F14, /*"F14"    The F14 key.*/\r
+       GF_KEY_F15, /*"F15"    The F15 key.*/\r
+       GF_KEY_F16, /*"F16"    The F16 key.*/\r
+       GF_KEY_F17, /*"F17"    The F17 key.*/\r
+       GF_KEY_F18, /*"F18"    The F18 key.*/\r
+       GF_KEY_F19, /*"F19"    The F19 key.*/\r
+       GF_KEY_F20, /*"F20"    The F20 key.*/\r
+       GF_KEY_F21, /*"F21"    The F21 key.*/\r
+       GF_KEY_F22, /*"F22"    The F22 key.*/\r
+       GF_KEY_F23, /*"F23"    The F23 key.*/\r
+       GF_KEY_F24, /*"F24"    The F24 key.*/\r
+       GF_KEY_FINALMODE, /*"FinalMode"    The Final Mode (Final) key used on some asian keyboards.*/\r
+       GF_KEY_FIND, /*"Find"    The Find key.*/\r
+       GF_KEY_FULLWIDTH, /*"FullWidth"    The Full-Width Characters key.*/\r
+       GF_KEY_HALFWIDTH, /*"HalfWidth"    The Half-Width Characters key.*/\r
+       GF_KEY_HANGULMODE, /*"HangulMode"    The Hangul (Korean characters) Mode key.*/\r
+       GF_KEY_HANJAMODE, /*"HanjaMode"    The Hanja (Korean characters) Mode key.*/\r
+       GF_KEY_HELP, /*"Help"    The Help key.*/\r
+       GF_KEY_HIRAGANA, /*"Hiragana"    The Hiragana (Japanese Kana characters) key.*/\r
+       GF_KEY_HOME, /*"Home"    The Home key.*/\r
+       GF_KEY_INSERT, /*"Insert"    The Insert (Ins) key.*/\r
+       GF_KEY_JAPANESEHIRAGANA, /*"JapaneseHiragana"    The Japanese-Hiragana key.*/\r
+       GF_KEY_JAPANESEKATAKANA, /*"JapaneseKatakana"    The Japanese-Katakana key.*/\r
+       GF_KEY_JAPANESEROMAJI, /*"JapaneseRomaji"    The Japanese-Romaji key.*/\r
+       GF_KEY_JUNJAMODE, /*"JunjaMode"    The Junja Mode key.*/\r
+       GF_KEY_KANAMODE, /*"KanaMode"    The Kana Mode (Kana Lock) key.*/\r
+       GF_KEY_KANJIMODE, /*"KanjiMode"    The Kanji (Japanese name for ideographic characters of Chinese origin) Mode key.*/\r
+       GF_KEY_KATAKANA, /*"Katakana"    The Katakana (Japanese Kana characters) key.*/\r
+       GF_KEY_LAUNCHAPPLICATION1, /*"LaunchApplication1"    The Start Application One key.*/\r
+       GF_KEY_LAUNCHAPPLICATION2, /*"LaunchApplication2"    The Start Application Two key.*/\r
+       GF_KEY_LAUNCHMAIL, /*"LaunchMail"    The Start Mail key.*/\r
+       GF_KEY_LEFT, /*"Left"    The Left Arrow key.*/\r
+       GF_KEY_META, /*"Meta"    The Meta key.*/\r
+       GF_KEY_MEDIANEXTTRACK, /*"MediaNextTrack"    The Media Next Track key.*/\r
+       GF_KEY_MEDIAPLAYPAUSE, /*"MediaPlayPause"    The Media Play Pause key.*/\r
+       GF_KEY_MEDIAPREVIOUSTRACK, /*"MediaPreviousTrack"    The Media Previous Track key.*/\r
+       GF_KEY_MEDIASTOP, /*"MediaStop"    The Media Stok key.*/\r
+       GF_KEY_MODECHANGE, /*"ModeChange"    The Mode Change key.*/\r
+       GF_KEY_NONCONVERT, /*"Nonconvert"    The Nonconvert (Don't Convert) key.*/\r
+       GF_KEY_NUMLOCK, /*"NumLock"    The Num Lock key.*/\r
+       GF_KEY_PAGEDOWN, /*"PageDown"    The Page Down (Next) key.*/\r
+       GF_KEY_PAGEUP, /*"PageUp"    The Page Up key.*/\r
+       GF_KEY_PASTE, /*"Paste"    The Paste key.*/\r
+       GF_KEY_PAUSE, /*"Pause"    The Pause key.*/\r
+       GF_KEY_PLAY, /*"Play"    The Play key.*/\r
+       GF_KEY_PREVIOUSCANDIDATE, /*"PreviousCandidate"    The Previous Candidate function key.*/\r
+       GF_KEY_PRINTSCREEN, /*"PrintScreen"    The Print Screen (PrintScrn, SnapShot) key.*/\r
+       GF_KEY_PROCESS, /*"Process"    The Process key.*/\r
+       GF_KEY_PROPS, /*"Props"    The Props key.*/\r
+       GF_KEY_RIGHT, /*"Right"    The Right Arrow key.*/\r
+       GF_KEY_ROMANCHARACTERS, /*"RomanCharacters"    The Roman Characters function key.*/\r
+       GF_KEY_SCROLL, /*"Scroll"    The Scroll Lock key.*/\r
+       GF_KEY_SELECT, /*"Select"    The Select key.*/\r
+       GF_KEY_SELECTMEDIA, /*"SelectMedia"    The Select Media key.*/\r
+       GF_KEY_SHIFT, /*"Shift"    The Shift key.*/\r
+       GF_KEY_STOP, /*"Stop"    The Stop key.*/\r
+       GF_KEY_UP, /*"Up"    The Up Arrow key.*/\r
+       GF_KEY_UNDO, /*"Undo"    The Undo key.*/\r
+       GF_KEY_VOLUMEDOWN, /*"VolumeDown"    The Volume Down key.*/\r
+       GF_KEY_VOLUMEMUTE, /*"VolumeMute"    The Volume Mute key.*/\r
+       GF_KEY_VOLUMEUP, /*"VolumeUp"    The Volume Up key.*/\r
+       GF_KEY_WIN, /*"Win"    The Windows Logo key.*/\r
+       GF_KEY_ZOOM, /*"Zoom"    The Zoom key.*/\r
+       GF_KEY_BACKSPACE, /*"U+0008"    The Backspace (Back) key.*/\r
+       GF_KEY_TAB, /*"U+0009"    The Horizontal Tabulation (Tab) key.*/\r
+       GF_KEY_CANCEL, /*"U+0018"    The Cancel key.*/\r
+       GF_KEY_ESCAPE, /*"U+001B"    The Escape (Esc) key.*/\r
+       GF_KEY_SPACE, /*"U+0020"    The Space (Spacebar) key.*/\r
+       GF_KEY_EXCLAMATION, /*"U+0021"    The Exclamation Mark (Factorial, Bang) key (!).*/\r
+       GF_KEY_QUOTATION, /*"U+0022"    The Quotation Mark (Quote Double) key (").*/\r
+       GF_KEY_NUMBER, /*"U+0023"    The Number Sign (Pound Sign, Hash, Crosshatch, Octothorpe) key (#).*/\r
+       GF_KEY_DOLLAR, /*"U+0024"    The Dollar Sign (milreis, escudo) key ($).*/\r
+       GF_KEY_AMPERSAND, /*"U+0026"    The Ampersand key (&).*/\r
+       GF_KEY_APOSTROPHE, /*"U+0027"    The Apostrophe (Apostrophe-Quote, APL Quote) key (').*/\r
+       GF_KEY_LEFTPARENTHESIS, /*"U+0028"    The Left Parenthesis (Opening Parenthesis) key (().*/\r
+       GF_KEY_RIGHTPARENTHESIS, /*"U+0029"    The Right Parenthesis (Closing Parenthesis) key ()).*/\r
+       GF_KEY_STAR, /*"U+002A"    The Asterix (Star) key (*).*/\r
+       GF_KEY_PLUS, /*"U+002B"    The Plus Sign (Plus) key (+).*/\r
+       GF_KEY_COMMA, /*"U+002C"    The Comma (decimal separator) sign key (,).*/\r
+       GF_KEY_HYPHEN, /*"U+002D"    The Hyphen-minus (hyphen or minus sign) key (-).*/\r
+       GF_KEY_FULLSTOP, /*"U+002E"    The Full Stop (period, dot, decimal point) key (.).*/\r
+       GF_KEY_SLASH, /*"U+002F"    The Solidus (slash, virgule, shilling) key (/).*/\r
+       GF_KEY_0, /*"U+0030"    The Digit Zero key (0).*/\r
+       GF_KEY_1, /*"U+0031"    The Digit One key (1).*/\r
+       GF_KEY_2, /*"U+0032"    The Digit Two key (2).*/\r
+       GF_KEY_3, /*"U+0033"    The Digit Three key (3).*/\r
+       GF_KEY_4, /*"U+0034"    The Digit Four key (4).*/\r
+       GF_KEY_5, /*"U+0035"    The Digit Five key (5).*/\r
+       GF_KEY_6, /*"U+0036"    The Digit Six key (6).*/\r
+       GF_KEY_7, /*"U+0037"    The Digit Seven key (7).*/\r
+       GF_KEY_8, /*"U+0038"    The Digit Eight key (8).*/\r
+       GF_KEY_9, /*"U+0039"    The Digit Nine key (9).*/\r
+       GF_KEY_COLON, /*"U+003A"    The Colon key (:).*/\r
+       GF_KEY_SEMICOLON, /*"U+003B"    The Semicolon key (;).*/\r
+       GF_KEY_LESSTHAN, /*"U+003C"    The Less-Than Sign key (<).*/\r
+       GF_KEY_EQUALS, /*"U+003D"    The Equals Sign key (=).*/\r
+       GF_KEY_GREATERTHAN, /*"U+003E"    The Greater-Than Sign key (>).*/\r
+       GF_KEY_QUESTION, /*"U+003F"    The Question Mark key (?).*/\r
+       GF_KEY_AT, /*"U+0040"    The Commercial At (@) key.*/\r
+       GF_KEY_A, /*"U+0041"    The Latin Capital Letter A key (A).*/\r
+       GF_KEY_B, /*"U+0042"    The Latin Capital Letter B key (B).*/\r
+       GF_KEY_C, /*"U+0043"    The Latin Capital Letter C key (C).*/\r
+       GF_KEY_D, /*"U+0044"    The Latin Capital Letter D key (D).*/\r
+       GF_KEY_E, /*"U+0045"    The Latin Capital Letter E key (E).*/\r
+       GF_KEY_F, /*"U+0046"    The Latin Capital Letter F key (F).*/\r
+       GF_KEY_G, /*"U+0047"    The Latin Capital Letter G key (G).*/\r
+       GF_KEY_H, /*"U+0048"    The Latin Capital Letter H key (H).*/\r
+       GF_KEY_I, /*"U+0049"    The Latin Capital Letter I key (I).*/\r
+       GF_KEY_J, /*"U+004A"    The Latin Capital Letter J key (J).*/\r
+       GF_KEY_K, /*"U+004B"    The Latin Capital Letter K key (K).*/\r
+       GF_KEY_L, /*"U+004C"    The Latin Capital Letter L key (L).*/\r
+       GF_KEY_M, /*"U+004D"    The Latin Capital Letter M key (M).*/\r
+       GF_KEY_N, /*"U+004E"    The Latin Capital Letter N key (N).*/\r
+       GF_KEY_O, /*"U+004F"    The Latin Capital Letter O key (O).*/\r
+       GF_KEY_P, /*"U+0050"    The Latin Capital Letter P key (P).*/\r
+       GF_KEY_Q, /*"U+0051"    The Latin Capital Letter Q key (Q).*/\r
+       GF_KEY_R, /*"U+0052"    The Latin Capital Letter R key (R).*/\r
+       GF_KEY_S, /*"U+0053"    The Latin Capital Letter S key (S).*/\r
+       GF_KEY_T, /*"U+0054"    The Latin Capital Letter T key (T).*/\r
+       GF_KEY_U, /*"U+0055"    The Latin Capital Letter U key (U).*/\r
+       GF_KEY_V, /*"U+0056"    The Latin Capital Letter V key (V).*/\r
+       GF_KEY_W, /*"U+0057"    The Latin Capital Letter W key (W).*/\r
+       GF_KEY_X, /*"U+0058"    The Latin Capital Letter X key (X).*/\r
+       GF_KEY_Y, /*"U+0059"    The Latin Capital Letter Y key (Y).*/\r
+       GF_KEY_Z, /*"U+005A"    The Latin Capital Letter Z key (Z).*/\r
+       GF_KEY_LEFTSQUAREBRACKET, /*"U+005B"    The Left Square Bracket (Opening Square Bracket) key ([).*/\r
+       GF_KEY_BACKSLASH, /*"U+005C"    The Reverse Solidus (Backslash) key (\).*/\r
+       GF_KEY_RIGHTSQUAREBRACKET, /*"U+005D"    The Right Square Bracket (Closing Square Bracket) key (]).*/\r
+       GF_KEY_CIRCUM, /*"U+005E"    The Circumflex Accent key (^).*/\r
+       GF_KEY_UNDERSCORE, /*"U+005F"    The Low Sign (Spacing Underscore, Underscore) key (_).*/\r
+       GF_KEY_GRAVEACCENT, /*"U+0060"    The Grave Accent (Back Quote) key (`).*/\r
+       GF_KEY_LEFTCURLYBRACKET, /*"U+007B"    The Left Curly Bracket (Opening Curly Bracket, Opening Brace, Brace Left) key ({).*/\r
+       GF_KEY_PIPE, /*"U+007C"    The Vertical Line (Vertical Bar, Pipe) key (|).*/\r
+       GF_KEY_RIGHTCURLYBRACKET, /*"U+007D"    The Right Curly Bracket (Closing Curly Bracket, Closing Brace, Brace Right) key (}).*/\r
+       GF_KEY_DEL, /*"U+007F"    The Delete (Del) Key.*/\r
+       GF_KEY_INVERTEXCLAMATION, /*"U+00A1"    The Inverted Exclamation Mark key (�).*/\r
+       GF_KEY_DEADGRAVE, /*"U+0300"    The Combining Grave Accent (Greek Varia, Dead Grave) key.*/\r
+       GF_KEY_DEADEACUTE, /*"U+0301"    The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute) key.*/\r
+       GF_KEY_DEADCIRCUM, /*"U+0302"    The Combining Circumflex Accent (Hat, Dead Circumflex) key.*/\r
+       GF_KEY_DEADTILDE, /*"U+0303"    The Combining Tilde (Dead Tilde) key.*/\r
+       GF_KEY_DEADMACRON, /*"U+0304"    The Combining Macron (Long, Dead Macron) key.*/\r
+       GF_KEY_DEADBREVE, /*"U+0306"    The Combining Breve (Short, Dead Breve) key.*/\r
+       GF_KEY_DEADABOVEDOT, /*"U+0307"    The Combining Dot Above (Derivative, Dead Above Dot) key.*/\r
+       GF_KEY_DEADDIARESIS, /*"U+0308"    The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika, Double Derivative, Dead Diaeresis) key.*/\r
+       GF_KEY_DEADRINGABOVE, /*"U+030A"    The Combining Ring Above (Dead Above Ring) key.*/\r
+       GF_KEY_DEADDOUBLEACUTE, /*"U+030B"    The Combining Double Acute Accent (Dead Doubleacute) key.*/\r
+       GF_KEY_DEADCARON, /*"U+030C"    The Combining Caron (Hacek, V Above, Dead Caron) key.*/\r
+       GF_KEY_DEADCEDILLA, /*"U+0327"    The Combining Cedilla (Dead Cedilla) key.*/\r
+       GF_KEY_DEADOGONEK, /*"U+0328"    The Combining Ogonek (Nasal Hook, Dead Ogonek) key.*/\r
+       GF_KEY_DEADIOTA, /*"U+0345"    The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota Subscript, Dead Iota) key.*/\r
+       GF_KEY_EURO, /*"U+20AC"    The Euro Currency Sign key (�).*/\r
+       GF_KEY_DEADVOICESOUND, /*"U+3099"    The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key.*/\r
+       GF_KEY_DEADSEMIVOICESOUND, /*"U+309A"    The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced Sound) key. */\r
+       /* STB */\r
+       GF_KEY_CHANNELUP, /*ChannelUp*/\r
+       GF_KEY_CHANNELDOWN, /*ChannelDown*/\r
+       GF_KEY_TEXT, /*Text*/\r
+       GF_KEY_INFO, /*Info*/\r
+       GF_KEY_EPG, /*EPG*/\r
+       GF_KEY_RECORD, /*Record*/\r
+       GF_KEY_BEGINPAGE, /*BeginPage*/\r
+    /* end STB */\r
+\r
+       /*non-dom keys, used in LASeR*/\r
+       GF_KEY_CELL_SOFT1,      /*soft1 key of cell phones*/\r
+       GF_KEY_CELL_SOFT2,      /*soft2 key of cell phones*/\r
+\r
+       /*for joystick handling*/\r
+       GF_KEY_JOYSTICK\r
+};\r
+\r
+\r
+/*key modifiers state - set by terminal (not set by video driver)*/\r
+enum\r
+{\r
+       GF_KEY_MOD_SHIFT = (1),\r
+       GF_KEY_MOD_CTRL = (1<<2),\r
+       GF_KEY_MOD_ALT = (1<<3),\r
+\r
+       GF_KEY_EXT_NUMPAD = (1<<4),\r
+       GF_KEY_EXT_LEFT = (1<<5),\r
+       GF_KEY_EXT_RIGHT = (1<<6)\r
+};\r
+\r
+/*sensor signaling*/\r
+enum\r
+{\r
+       GF_CURSOR_NORMAL = 0x00,\r
+       GF_CURSOR_ANCHOR,\r
+       GF_CURSOR_TOUCH,\r
+       /*discSensor, cylinderSensor, sphereSensor*/\r
+       GF_CURSOR_ROTATE,\r
+       /*proximitySensor & proximitySensor2D*/\r
+       GF_CURSOR_PROXIMITY,\r
+       /*planeSensor & planeSensor2D*/\r
+       GF_CURSOR_PLANE,\r
+       /*collision*/\r
+       GF_CURSOR_COLLIDE,\r
+       GF_CURSOR_HIDE,\r
+};\r
+\r
+/*Mutation AttrChangeType Signaling*/\r
+enum\r
+{\r
+       GF_MUTATION_ATTRCHANGE_MODIFICATION = 0x01,\r
+       GF_MUTATION_ATTRCHANGE_ADDITION = 0x02,\r
+       GF_MUTATION_ATTRCHANGE_REMOVAL = 0x03,\r
+};\r
+\r
+enum\r
+{\r
+       /*events forwarded from MPEG-2 stack*/\r
+       GF_EVT_FORWARDED_MPEG2 = 0,\r
+       /*events forwarded from RTP/RTSP/IP stack (not used yet)*/\r
+       GF_EVT_FORWARDED_RTP_RTSP\r
+};\r
+\r
+#endif\r
index a400851a49615cd916f5d9b31c0354235dc80b01..a882f2abb396982d420c8cd3c79b3acdd599dda8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2008-
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2008-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / media tools sub-project
index 7818052042eb28bcd62ed4111cc65edaba36644d..1fa42b305b7607700c984f78933f34033795d262 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
@@ -1269,7 +1270,9 @@ enum
        /*ISMACryp stuff*/
        GF_RTP_HAS_ISMACRYP = (1<<5),
        GF_RTP_ISMA_SEL_ENC = (1<<6),
-       GF_RTP_ISMA_HAS_KEY_IDX = (1<<7)
+       GF_RTP_ISMA_HAS_KEY_IDX = (1<<7),
+       
+       GF_RTP_AVC_USE_ANNEX_B = (1<<8)
 };
 
 /*
index 29204271c11d6cf1f9a223f6367645c7e24fa66d..7dc33248b27e988b6279ef3d901e3651d76aef5d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index e83ccccba70e169d4d3f83404d8505e468ce9457..748cdac3a41e6dd912a523d07b8ae7c594180553 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 2f031f29660b3ee6ae54ed596e7b28f62d615fb7..340bde4a8d2bc826973f6a8f335884a3d5465b33 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -167,7 +168,9 @@ typedef struct _camera
 /*invalidate camera to force recompute of all params*/
 void camera_invalidate(GF_Camera *cam);
 /*updates camera. user transform is only used in 2D to set global user zoom/pan/translate*/
-void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coords, Fixed horizontal_shift, Fixed viewing_distance, Fixed view_distance_offset, u32 camera_layout);
+void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coords);
+/*updates camera. user transform is only used in 2D to set global user zoom/pan/translate + stereo param*/
+void camera_update_stereo(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coords, Fixed horizontal_shift, Fixed viewing_distance, Fixed viewing_distance_offset, u32 camera_layout);
 /*reset to last viewport*/
 void camera_reset_viewpoint(GF_Camera *cam, Bool animate);
 /*move camera to given vp*/
index 5ab1422a08e74dbea85e45c2ff53279a72543dd8..afee21fed0011ba57fd4b5d76ee81a414370800d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Rendering sub-project
@@ -476,11 +477,11 @@ struct __tag_compositor
 
        Fixed depth_gl_scale, depth_gl_strips_filter;
        u32 depth_gl_type;
+       Fixed interoccular_distance;
        /*increase/decrease the standard interoccular offset by the specified distance in cm*/
        Fixed interoccular_offset;
-       /*increase/decrease the view distance by the specified distance in cm*/
-       Fixed view_distance_offset;
-
+       /*specifies distance the camera focal point and the screen plane : <0 is behind the screen, >0 is in front*/
+       Fixed focus_distance;
 #endif
        
        u32 networks_time;
index 9244b1e337c6dfeeb60dc87095fee0d67c60f3d3..40d288230f3574ec4d8eb09afd225ec69e88f6aa 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Crypto Tools sub-project
index 9949d07cbd06bc8664398e97e1811ef6007996ce..4e32c98d2d977b3f800870fc11e88f9b880584f9 100644 (file)
@@ -2,11 +2,12 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Walid B.H - Jean Le Feuvre
- *    Copyright (c)2006-200X ENST - All rights reserved
+ *                     Copyright (c) Telecom ParisTech 2000-2012
+ *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG2-TS sub-project
  *
- *  GPAC is gf_free software; you can redistribute it and/or modify
+ *  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 gf_free Software Foundation; either version 2, or (at your option)
  *  any later version.
index e02a7ee60e05b3e1c77db4fd37c2a9fa479565c6..84feae3b64893940c503eddf047ba21e0a847448 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index 4950165f07cbc820d67e8cd4f4f1da1fd9a570fb..151cf0bee667511b1b8b6382dedadad086e53c5d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -34,10 +35,17 @@ extern "C" {
 #ifndef GPAC_DISABLE_ISOM
 
 
-//the default size is 64, cause we need to handle large boxes...
+/*the default size is 64, cause we need to handle large boxes...
+
+the other_boxes container is by default NOT created. When parsing a box and adding 
+a sub-box with gf_isom_box_add_default, the list is created.
+This list is destroyed befaore calling the final box destructor
+This list is automatically taken into account during size() and write() functions
+*/
 #define GF_ISOM_BOX                    \
        u32 type;                       \
        u64 size;                       \
+       GF_List *other_boxes;   \
 
 #define GF_ISOM_FULL_BOX               \
        GF_ISOM_BOX                     \
@@ -47,6 +55,7 @@ extern "C" {
 #define GF_ISOM_UUID_BOX       \
        GF_ISOM_BOX                     \
        u8 uuid[16];            \
+       u32 internal_4cc;               \
 
 typedef struct
 {
@@ -63,6 +72,13 @@ typedef struct
        GF_ISOM_UUID_BOX
 } GF_UUIDBox;
 
+
+#define ISOM_DECL_BOX_ALLOC(__TYPE, __4cc)     __TYPE *tmp; \
+       GF_SAFEALLOC(tmp, __TYPE);      \
+       if (tmp==NULL) return NULL;     \
+       tmp->type = __4cc;
+
+
 /*constructor*/
 GF_Box *gf_isom_box_new(u32 boxType);
 
@@ -71,21 +87,26 @@ GF_Err gf_isom_box_read(GF_Box *ptr, GF_BitStream *bs);
 void gf_isom_box_del(GF_Box *ptr);
 GF_Err gf_isom_box_size(GF_Box *ptr);
 
+GF_Err gf_isom_clone_box(GF_Box *src, GF_Box **dst);
+
 GF_Err gf_isom_parse_box(GF_Box **outBox, GF_BitStream *bs);
 GF_Err gf_isom_read_box_list(GF_Box *s, GF_BitStream *bs, GF_Err (*add_box)(GF_Box *par, GF_Box *b));
 GF_Err gf_isom_read_box_list_ex(GF_Box *parent, GF_BitStream *bs, GF_Err (*add_box)(GF_Box *par, GF_Box *b), u32 parent_type);
+GF_Err gf_isom_box_add_default(GF_Box *a, GF_Box *subbox);
+
+#define gf_isom_full_box_init(__pre)
+
+//void gf_isom_full_box_init(GF_Box *ptr);
 
 GF_Err gf_isom_box_get_size(GF_Box *ptr);
 GF_Err gf_isom_full_box_get_size(GF_Box *ptr);
 GF_Err gf_isom_box_write_header(GF_Box *ptr, GF_BitStream *bs);
 GF_Err gf_isom_full_box_read(GF_Box *ptr, GF_BitStream *bs);
 GF_Err gf_isom_full_box_write(GF_Box *s, GF_BitStream *bs);
-void gf_isom_full_box_init(GF_Box *ptr);
-void gf_isom_box_array_del(GF_List *boxList);
+void gf_isom_box_array_del(GF_List *other_boxes);
 GF_Err gf_isom_box_array_write(GF_Box *parent, GF_List *list, GF_BitStream *bs);
 GF_Err gf_isom_box_array_size(GF_Box *parent, GF_List *list);
 
-
 enum
 {
        GF_ISOM_BOX_TYPE_CO64   = GF_4CC( 'c', 'o', '6', '4' ),
@@ -129,13 +150,19 @@ enum
        GF_ISOM_BOX_TYPE_UDTA   = GF_4CC( 'u', 'd', 't', 'a' ),
        GF_ISOM_BOX_TYPE_VMHD   = GF_4CC( 'v', 'm', 'h', 'd' ),
        GF_ISOM_BOX_TYPE_FTYP   = GF_4CC( 'f', 't', 'y', 'p' ),
-       GF_ISOM_BOX_TYPE_FADB   = GF_4CC( 'p', 'a', 'd', 'b' ),
+       GF_ISOM_BOX_TYPE_PADB   = GF_4CC( 'p', 'a', 'd', 'b' ),
        GF_ISOM_BOX_TYPE_PDIN   = GF_4CC( 'p', 'd', 'i', 'n' ),
        GF_ISOM_BOX_TYPE_SDTP   = GF_4CC( 's', 'd', 't', 'p' ),
+       GF_ISOM_BOX_TYPE_CSLG   = GF_4CC( 'c', 's', 'l', 'g' ),
 
        GF_ISOM_BOX_TYPE_SBGP   = GF_4CC( 's', 'b', 'g', 'p' ),
        GF_ISOM_BOX_TYPE_SGPD   = GF_4CC( 's', 'g', 'p', 'd' ),
+       GF_ISOM_BOX_TYPE_SAIZ   = GF_4CC( 's', 'a', 'i', 'z' ),
+       GF_ISOM_BOX_TYPE_SAIO   = GF_4CC( 's', 'a', 'i', 'o' ),
+       GF_ISOM_BOX_TYPE_MFRA   = GF_4CC( 'm', 'f', 'r', 'a' ),
 
+       GF_ISOM_BOX_TYPE_PSSH   = GF_4CC( 'p', 's', 's', 'h' ),
+       GF_ISOM_BOX_TYPE_TENC   = GF_4CC( 't', 'e', 'n', 'c' ),
 
 #ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
        /*Movie Fragments*/
@@ -163,6 +190,7 @@ enum
        GF_ISOM_BOX_TYPE_MP4A   = GF_4CC( 'm', 'p', '4', 'a' ),
        GF_ISOM_BOX_TYPE_MP4V   = GF_4CC( 'm', 'p', '4', 'v' ),
 
+
        /*AVC / H264 extension*/
        GF_ISOM_BOX_TYPE_AVCC   = GF_4CC( 'a', 'v', 'c', 'C' ),
        GF_ISOM_BOX_TYPE_BTRT   = GF_4CC( 'b', 't', 'r', 't' ),
@@ -260,6 +288,14 @@ enum
        /*internal type for track references*/
        GF_ISOM_BOX_TYPE_REFT   = GF_4CC( 'R', 'E', 'F', 'T' ),
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /* Adobe extensions */
+       GF_ISOM_BOX_TYPE_ABST   = GF_4CC( 'a', 'b', 's', 't' ),
+       GF_ISOM_BOX_TYPE_AFRA   = GF_4CC( 'a', 'f', 'r', 'a' ),
+       GF_ISOM_BOX_TYPE_ASRT   = GF_4CC( 'a', 's', 'r', 't' ),
+       GF_ISOM_BOX_TYPE_AFRT   = GF_4CC( 'a', 'f', 'r', 't' ),
+#endif
+
        /* Apple extensions */
 
        GF_ISOM_BOX_TYPE_ILST   = GF_4CC( 'i', 'l', 's', 't' ),
@@ -309,6 +345,8 @@ enum
 
        GF_ISOM_BOX_TYPE_AC3    = GF_4CC( 'a', 'c', '-', '3' ),
        GF_ISOM_BOX_TYPE_DAC3   = GF_4CC( 'd', 'a', 'c', '3' ),
+       GF_ISOM_BOX_TYPE_EC3    = GF_4CC( 'e', 'c', '-', '3' ),
+       GF_ISOM_BOX_TYPE_DEC3   = GF_4CC( 'd', 'e', 'c', '3' ),
 
        GF_ISOM_BOX_TYPE_SUBS   = GF_4CC( 's', 'u', 'b', 's' ),
 
@@ -326,6 +364,14 @@ enum
        GF_ISOM_BOX_TYPE_GHNT   = GF_4CC( 'g', 'h', 'n', 't' ),
        /*for compatibility with old files hinted for DSS - needs special parsing*/
        GF_ISOM_BOX_TYPE_VOID   = GF_4CC( 'V', 'O', 'I', 'D' ),
+
+
+       /*MS Smooth - these are actually UUID boxes*/
+       GF_ISOM_BOX_UUID_PSSH   = GF_4CC( 'P', 'S', 'S', 'H' ),
+       GF_ISOM_BOX_UUID_TENC   = GF_4CC( 'T', 'E', 'N', 'C' ),
+       GF_ISOM_BOX_UUID_PSEC   = GF_4CC( 'P', 'S', 'E', 'C' ),
+       GF_ISOM_BOX_UUID_TFRF   = GF_4CC( 'T', 'F', 'R', 'F' ),
+       GF_ISOM_BOX_UUID_TFXD   = GF_4CC( 'T', 'F', 'X', 'D' ),
 };
 
 
@@ -413,7 +459,7 @@ typedef struct
 {
        u32 boxType;
        u8 uuid[16];
-       GF_List *boxList;
+       GF_List *other_boxes;
 } GF_UserDataMap;
 
 typedef struct
@@ -435,8 +481,6 @@ typedef struct
        struct __tag_meta_box *meta;
        /*track boxes*/
        GF_List *trackList;
-       /*other boxes*/
-       GF_List *boxes;
 
        GF_ISOFile *mov;
 
@@ -462,7 +506,6 @@ typedef struct
 typedef struct
 {
        GF_ISOM_BOX
-       GF_List *boxList;
 } GF_TrackReferenceBox;
 
 
@@ -477,8 +520,6 @@ typedef struct
        GF_TrackReferenceBox *References;
        /*meta box if any*/
        struct __tag_meta_box *meta;
-       /*other*/
-       GF_List *boxes;
 
        GF_MovieBox *moov;
        /*private for media padding*/
@@ -491,6 +532,7 @@ typedef struct
 #ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
        u64 dts_at_seg_start;
        u32 sample_count_at_seg_start;
+       Bool first_traf_merged;
 #endif 
 } GF_TrackBox;
 
@@ -572,7 +614,6 @@ typedef struct
 typedef struct
 {
        GF_ISOM_FULL_BOX
-       GF_List *boxList;
 } GF_DataReferenceBox;
 
 typedef struct
@@ -631,7 +672,7 @@ typedef struct
 typedef struct
 {
        u32 sampleCount;
-       u32 decodingOffset;
+       s32 decodingOffset;
 } GF_DttsEntry;
 
 typedef struct
@@ -677,7 +718,7 @@ typedef struct
        GF_ISOM_UUID_BOX                                        \
        u16 dataReferenceIndex;                         \
        char reserved[ 6 ];                                     \
-       struct __tag_protect_box *protection_info;
+       GF_List *protections;
 
 /*base sample entry box (never used but for typecasting)*/
 typedef struct
@@ -685,6 +726,9 @@ typedef struct
        GF_ISOM_SAMPLE_ENTRY_FIELDS
 } GF_SampleEntryBox;
 
+void gf_isom_sample_entry_init(GF_SampleEntryBox *ptr);
+void gf_isom_sample_entry_predestroy(GF_SampleEntryBox *ptr);
+
 typedef struct
 {
        GF_ISOM_SAMPLE_ENTRY_FIELDS
@@ -766,7 +810,7 @@ typedef struct
        u16 revision;                                           \
        u32 vendor;                                                     \
        u32 temporal_quality;                           \
-       u32 spacial_quality;                            \
+       u32 spatial_quality;                            \
        u16 Width, Height;                                      \
        u32 horiz_res, vert_res;                        \
        u32 entry_data_size;                            \
@@ -789,6 +833,8 @@ void gf_isom_video_sample_entry_write(GF_VisualSampleEntryBox *ent, GF_BitStream
 void gf_isom_video_sample_entry_size(GF_VisualSampleEntryBox *ent);
 #endif
 
+void gf_isom_sample_entry_predestroy(GF_SampleEntryBox *ptr);
+
 typedef struct
 {
        GF_ISOM_BOX
@@ -899,12 +945,11 @@ typedef struct
 typedef struct
 {
        GF_ISOM_AUDIO_SAMPLE_ENTRY
+       Bool is_ec3;
        GF_AC3ConfigBox *info;
 } GF_AC3SampleEntryBox;
 
 
-
-
 typedef struct
 {
        GF_ISOM_FULL_BOX
@@ -946,7 +991,6 @@ typedef struct
 typedef struct
 {
        GF_ISOM_FULL_BOX
-       GF_List *boxList;
 } GF_SampleDescriptionBox;
 
 
@@ -1048,12 +1092,6 @@ typedef struct
 } GF_SampleDependencyTypeBox;
 
 
-typedef struct
-{
-       u32 sample_delta;
-       GF_List *SubSamples;
-} GF_SampleEntry;
-
 typedef struct
 {
        u32 subsample_size;
@@ -1062,22 +1100,41 @@ typedef struct
        u32 reserved;
 } GF_SubSampleEntry;
 
+typedef struct
+{
+       u32 sample_delta;
+       GF_List *SubSamples;
+} GF_SubSampleInfoEntry;
+
 typedef struct
 {
        GF_ISOM_FULL_BOX
        GF_List *Samples;
 } GF_SubSampleInformationBox;
  
-u32 gf_isom_sample_get_subsample_entry(GF_ISOFile *movie, u32 track, u32 sampleNumber, GF_SampleEntry **sub_sample);
+u32 gf_isom_sample_get_subsample_entry(GF_ISOFile *movie, u32 track, u32 sampleNumber, GF_SubSampleInfoEntry **sub_sample);
 #ifndef GPAC_DISABLE_ISOM_WRITE
 GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable);
 #endif
 
+/* Use to relate the composition and decoding timeline when signed composition is used*/
+typedef struct
+{
+       GF_ISOM_FULL_BOX
+
+       s32 compositionToDTSShift; 
+       s32 leastDecodeToDisplayDelta; 
+       s32 greatestDecodeToDisplayDelta;
+       s32 compositionStartTime; 
+       s32 compositionEndTime;
+} GF_CompositionToDecodeBox;
+
 typedef struct
 {
        GF_ISOM_BOX
        GF_TimeToSampleBox *TimeToSample;
        GF_CompositionOffsetBox *CompositionOffset;
+       GF_CompositionToDecodeBox *CompositionToDecode;
        GF_SyncSampleBox *SyncSample;
        GF_SampleDescriptionBox *SampleDescription;
        GF_SampleSizeBox *SampleSize;
@@ -1095,6 +1152,9 @@ typedef struct
        GF_List *sampleGroups;
        GF_List *sampleGroupsDescription;
 
+       GF_List *sai_sizes;
+       GF_List *sai_offsets;
+
        u32 MaxSamplePerChunk;
        u16 groupID;
        u16 trackPriority;
@@ -1109,7 +1169,6 @@ typedef struct __tag_media_info_box
        GF_Box *InfoHeader;
        struct __tag_data_map *dataHandler;
        u32 dataEntryIndex;
-       GF_List *boxes;
 } GF_MediaInformationBox;
 
 
@@ -1402,6 +1461,8 @@ typedef struct
        GF_ISMAKMSBox *ikms;
        GF_ISMASampleFormatBox *isfm;
        struct __oma_kms_box *okms;
+       struct __cenc_tenc_box *tenc;
+       struct __piff_tenc_box *piff_tenc;
 } GF_SchemeInformationBox;
 
 typedef struct __tag_protect_box
@@ -1436,7 +1497,6 @@ typedef struct __tag_meta_box
        GF_ItemProtectionBox *protections;
        GF_ItemInfoBox *item_infos;
        GF_IPMPControlBox *IPMP_control;
-       GF_List *other_boxes;
 } GF_MetaBox;
 
 
@@ -1502,7 +1562,8 @@ enum
        GF_ISOM_TRAF_SAMPLE_DUR =       0x08,
        GF_ISOM_TRAF_SAMPLE_SIZE        =       0x10,
        GF_ISOM_TRAF_SAMPLE_FLAGS       =       0x20,
-       GF_ISOM_TRAF_DUR_EMPTY  =       0x10000
+       GF_ISOM_TRAF_DUR_EMPTY  =       0x10000,
+       GF_ISOM_MOOF_BASE_OFFSET        =       0x20000,
 };
 
 typedef struct
@@ -1539,6 +1600,11 @@ typedef struct
        GF_List *sampleGroups;
        GF_List *sampleGroupsDescription;
 
+       GF_List *sai_sizes;
+       GF_List *sai_offsets;
+
+       struct __piff_sample_enc_box *piff_sample_encryption;
+
        /*when data caching is on*/
        u32 DataCache;
     GF_TFBaseMediaDecodeTimeBox *tfdt;
@@ -1628,9 +1694,9 @@ typedef struct
 typedef struct
 {
        GF_ISOM_BOX
+       GF_List *hints;
        /*contains GF_SDPBox if in track, GF_RTPBox if in movie*/
        GF_Box *SDP;
-       GF_List *boxList;
 } GF_HintTrackInfoBox;
 
 typedef struct
@@ -1788,8 +1854,6 @@ typedef struct
 typedef struct
 {
        GF_ISOM_BOX
-       GF_List *dataRates;
-       GF_List *boxList;
 } GF_HintInfoBox;
 
 /*Apple extension*/
@@ -1811,7 +1875,6 @@ typedef struct
 typedef struct
 {
        GF_ISOM_BOX
-       GF_List *tags;
 } GF_ItemListBox;
 
 /*OMA (P)DCF extensions*/
@@ -1825,7 +1888,6 @@ typedef struct
        char *RightsIssuerURL;
        char *TextualHeaders;
        u32 TextualHeadersLen;
-       GF_List *ExtendedHeaders;
 } GF_OMADRMCommonHeaderBox;
 
 typedef struct
@@ -1840,7 +1902,6 @@ typedef struct
 typedef struct
 {
        GF_ISOM_BOX
-       GF_List *boxes;
 } GF_OMADRMMutableInformationBox;
 
 typedef struct
@@ -1896,6 +1957,96 @@ typedef struct __pcrInfo_box
        u64 *pcr_values;
 } GF_PcrInfoBox;
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+
+/*Adobe specific boxes*/
+typedef struct
+{
+       u64 time;
+       u64 offset;
+} GF_AfraEntry;
+
+typedef struct
+{
+       u64 time;
+       u32 segment;
+       u32 fragment;
+       u64 afra_offset;
+       u64 offset_from_afra;
+} GF_GlobalAfraEntry;
+
+typedef struct __adobe_frag_random_access_box
+{
+       GF_ISOM_FULL_BOX
+       Bool long_ids;
+       Bool long_offsets;
+       Bool global_entries;
+       u8 reserved;
+       u32 time_scale;
+       u32 entry_count;
+       GF_List *local_access_entries;
+       u32 global_entry_count;
+       GF_List *global_access_entries;
+} GF_AdobeFragRandomAccessBox;
+
+typedef struct __adobe_bootstrap_info_box
+{
+       GF_ISOM_FULL_BOX
+       u32 bootstrapinfo_version;
+       u8 profile;
+       Bool live;
+       Bool update;
+       u8 reserved;
+       u32 time_scale;
+       u64 current_media_time;
+       u64 smpte_time_code_offset;
+       char *movie_identifier;
+       u8 server_entry_count;
+       GF_List *server_entry_table;
+       u8 quality_entry_count;
+       GF_List *quality_entry_table;
+       char *drm_data;
+       char *meta_data;
+       u8 segment_run_table_count;
+       GF_List *segment_run_table_entries;
+       u8 fragment_run_table_count;
+       GF_List *fragment_run_table_entries;
+} GF_AdobeBootstrapInfoBox;
+
+typedef struct
+{
+       u32 first_segment;
+       u32 fragment_per_segment;
+} GF_AdobeSegmentRunEntry;
+
+typedef struct __adobe_segment_run_table_box
+{
+       GF_ISOM_FULL_BOX
+       u8 quality_entry_count;
+       GF_List *quality_segment_url_modifiers;
+       u32 segment_run_entry_count;
+       GF_List *segment_run_entry_table;
+} GF_AdobeSegmentRunTableBox;
+
+typedef struct
+{
+       u32 first_fragment;
+       u64 first_fragment_timestamp;
+       u32 fragment_duration;
+       u8 discontinuity_indicator;
+} GF_AdobeFragmentRunEntry;
+
+typedef struct __adobe_fragment_run_table_box
+{
+       GF_ISOM_FULL_BOX
+       u32 timescale;
+       u8 quality_entry_count;
+       GF_List *quality_segment_url_modifiers;
+       u32 fragment_run_entry_count;
+       GF_List *fragment_run_entry_table;
+} GF_AdobeFragmentRunTableBox;
+
+#endif /*GPAC_DISABLE_ISOM_ADOBE*/
 
 
 /***********************************************************
@@ -1948,13 +2099,140 @@ typedef struct
 } GF_RollRecoveryEntry;
 
 
+typedef struct
+{
+       GF_ISOM_FULL_BOX
+
+       u32 aux_info_type;
+       u32 aux_info_type_parameter;
+
+       u8 default_sample_info_size; 
+       u32 sample_count; 
+       u8 *sample_info_size;
+} GF_SampleAuxiliaryInfoSizeBox;
+
+typedef struct
+{
+       GF_ISOM_FULL_BOX
+
+       u32 aux_info_type;
+       u32 aux_info_type_parameter;
+
+       u8 default_sample_info_size; 
+       u32 entry_count;  //1 or stco / trun count
+       u32 *offsets;
+       u64 *offsets_large;
+
+       u64 single_offset;
+} GF_SampleAuxiliaryInfoOffsetBox;
+
+/* 
+               CENC stuff
+*/
+
+/*CENCSampleEncryptionGroupEntry - 'seig' type*/
+typedef struct
+{
+       u32 IsEncrypted;
+       u8 IV_size; 
+       bin128 KID;
+} GF_CENCSampleEncryptionGroupEntry;
+
+typedef struct
+{
+       GF_ISOM_FULL_BOX
+
+       bin128 SystemID;
+       u32 KID_count;
+       bin128 *KIDs;
+       u32 private_data_size;
+       u8 *private_data;
+} GF_ProtectionSystemHeaderBox;
+
+typedef struct __cenc_tenc_box
+{
+       GF_ISOM_FULL_BOX
+
+       u32 IsEncrypted;
+       u8 IV_size; 
+       bin128 KID;
+} GF_TrackEncryptionBox;
+
+typedef struct __piff_tenc_box
+{
+       GF_ISOM_UUID_BOX
+       u8 version;
+       u32 flags;              
+
+       u32 AlgorithmID;
+       u8 IV_size; 
+       bin128 KID;
+} GF_PIFFTrackEncryptionBox;
+
+typedef struct
+{
+       GF_ISOM_UUID_BOX
+       u8 version;
+       u32 flags;              
+
+       bin128 SystemID;
+       u32 private_data_size;
+       u8 *private_data;
+} GF_PIFFProtectionSystemHeaderBox;
+
+
+typedef struct 
+{
+       u32 bytes_clear_data;
+       u32 bytes_encrypted_data;
+} GF_CENCSubSampleEntry;
+
+typedef struct __cenc_sample_info
+{
+       /*set to 1 if keyID, IV_size and algo_id are NOT the default vamlues for the track*/
+       Bool is_alt_info;
+       bin128 keyID;
+       /*can be 0, 64 or 128 bits - if 64, bytes 0-7 are used and 8-15 are 0-padded*/
+       bin128 IV;
+       u32 algo_id;
+       u16 IV_size;
+    u16 subsample_count;
+       GF_CENCSubSampleEntry *subsamples;
+} GF_CENCSampleInfo;
+
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
+GF_CENCSampleInfo *gf_isom_cenc_get_sample(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u32 sample_number);
+void gf_isom_cenc_sample_del(GF_CENCSampleInfo *samp);
+#endif
+
+
+typedef struct __piff_sample_enc_box
+{
+       GF_ISOM_UUID_BOX
+       u8 version;
+       u32 flags;              
+
+       u32 AlgorithmID;
+       u8 IV_size;
+       bin128 KID;
+
+       u32 sample_count;
+       u32 cenc_data_size;
+       char *cenc_data;
+
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
+       /*pointer to container traf*/
+       GF_TrackFragmentBox *traf;
+#endif
+} GF_PIFFSampleEncryptionBox;
+
 /*
                Data Map (media storage) stuff
 */
 
 /*regular file IO*/
 #define GF_ISOM_DATA_FILE                      0x01
-/*File Mapaing object, read-only mode on complete files (no download)*/
+/*File Maping object, read-only mode on complete files (no download)*/
 #define GF_ISOM_DATA_FILE_MAPPING              0x02
 /*External file object. Needs implementation*/
 #define GF_ISOM_DATA_FILE_EXTERN               0x03
@@ -1992,6 +2270,7 @@ typedef struct
 {
        GF_ISOM_BASE_DATA_HANDLER
        FILE *stream;
+       Bool is_stdout;
        Bool last_acces_was_read;
 #ifndef GPAC_DISABLE_ISOM_WRITE
        char *temp_file;
@@ -2101,7 +2380,6 @@ struct __tag_isom {
 
 #ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
        u32 FragmentsFlags, NextMoofNumber;
-       Bool first_moof_merged;
        /*active fragment*/
        GF_MovieFragmentBox *moof;
        /*in WRITE mode, this is the current MDAT where data is written*/
@@ -2290,6 +2568,7 @@ GF_Err hnti_AddBox(GF_HintTrackInfoBox *hnti, GF_Box *a);
 GF_Err udta_AddBox(GF_UserDataBox *ptr, GF_Box *a);
 GF_Err edts_AddBox(GF_Box *s, GF_Box *a);
 GF_Err stdp_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a);
 GF_Err sdtp_Read(GF_Box *s, GF_BitStream *bs);
 GF_Err dinf_AddBox(GF_Box *s, GF_Box *a);
 GF_Err minf_AddBox(GF_Box *s, GF_Box *a);
@@ -2476,6 +2755,13 @@ struct _3gpp_text_sample
 GF_TextSample *gf_isom_parse_texte_sample(GF_BitStream *bs);
 GF_TextSample *gf_isom_parse_texte_sample_from_data(char *data, u32 dataLength);
 
+struct _generic_subtitle_sample
+{
+       char *text;
+       u32 len;
+};
+GF_GenericSubtitleSample *gf_isom_parse_generic_subtitle_sample(GF_BitStream *bs);
+GF_GenericSubtitleSample *gf_isom_parse_generic_subtitle_sample_from_data(char *data, u32 dataLength);
 
 
 /*
@@ -3136,6 +3422,32 @@ GF_Err iKMS_Size(GF_Box *s);
 GF_Err iSFM_Size(GF_Box *s);
 #endif
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+/* Adobe extensions */
+void abst_del(GF_Box *s);
+GF_Err abst_Read(GF_Box *s, GF_BitStream *bs);
+GF_Box *abst_New();
+void afra_del(GF_Box *s);
+GF_Err afra_Read(GF_Box *s, GF_BitStream *bs);
+GF_Box *afra_New();
+void asrt_del(GF_Box *s);
+GF_Err asrt_Read(GF_Box *s, GF_BitStream *bs);
+GF_Box *asrt_New();
+void afrt_del(GF_Box *s);
+GF_Err afrt_Read(GF_Box *s, GF_BitStream *bs);
+GF_Box *afrt_New();
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err abst_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err abst_Size(GF_Box *s);
+GF_Err afra_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err afra_Size(GF_Box *s);
+GF_Err asrt_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err asrt_Size(GF_Box *s);
+GF_Err afrt_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err afrt_Size(GF_Box *s);
+#endif
+#endif /*GPAC_DISABLE_ISOM_ADOBE*/
+
 /* Apple extensions */
 void ilst_del(GF_Box *s);
 void ListItem_del(GF_Box *s);
@@ -3155,6 +3467,7 @@ GF_Err ListItem_Size(GF_Box *s);
 GF_Err data_Size(GF_Box *s);
 #endif
 
+GF_Err gf_box_dump(void *ptr, FILE * trace);
 
 GF_Err gb_box_array_dump(GF_List *list, FILE * trace);
 GF_Err reftype_dump(GF_Box *a, FILE * trace);
@@ -3288,6 +3601,14 @@ GF_Err frma_dump(GF_Box *a, FILE * trace);
 GF_Err schm_dump(GF_Box *a, FILE * trace);
 GF_Err schi_dump(GF_Box *a, FILE * trace);
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+/*Adobe extensions*/
+GF_Err abst_dump(GF_Box *a, FILE * trace);
+GF_Err afra_dump(GF_Box *a, FILE * trace);
+GF_Err asrt_dump(GF_Box *a, FILE * trace);
+GF_Err afrt_dump(GF_Box *a, FILE * trace);
+#endif
+
 /*Apple extensions*/
 GF_Err ilst_dump(GF_Box *a, FILE * trace);
 GF_Err ListItem_dump(GF_Box *a, FILE * trace);
@@ -3388,14 +3709,14 @@ GF_Err diST_Size(GF_Box *s);
 GF_Err diST_dump(GF_Box *a, FILE * trace);
 
 
-GF_Box *ac3_New();
+GF_Box *ac3_New(u32 boxType);
 void ac3_del(GF_Box *s);
 GF_Err ac3_Read(GF_Box *s, GF_BitStream *bs);
 GF_Err ac3_Write(GF_Box *s, GF_BitStream *bs);
 GF_Err ac3_Size(GF_Box *s);
 GF_Err ac3_dump(GF_Box *a, FILE * trace);
 
-GF_Box *dac3_New();
+GF_Box *dac3_New(u32 boxType);
 void dac3_del(GF_Box *s);
 GF_Err dac3_Read(GF_Box *s, GF_BitStream *bs);
 GF_Err dac3_Write(GF_Box *s, GF_BitStream *bs);
@@ -3468,6 +3789,63 @@ GF_Err sgpd_Size(GF_Box *s);
 GF_Err sgpd_Read(GF_Box *s, GF_BitStream *bs);
 GF_Err sgpd_dump(GF_Box *a, FILE * trace);
 
+GF_Box *saiz_New();
+void saiz_del(GF_Box *);
+GF_Err saiz_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err saiz_Size(GF_Box *s);
+GF_Err saiz_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err saiz_dump(GF_Box *a, FILE * trace);
+
+GF_Box *saio_New();
+void saio_del(GF_Box *);
+GF_Err saio_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err saio_Size(GF_Box *s);
+GF_Err saio_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err saio_dump(GF_Box *a, FILE * trace);
+
+GF_Box *pssh_New();
+void pssh_del(GF_Box *);
+GF_Err pssh_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err pssh_Size(GF_Box *s);
+GF_Err pssh_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err pssh_dump(GF_Box *a, FILE * trace);
+
+GF_Box *tenc_New();
+void tenc_del(GF_Box *);
+GF_Err tenc_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err tenc_Size(GF_Box *s);
+GF_Err tenc_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err tenc_dump(GF_Box *a, FILE * trace);
+
+GF_Box *piff_tenc_New();
+void piff_tenc_del(GF_Box *);
+GF_Err piff_tenc_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err piff_tenc_Size(GF_Box *s);
+GF_Err piff_tenc_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err piff_tenc_dump(GF_Box *a, FILE * trace);
+
+GF_Box *piff_psec_New();
+void piff_psec_del(GF_Box *);
+GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err piff_psec_Size(GF_Box *s);
+GF_Err piff_psec_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err piff_psec_dump(GF_Box *a, FILE * trace);
+
+GF_Box *piff_pssh_New();
+void piff_pssh_del(GF_Box *);
+GF_Err piff_pssh_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err piff_pssh_Size(GF_Box *s);
+GF_Err piff_pssh_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err piff_pssh_dump(GF_Box *a, FILE * trace);
+
+
+GF_Box *cslg_New();
+void cslg_del(GF_Box *);
+GF_Err cslg_Write(GF_Box *s, GF_BitStream *bs);
+GF_Err cslg_Size(GF_Box *s);
+GF_Err cslg_Read(GF_Box *s, GF_BitStream *bs);
+GF_Err cslg_dump(GF_Box *a, FILE * trace);
+
 #endif /*GPAC_DISABLE_ISOM*/
 
 #ifdef __cplusplus
index 83ed903120e7c4c5291dcc7985bc56b40b51a0a7..c8094ea7fd1bbaae0ba0f1b30efc2147be162c40 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / LASeR codec sub-project
index 320e4013d41e4eef4a887aeb53db090ce29a6d7f..1f85eb41d7e1fc498ab5313c152b93f4be3e80a9 100644 (file)
@@ -1,7 +1,7 @@
 /**
  *                     GPAC - Multimedia Framework C SDK
  *
- *                                     Authors: Pierre Souchay
+ *                                     Authors: Pierre Souchay - Jean Le Feuvre
  *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
@@ -86,7 +86,7 @@ typedef enum e_playlistElementType  { TYPE_PLAYLIST, TYPE_STREAM, TYPE_UNKNOWN}
 typedef struct s_playlistElement {
     int durationInfo;
     u64 byteRangeStart, byteRangeEnd;
-    int bandwidth;
+    int bandwidth, width, height;
     char * title;
        char * codecs;
     char * url;
index 956426d621d4795e5e8d6e794041bd32633ff027..4ff8ab12e72e21171046e9fcf1042c707b38fa53 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
@@ -66,6 +67,8 @@ enum
        AVC_SUBSPS_PARSED = 1<<2,
        /*SUB-SPS has been declared to the upper layer*/
        AVC_SUBSPS_DECLARED = 1<<3,
+       /*SPS extension has been parsed*/
+       AVC_SPS_EXT_DECLARED = 1<<4,
 };
 
 typedef struct 
@@ -104,6 +107,9 @@ typedef struct
        s32 delta_pic_order_always_zero_flag;
        s32 offset_for_non_ref_pic, offset_for_top_to_bottom_field;
        Bool frame_mbs_only_flag;
+       u8 chroma_format;
+       u8 luma_bit_depth_m8;
+       u8 chroma_bit_depth_m8;
 
        s16 offset_for_ref_frame[256];
 
@@ -188,12 +194,26 @@ typedef struct
        Bool is_svc;
 } AVCState;
 
+typedef struct
+{
+       u32 NALUnitHeader;
+       u8 track_ref_index;
+       s8 sample_offset;
+       u32 data_offset;
+       u32 data_length;
+} SVC_Extractor;
+
+
 /*return sps ID or -1 if error*/
 s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos);
 /*return pps ID or -1 if error*/
 s32 AVC_ReadPictParamSet(char *pps_data, u32 pps_size, AVCState *avc);
-/*is slice a RAP*/
+/*return sps ID or -1 if error*/
+s32 AVC_ReadSeqParamSetExtId(char *spse_data, u32 spse_size);
+/*is slice an IDR*/
 Bool AVC_SliceIsIDR(AVCState *avc);
+/*is slice containing intra MB only*/
+Bool AVC_SliceIsIntra(AVCState *avc);
 /*parses NALU, updates avc state and returns:
        1 if NALU part of new frame
        0 if NALU part of prev frame
@@ -239,5 +259,17 @@ void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, cha
 
 #endif
 
+
+typedef enum
+{
+       GF_DASH_TEMPLATE_SEGMENT = 0,
+       GF_DASH_TEMPLATE_INITIALIZATION,
+       GF_DASH_TEMPLATE_TEMPLATE,
+       GF_DASH_TEMPLATE_INITIALIZATION_TEMPLATE,
+       GF_DASH_TEMPLATE_REPINDEX,
+} GF_DashTemplateSegmentType;
+
+GF_Err gf_media_mpd_format_segment_name(GF_DashTemplateSegmentType seg_type, Bool is_bs_switching, char *segment_name, const char *output_file_name, const char *rep_id, const char *seg_rad_name, const char *seg_ext, u64 start_time, u32 bandwidth, u32 segment_number);
+
 #endif         /*_GF_MEDIA_DEV_H_*/
 
index 3bed6516948786fd59fb4de9a810f5b765bdf2e7..7c35e0355d570f3430b1bebfe2236104d9dfe575 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 2a41d3b59d553e2348c0e39856149a62d813c789..dfee3513e2730c1334e58cbe1973e15d7250f87e 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Cyril Concolato
- *                     Copyright (c) Telecom ParisTech 2010-
+ *                     Authors: Jean Le Feuvre - Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / 3GPP/MPEG Media Presentation Description input module
@@ -54,10 +54,9 @@ typedef struct
        u32 dummy;
 } GF_MPD_Subset;
 
-/*TODO*/
 typedef struct 
 {
-       u32 start_time;
+       u64 start_time;
        u32 duration; /*MANDATORY*/
        u32 repeat_count;
 } GF_MPD_SegmentTimelineEntry;
@@ -94,7 +93,7 @@ typedef struct
 
 #define GF_MPD_SEGMENT_BASE    \
        u32 timescale;  \
-       u32 presentation_time_offset;   \
+       u64 presentation_time_offset;   \
        u32 index_range;        \
        Bool index_range_exact; \
        GF_MPD_URL *initialization_segment;     \
@@ -132,6 +131,9 @@ typedef struct
        GF_MPD_MULTIPLE_SEGMENT_BASE    
        /*list of segments - can be NULL if no segment*/
        GF_List *segment_URLs;
+
+       char *xlink_href;
+       Bool xlink_actuate_on_load;
 } GF_MPD_SegmentList;
 
 typedef struct 
@@ -187,6 +189,12 @@ typedef struct {
        char *content_components;
 } GF_MPD_SubRepresentation;
 
+typedef struct
+{
+       Bool disabled;
+       char *cached_init_segment_url;
+       u64 init_start_range, init_end_range;
+} GF_DASH_RepresentationPlayback;
 
 typedef struct {
        GF_MPD_COMMON_ATTRIBUTES_ELEMENTS
@@ -205,8 +213,7 @@ typedef struct {
        GF_List *sub_representations;
 
        /*GPAC playback implementation*/
-       Bool disabled;
-
+       GF_DASH_RepresentationPlayback playback;
 } GF_MPD_Representation;
 
 
@@ -247,6 +254,8 @@ typedef struct
 
        GF_List *representations;
 
+       char *xlink_href;
+       Bool xlink_actuate_on_load;
 } GF_MPD_AdaptationSet;
 
 
@@ -264,6 +273,8 @@ typedef struct
 
        GF_List *adaptation_sets;
        GF_List *subsets;
+       char *xlink_href;
+       Bool xlink_actuate_on_load;
 } GF_MPD_Period;
 
 typedef struct 
@@ -307,14 +318,17 @@ typedef struct {
        GF_List *metrics;
        /*list of GF_MPD_Period */
     GF_List *periods;
+
+       /*set during parsing*/
+       const char *xml_namespace;
 } GF_MPD;
 
 GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd, const char *base_url);
 
 GF_MPD *gf_mpd_new();
 void gf_mpd_del(GF_MPD *mpd);
-/*frees a SegmentURL*/
-void gf_mpd_segment_url_free(void *_item);
+/*frees a GF_MPD_SegmentURL structure (type-casted to void *)*/
+void gf_mpd_segment_url_free(void *ptr);
 
 typedef struct _gf_file_get GF_FileDownload;
 struct _gf_file_get
index 8ff4046f3cf83551ab6c33e69a5560abba15e555..15c7f0ed0d1a72675e808abb658b487bac25e3d5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 43b31c97e0166009e51c3691384b5f0fe4dfaf53..80c0f8cbeced90b000f2e600c38cfc13bfb0d6ff 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index d3718829fbf96af67f3b4abd5a5b2effd9bdb8d6..5c793a856191bd15328ece220c9a952a0dfb3928 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index f28e0ab34b65b33058b07b501458e88e744445ce..756347be2a9405bfe4e235a6e79f97438bf14bdf 100644 (file)
 #define JS_VERSION 170
 #endif
 
+
+typedef struct
+{
+       JSClass _class;
+       JSObject *_proto;
+} GF_JSClass;
+
+
+
 /*new APIs*/
 #if (JS_VERSION>=185)
 
+#ifdef USE_FFDEV_16
+#define USE_FFDEV_15
+#endif
+
+#ifdef USE_FFDEV_15
+#define JSVAL_IS_OBJECT(__v) JSVAL_IS_OBJECT_OR_NULL_IMPL(JSVAL_TO_IMPL(__v))
+#define USE_FFDEV_14
+#endif
+
+#ifdef USE_FFDEV_14
+#define USE_FFDEV_12
+
+#define JS_FinalizeStub        NULL
+#ifdef USE_FFDEV_16
+#define JS_NEW_OBJ_FOR_CONS(__c, __classp, __args)     JS_NewObjectForConstructor(__c, &(__classp)->_class, __args)
+#else
+#define JS_NEW_OBJ_FOR_CONS(__c, __classp, __args)     JS_NewObjectForConstructor(__c, __classp, __args)
+#endif
+
+#else
+#define JS_NEW_OBJ_FOR_CONS(__c, __classp, __args)     JS_NewObjectForConstructor(__c, __args)
+#endif
 
 #ifdef USE_FFDEV_12
 typedef unsigned uintN;
@@ -53,8 +84,28 @@ typedef double jsdouble;
 
 #define JS_NewDouble(c, v)     v
 #define JS_PropertyStub_forSetter JS_StrictPropertyStub
-#define SMJS_PROP_SETTER jsid id, JSBool strict
-#define SMJS_PROP_GETTER jsid id
+
+#ifdef USE_FFDEV_15
+
+#define SMJS_DECL_FUNC_PROP_SET(func_name) JSBool func_name(JSContext *c, JSHandleObject __hobj, JSHandleId __hid, JSBool strict, jsval *vp) 
+#define SMJS_FUNC_PROP_SET(func_name) SMJS_DECL_FUNC_PROP_SET(func_name) { JSObject *obj = *(__hobj._); jsid id = *(__hid._);
+#define SMJS_DECL_FUNC_PROP_GET(func_name) JSBool func_name(JSContext *c, JSHandleObject __hobj, JSHandleId __hid, jsval *vp)
+#define SMJS_FUNC_PROP_GET(func_name) SMJS_DECL_FUNC_PROP_GET( func_name ) { JSObject *obj = *(__hobj._); jsid id = *(__hid._);
+#define SMJS_CALL_PROP_STUB() JS_PropertyStub(c, __hobj, __hid, vp)
+#define DECL_FINALIZE(func_name) void func_name(JSFreeOp *fop, JSObject *obj) { void *c = NULL;
+
+#else
+
+#define SMJS_DECL_FUNC_PROP_SET(func_name) JSBool func_name(JSContext *c, JSObject *obj, jsid id, JSBool strict, jsval *vp)
+#define SMJS_FUNC_PROP_SET(func_name) SMJS_DECL_FUNC_PROP_SET( func_name) {
+#define SMJS_DECL_FUNC_PROP_GET(func_name) JSBool func_name(JSContext *c, JSObject *obj, jsid id, jsval *vp) 
+#define SMJS_FUNC_PROP_GET(func_name) SMJS_DECL_FUNC_PROP_GET(func_name) { 
+#define SMJS_CALL_PROP_STUB() JS_PropertyStub(c, obj, id, vp)
+#define DECL_FINALIZE(func_name) void func_name(JSContext *c, JSObject *obj) {
+
+#endif
+
+
 #define SMJS_FUNCTION_SPEC(__name, __fun, __argc) {__name, __fun, __argc, 0}
 #define SMJS_FUNCTION(__name) __name(JSContext *c, uintN argc, jsval *argsvp)
 #define SMJS_FUNCTION_EXT(__name, __ext) __name(JSContext *c, uintN argc, jsval *argsvp, __ext)
@@ -70,8 +121,8 @@ typedef double jsdouble;
 #define SMJS_FREE(__c, __str)  if (__str) JS_free(__c, __str)
 
 
-#define SMJS_OBJ_CONSTRUCTOR   \
-       JSObject *obj = JS_NewObjectForConstructor(c, argsvp);  \
+#define SMJS_OBJ_CONSTRUCTOR(__classp) \
+       JSObject *obj = JS_NEW_OBJ_FOR_CONS(c, __classp, argsvp);       \
        SMJS_SET_RVAL(OBJECT_TO_JSVAL(obj));\
 
 #define JS_GetFunctionName(_v) (JS_GetFunctionId(_v)!=NULL) ? SMJS_CHARS_FROM_STRING(c, JS_GetFunctionId(_v)) : NULL
@@ -92,8 +143,19 @@ typedef double jsdouble;
 #define SMJS_GET_PRIVATE(__ctx, __obj) JS_GetPrivate(__obj)
 #define SMJS_SET_PRIVATE(__ctx, __obj, __val)  JS_SetPrivate(__obj, __val)
 #define SMJS_GET_PARENT(__ctx, __obj)  JS_GetParent(__obj)
+
+
+#ifdef USE_FFDEV_15
+#define JS_GET_CLASS(__ctx, __obj) JS_GetClass(* __obj._)
+#else
 #define JS_GET_CLASS(__ctx, __obj) JS_GetClass(__obj)
-#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, __class, __parent)
+#endif
+
+#ifdef USE_FFDEV_16
+#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_New(__ctx, JS_GetConstructor(__ctx, (__class)->_proto), 0, NULL)
+#else
+#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, &(__class)->_class, __parent)
+#endif
 
 #else
 
@@ -104,9 +166,9 @@ typedef double jsdouble;
 #ifdef USE_FFDEV_11
 #define JS_ClearContextThread(__ctx)
 #define JS_SetContextThread(__ctx)
-#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, __class, __parent)
+#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, &(__class)->_class, __parent)
 #else
-#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, __class, 0, __parent)
+#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, &(__class)->_class, 0, __parent)
 #endif
 
 #endif
@@ -114,6 +176,13 @@ typedef double jsdouble;
 
 #else
 
+#define SMJS_DECL_FUNC_PROP_SET(func_name) JSBool func_name(JSContext *c, JSObject *obj, jsval id, jsval *vp)
+#define SMJS_FUNC_PROP_SET(func_name) SMJS_DECL_FUNC_PROP_SET(func_name) {
+#define SMJS_DECL_FUNC_PROP_GET(func_name) JSBool func_name(JSContext *c, JSObject *obj, jsval id, jsval *vp) 
+#define SMJS_FUNC_PROP_GET(func_name) SMJS_DECL_FUNC_PROP_GET( func_name) { 
+#define DECL_FINALIZE(func_name) void func_name(JSContext *c, JSObject *obj) {
+
+#define SMJS_CALL_PROP_STUB() JS_PropertyStub(c, obj, id, vp)
 #define SMJS_PROP_SETTER jsval id
 #define SMJS_PROP_GETTER jsval id
 #define JS_PropertyStub_forSetter JS_PropertyStub
@@ -122,7 +191,7 @@ typedef double jsdouble;
 #define SMJS_FUNCTION_EXT(__name, __ext) __name(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, __ext)
 #define SMJS_ARGS
 #define SMJS_OBJ       
-#define SMJS_OBJ_CONSTRUCTOR
+#define SMJS_OBJ_CONSTRUCTOR(__classp)
 #define SMJS_GET_RVAL rval
 #define SMJS_SET_RVAL(__rval) *rval = __rval
 #define SMJS_CALL_ARGS c, obj, argc, argv, rval
@@ -137,7 +206,7 @@ typedef double jsdouble;
 #define SMJS_ID_IS_INT JSVAL_IS_INT
 #define SMJS_ID_TO_INT         JSVAL_TO_INT
 
-#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, __class, 0, __parent)
+#define SMJS_CONSTRUCT_OBJECT(__ctx, __class, __parent)        JS_ConstructObject(__ctx, &(__class)->_class, 0, __parent)
 #define SMJS_GET_PRIVATE(__ctx, __obj) JS_GetPrivate(__ctx, __obj)
 #define SMJS_SET_PRIVATE(__ctx, __obj, __val)  JS_SetPrivate(__ctx, __obj, __val)
 #define SMJS_GET_PARENT(__ctx, __obj)  JS_GetParent(__ctx, __obj)
@@ -150,30 +219,39 @@ extern "C" {
 #endif
 
 #if (JS_VERSION>=185)
+#ifdef USE_FFDEV_15
+JSBool gf_sg_js_has_instance(JSContext *c, JSHandleObject obj,const jsval *val, JSBool *vp);
+#else
 JSBool gf_sg_js_has_instance(JSContext *c, JSObject *obj,const jsval *val, JSBool *vp);
+#endif
 #else
 JSBool gf_sg_js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp);
 #endif
 
 #define JS_SETUP_CLASS(the_class, cname, flag, getp, setp, fin)        \
        memset(&the_class, 0, sizeof(the_class));       \
-       the_class.name = cname; \
-       the_class.flags = flag; \
-       the_class.addProperty = JS_PropertyStub;        \
-       the_class.delProperty = JS_PropertyStub;        \
-       the_class.getProperty = getp;   \
-       the_class.setProperty = setp;   \
-       the_class.enumerate = JS_EnumerateStub; \
-       the_class.resolve = JS_ResolveStub;             \
-       the_class.convert = JS_ConvertStub;             \
-       the_class.finalize = fin;       \
-       the_class.hasInstance = gf_sg_js_has_instance;
+       the_class._class.name = cname;  \
+       the_class._class.flags = flag;  \
+       the_class._class.addProperty = JS_PropertyStub; \
+       the_class._class.delProperty = JS_PropertyStub; \
+       the_class._class.getProperty = getp;    \
+       the_class._class.setProperty = setp;    \
+       the_class._class.enumerate = JS_EnumerateStub;  \
+       the_class._class.resolve = JS_ResolveStub;              \
+       the_class._class.convert = JS_ConvertStub;              \
+       the_class._class.finalize = (JSFinalizeOp) fin; \
+       the_class._class.hasInstance = gf_sg_js_has_instance;
 
 
 #define JS_MAKE_DOUBLE(__c, __double)  DOUBLE_TO_JSVAL(JS_NewDouble(__c, __double) ) 
 
 
-JSObject *gf_sg_js_global_object(JSContext *cx, JSClass *__class);
+#define GF_JS_InstanceOf(_a, _b, __class, _d) JS_InstanceOf(_a, _b, & (__class)->_class, NULL)
+
+#define GF_JS_InitClass(cx, obj, parent_proto, clasp, constructor, nargs, ps, fs, static_ps, static_fs) \
+               (clasp)->_proto = JS_InitClass(cx, obj, parent_proto, &(clasp)->_class, constructor, nargs, ps, fs, static_ps, static_fs);
+
+JSObject *gf_sg_js_global_object(JSContext *cx, GF_JSClass *__class);
 
 #ifdef __cplusplus
 }
index 3eb9ba1ea7793dd534b979bf51c7476b3f523336..3c074a21f0d96095140d638109b88c6a61903043 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
@@ -47,6 +48,14 @@ enum
        SWF_MOVE,
 };
 
+/*display list item (one per layer only)*/
+typedef struct
+{
+       GF_Matrix2D mat;
+       GF_ColorMatrix cmat;
+       u32 depth;
+       u32 char_id;
+} DispShape;
 
 struct SWFReader
 {
@@ -159,6 +168,11 @@ struct SWFReader
        GF_List *btn_over, *btn_not_over, *btn_active, *btn_not_active;
 
        /* </BIFS conversion state> */
+
+    /* SVG conversion state */
+    FILE *svg_output;
+    /* end of SVG conversion state */
+
 };
 
 
@@ -168,6 +182,7 @@ GF_Err swf_parse_sprite(SWFReader *read);
 
 
 GF_Err swf_to_bifs_init(SWFReader *read);
+GF_Err swf_to_svg_init(SWFReader *read);
 
 
 
index bedef4847eccf4252bbfc899fd9deafc8761e4d2..7240d291c7511378088343ed3928eaefc2f5c6a1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Stream Management sub-project
@@ -429,8 +430,8 @@ GF_Err gf_term_init_scheduler(GF_Terminal *term, u32 threading_mode);
 void gf_term_stop_scheduler(GF_Terminal *term);
 void gf_term_add_codec(GF_Terminal *term, GF_Codec *codec);
 void gf_term_remove_codec(GF_Terminal *term, GF_Codec *codec);
-void gf_term_start_codec(GF_Codec *codec);
-void gf_term_stop_codec(GF_Codec *codec);
+void gf_term_start_codec(GF_Codec *codec, Bool is_resume);
+void gf_term_stop_codec(GF_Codec *codec, Bool is_pause);
 void gf_term_set_threading(GF_Terminal *term, u32 mode);
 void gf_term_set_priority(GF_Terminal *term, s32 Priority);
 
@@ -799,6 +800,9 @@ struct _generic_codec
        /*for CTS reconstruction (channels not using SL): we cannot just update timing at each frame, not precise enough 
        since we use ms and not microsec TSs*/
        u32 cur_audio_bytes, cur_video_frames;
+
+       /*signals that CB should be resized to this value once all units in CB has been consumed (codec config change)*/
+       u32 force_cb_resize;
 };
 
 GF_Codec *gf_codec_new(GF_ObjectManager *odm, GF_ESD *base_layer, s32 PL, GF_Err *e);
@@ -1048,7 +1052,7 @@ void gf_term_service_media_event_with_download(GF_ObjectManager *odm, u32 event_
 /*checks the URL and returns the ODID (MPEG-4 od://) or GF_MEDIA_EXTERNAL_ID for all regular URLs*/
 u32 gf_mo_get_od_id(MFURL *url);
 
-void gf_scene_generate_views(GF_Scene *scene, char *url);
+void gf_scene_generate_views(GF_Scene *scene, char *url, char *parent_url);
 
 GF_Err gf_codec_process_private_media(GF_Codec *codec, u32 TimeAvailable);
 
index dac6e4791f899799f5f643e0acf1e7bdf5f831de..6653f2f075efd6fdaa48a8b2fdd3e6ba3e10cf43 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Authoring Tools sub-project
@@ -88,21 +89,21 @@ typedef struct
 
 #if !defined(GPAC_DISABLE_MCRYPT) && !defined(GPAC_DISABLE_ISOM_WRITE)
 
-/*encrypts track - logs, progress: info callbacks, NULL for stdout*/
+/*encrypts track - logs, progress: info callbacks, NULL for default*/
 GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u64 done, u64 total), void *cbk);
 
-/*decrypts track - logs, progress: info callbacks, NULL for stdout*/
+/*decrypts track - logs, progress: info callbacks, NULL for default*/
 GF_Err gf_ismacryp_decrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u64 done, u64 total), void *cbk);
 
 /*decrypt a file 
 @drm_file: location of DRM data (cf MP4Box doc).
-@LogMsg: redirection for message or NULL for stdout
+@LogMsg: redirection for message or NULL for default
 */
 GF_Err gf_ismacryp_decrypt_file(GF_ISOFile *mp4file, const char *drm_file);
 
 /*Crypt a the file 
 @drm_file: location of DRM data.
-@LogMsg: redirection for message or NULL for stdout
+@LogMsg: redirection for message or NULL for default
 */
 GF_Err gf_ismacryp_crypt_file(GF_ISOFile *mp4file, const char *drm_file);
 
index 72cbdba9602454af891bd47c7315a730f6a67905..e9301f7d74c07a3b3375ba73bb86754281e79184 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC 
index 60107056b69a5425c0374ecac51f7a470c1d27a7..9c001f2b89b6e063032eef500e05298837227bf7 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -34,43 +35,6 @@ extern "C" {
 
 #include <gpac/tools.h>
 
-#ifndef GPAC_DISABLE_ISOM
-
-#include <gpac/mpeg4_odf.h>
-
-/*the isomedia file*/
-typedef struct __tag_isom GF_ISOFile;
-
-/*media sample object*/
-typedef struct
-{
-       /*data size*/
-       u32 dataLength;
-       /*data with padding if requested*/
-       char *data;
-       /*decoding time*/
-       u64 DTS;
-       /*relative offset for composition if needed*/
-       u32 CTS_Offset;
-       /*Random Access Point flag:
-        0: not random access
-        1: regular RAP, 
-        2: sample is a redundant RAP. If set when adding the sample, this will create a sample dependency entry
-       */
-       u8 IsRAP;
-} GF_ISOSample;
-
-
-/*creates a new empty sample*/
-GF_ISOSample *gf_isom_sample_new();
-
-/*delete a sample. NOTE:the buffer content will be destroyed by default.
-if you wish to keep the buffer, set dataLength to 0 in the sample 
-before deleting it
-the pointer is set to NULL after deletion*/
-void gf_isom_sample_del(GF_ISOSample **samp);
-
-
 
 /********************************************************************
                                FILE FORMAT CONSTANTS
@@ -140,7 +104,10 @@ enum
        /*ref type for Hint tracks*/
        GF_ISOM_REF_HINT                = GF_4CC( 'h', 'i', 'n', 't' ),
        /*ref type for QT Chapter tracks*/
-       GF_ISOM_REF_CHAP                = GF_4CC( 'c', 'h', 'a', 'p' )
+       GF_ISOM_REF_CHAP                = GF_4CC( 'c', 'h', 'a', 'p' ),
+       /*ref type for the SVC tracks*/
+       GF_ISOM_REF_BASE = GF_4CC( 's', 'b', 'a', 's' ),
+       GF_ISOM_REF_SCAL = GF_4CC( 's', 'c', 'a', 'l' )
 };
 
 /*Track Edition flag*/
@@ -162,6 +129,7 @@ enum
        GF_ISOM_MEDIA_HINT              = GF_4CC( 'h', 'i', 'n', 't' ),
        GF_ISOM_MEDIA_META              = GF_4CC( 'm', 'e', 't', 'a' ),
        GF_ISOM_MEDIA_TEXT              = GF_4CC( 't', 'e', 'x', 't' ),
+       GF_ISOM_MEDIA_SUBM              = GF_4CC( 's', 'u', 'b', 'm' ),
        /*subtitle code point used on ipod - same as text*/
        GF_ISOM_MEDIA_SUBT              = GF_4CC( 's', 'b', 't', 'l' ),
        GF_ISOM_MEDIA_SUBPIC    = GF_4CC( 's', 'u', 'b', 'p' ),
@@ -189,6 +157,13 @@ enum
        GF_ISOM_ISMACRYP_SCHEME = GF_4CC( 'i', 'A', 'E', 'C' )
 };
 
+/* Encryption Scheme Type in the SchemeTypeInfoBox */
+enum 
+{
+       GF_ISOM_OMADRM_SCHEME   = GF_4CC('o','d','k','m')
+};
+
+
 /*specific media sub-types - you shall make sure the media sub type is what you expect*/
 enum
 {
@@ -278,6 +253,8 @@ enum
        GF_ISOM_BRAND_AVC1 = GF_4CC('a', 'v', 'c', '1'),
        /* file complying to ISO/IEC 21000-9:2005 (MPEG-21 spec)*/
        GF_ISOM_BRAND_MP21 = GF_4CC('m', 'p', '2', '1'),
+       /*file complying to the generic ISO Media File (base specification ISO/IEC 14496-12) + support for version 1*/
+       GF_ISOM_BRAND_ISO4 =  GF_4CC( 'i', 's', 'o', '4' )
 };
 
 
@@ -294,6 +271,41 @@ enum
        GF_ISOM_PL_INLINE,
 };
 
+#ifndef GPAC_DISABLE_ISOM
+
+#include <gpac/mpeg4_odf.h>
+
+/*the isomedia file*/
+typedef struct __tag_isom GF_ISOFile;
+
+/*media sample object*/
+typedef struct
+{
+       /*data size*/
+       u32 dataLength;
+       /*data with padding if requested*/
+       char *data;
+       /*decoding time*/
+       u64 DTS;
+       /*relative offset for composition if needed*/
+       s32 CTS_Offset;
+       /*Random Access Point flag:
+        0: not random access
+        1: regular RAP, 
+        2: sample is a redundant RAP. If set when adding the sample, this will create a sample dependency entry
+       */
+       u8 IsRAP;
+} GF_ISOSample;
+
+
+/*creates a new empty sample*/
+GF_ISOSample *gf_isom_sample_new();
+
+/*delete a sample. NOTE:the buffer content will be destroyed by default.
+if you wish to keep the buffer, set dataLength to 0 in the sample 
+before deleting it
+the pointer is set to NULL after deletion*/
+void gf_isom_sample_del(GF_ISOSample **samp);
 
 /********************************************************************
                                GENERAL API FUNCTIONS
@@ -329,6 +341,11 @@ u64 gf_isom_get_file_size(GF_ISOFile *the_file);
 
 Bool gf_isom_moov_first(GF_ISOFile *movie);
 
+/*sets write cache size for files when creating them. If size is 0, writing
+only relies on the underlying OS fwrite/fgetc
+If movie is NULL, assigns the default write cache size for any new movie*/
+GF_Err gf_isom_set_output_buffering(GF_ISOFile *movie, u32 size);
+
 /********************************************************************
                                STREAMING API FUNCTIONS
 ********************************************************************/
@@ -555,8 +572,12 @@ u8 gf_isom_has_sync_points(GF_ISOFile *the_file, u32 trackNumber);
 /*returns number of sync points*/
 u32 gf_isom_get_sync_point_count(GF_ISOFile *the_file, u32 trackNumber);
 
-/*returns 1 if one sample of the track is found to have a composition time offset (DTS<CTS)*/
-Bool gf_isom_has_time_offset(GF_ISOFile *the_file, u32 trackNumber);
+/*
+returns 1 if the track uses unsigned compositionTime offsets (B-frames or similar)
+returns 2 if the track uses signed compositionTime offsets (B-frames or similar) 
+returns 0 if the track does not use compositionTime offsets (CTS == DTS) 
+*/
+u32 gf_isom_has_time_offset(GF_ISOFile *the_file, u32 trackNumber);
 
 /*returns 1 if the track has sync shadow samples*/
 Bool gf_isom_has_sync_shadows(GF_ISOFile *the_file, u32 trackNumber);
@@ -689,7 +710,7 @@ typedef struct
 
        /*video codecs only*/
        u32 temporal_quality;
-       u32 spacial_quality;
+       u32 spatial_quality;
        u16 width, height;
        u32 h_res, v_res;
        u16 depth;
@@ -827,8 +848,8 @@ GF_Err gf_isom_update_sample_reference(GF_ISOFile *the_file, u32 trackNumber, u3
 /*Remove a given sample*/
 GF_Err gf_isom_remove_sample(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber);
 
-/*changes media time scale*/
-GF_Err gf_isom_set_media_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 new_timescale);
+/*changes media time scale - if force_rescale is 1, only the media timescale is changed but media times are not updated */
+GF_Err gf_isom_set_media_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 new_timescale, Bool force_rescale);
 
 /*set the save file name of the (edited) movie. 
 If the movie is edited, the default fileName is avp_#openName)
@@ -1156,6 +1177,9 @@ GF_Err gf_isom_change_track_fragment_defaults(GF_ISOFile *movie, u32 TrackID,
 @media_segment_type: 0 if no segments, 1 if regular segment, 2 if single segment*/
 GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *the_file, u32 media_segment_type);
 
+/*sets the duration of the movie in case of movie fragments*/
+GF_Err gf_isom_set_movie_duration(GF_ISOFile *movie, u64 duration);
+
 /*starts a new movie fragment - if force_cache is set, fragment metadata will be written before
 fragment media data for all tracks*/
 GF_Err gf_isom_start_fragment(GF_ISOFile *movie, Bool moof_first);
@@ -1209,13 +1233,13 @@ Note: because of the interleaved nature of the meta/media data, the sample durat
 MUST be provided (in case of regular tracks, this was computed internally by the lib)
 *PaddingBits: padding bits for the sample, or 0
 *DegradationPriority for the sample, or 0
+*redundantCoding: indicates this is samples acts as a sync shadow point
 
 */
 
 GF_Err gf_isom_fragment_add_sample(GF_ISOFile *the_file, u32 TrackID, GF_ISOSample *sample, 
                                                                 u32 StreamDescriptionIndex, 
-                                                                u32 Duration,
-                                                                u8 PaddingBits, u16 DegradationPriority);
+                                                                u32 Duration, u8 PaddingBits, u16 DegradationPriority, Bool redundantCoding);
 
 /*appends data into last sample of track for video fragments/other media
 CANNOT be used with OD tracks*/
@@ -1223,6 +1247,11 @@ GF_Err gf_isom_fragment_append_data(GF_ISOFile *the_file, u32 TrackID, char *dat
 
 void gf_isom_reset_fragment_info(GF_ISOFile *movie);
 
+/*return the duration of the movie+fragments if known, 0 if error*/
+u64 gf_isom_get_fragmented_duration(GF_ISOFile *movie);
+/*returns the number */
+u32 gf_isom_get_fragments_count(GF_ISOFile *movie, Bool segments_only);
+
 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
 
@@ -1524,9 +1553,18 @@ GF_Err gf_isom_3gp_config_update(GF_ISOFile *the_file, u32 trackNumber, GF_3GPCo
 
 /*gets uncompressed AVC config - user is responsible for deleting it*/
 GF_AVCConfig *gf_isom_avc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex);
-/*gets uncompressed AVC config - user is responsible for deleting it*/
+/*gets uncompressed SVC config - user is responsible for deleting it*/
 GF_AVCConfig *gf_isom_svc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex);
 
+typedef enum
+{
+       GF_ISOM_AVCTYPE_NONE=0,
+       GF_ISOM_AVCTYPE_AVC_ONLY,
+       GF_ISOM_AVCTYPE_AVC_SVC,
+       GF_ISOM_AVCTYPE_SVC_ONLY,
+} GF_ISOMAVCType;
+u32 gf_isom_get_avc_svc_type(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex);
+
 #ifndef GPAC_DISABLE_ISOM_WRITE
 /*creates new AVC config*/
 GF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex);
@@ -1534,6 +1572,10 @@ GF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfi
 GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg);
 /*updates SVC config. If is_additional is set, the SVCConfig will be added to the AVC sample description, otherwise the sample description will be SVC-only*/
 GF_Err gf_isom_svc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg, Bool is_additional);
+/*creates new SVC config*/
+GF_Err gf_isom_svc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex);
+/*deletes SVC config*/
+GF_Err gf_isom_svc_config_del(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex);
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 
@@ -1579,6 +1621,13 @@ GF_TextSample *gf_isom_new_text_sample();
 /*destroy text sample handle*/
 void gf_isom_delete_text_sample(GF_TextSample *tx_samp);
 
+/*generic subtitle sample formatting*/
+typedef struct _generic_subtitle_sample GF_GenericSubtitleSample;
+/*creates generic subtitle sample handle*/
+GF_GenericSubtitleSample *gf_isom_new_generic_subtitle_sample();
+/*destroy generic subtitle sample handle*/
+void gf_isom_delete_generic_subtitle_sample(GF_GenericSubtitleSample *generic_subtitle_samp);
+
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
 /*Create a new TextSampleDescription in the file. 
@@ -1645,6 +1694,12 @@ GF_Err gf_isom_text_set_wrap(GF_TextSample * samp, u8 wrap_flags);
 text sample content is kept untouched*/
 GF_ISOSample *gf_isom_text_to_sample(GF_TextSample * tx_samp);
 
+
+GF_Err gf_isom_generic_subtitle_reset(GF_GenericSubtitleSample *samp);
+GF_Err gf_isom_new_generic_subtitle_description(GF_ISOFile *movie, u32 trackNumber, char *content_encoding, char *xml_schema_loc, char*mime_type_or_namespace, Bool is_xml, char *URLname, char *URNname, u32 *outDescriptionIndex);
+GF_ISOSample *gf_isom_generic_subtitle_to_sample(GF_GenericSubtitleSample * tx_samp);
+GF_Err gf_isom_generic_subtitle_sample_add_text(GF_GenericSubtitleSample *samp, char *text_data, u32 text_len);
+
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 /*****************************************************
@@ -1905,7 +1960,7 @@ GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber);
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 
-/*3GPP Alternate Group API - (c) 2007 ENST & ResonateMP4*/
+/*3GPP Alternate Group API - (c) 2007 Telecom ParisTech*/
 
 /*gets the number of switching groups declared in this track if any:
 trackNumber: track number
@@ -1954,6 +2009,8 @@ typedef struct
        const char *textEncoding;
        const char *contentEncoding;
        const char *content_script_types;
+    const char *mime_type;
+    const char *xml_schema_loc;
 } GF_DIMSDescription;
 
 GF_Err gf_isom_get_dims_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, GF_DIMSDescription *desc);
@@ -1964,16 +2021,25 @@ GF_Err gf_isom_update_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DI
 
 
 
-
-/*AC3 config record*/
-typedef struct 
+struct __ec3_stream
 {
        u8 fscod;
        u8 bsid;
        u8 bsmod;
        u8 acmod;
        u8 lfon;
-       u8 brcode;
+       /*only for EC3*/
+       u8 nb_dep_sub;
+       u8 chan_loc;
+};
+
+/*AC3 config record*/
+typedef struct 
+{
+       u8 is_ec3;
+       u8 nb_streams; //1 for AC3, max 8 for EC3
+       u16 brcode; //if AC3 is bitrate code, otherwise cumulated datarate of EC3 streams
+       struct __ec3_stream streams[8];
 } GF_AC3Config;
 
 GF_AC3Config *gf_isom_ac3_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex);
@@ -1983,6 +2049,7 @@ GF_Err gf_isom_ac3_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AC3Confi
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 
+
 /*returns the number of subsamples in the given sample */
 u32 gf_isom_sample_has_subsamples(GF_ISOFile *movie, u32 track, u32 sampleNumber);
 GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleNumber, u32 *size, u8 *priority, u32 *reserved, Bool *discardable);
@@ -2016,8 +2083,13 @@ GF_Err gf_isom_set_sample_rap_group(GF_ISOFile *movie, u32 track, u32 sample_num
 /*sets roll_distance info for sample_number (number of frames before (<0) or after (>0) this sample to have a complete refresh of the decoded data (used by GDR in AVC)
 - currently sample group info MUST be added in order (no insertion in the tables)*/
 GF_Err gf_isom_set_sample_roll_group(GF_ISOFile *movie, u32 track, u32 sample_number, s16 roll_distance);
+
+GF_Err gf_isom_set_composition_offset_mode(GF_ISOFile *file, u32 track, Bool use_negative_offsets);
+
 #endif
 
+
+
 #endif /*GPAC_DISABLE_ISOM*/
 
 #ifdef __cplusplus
index 3ad8289ef219ec99f9f0a697f037885da23b4444..76eb9f2310974768bd09f5895211048330873ddd 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 9187fdcca58a4f6bdea141409a5f2f3f765a483b..04ffcf9e80c5777bd45aa152bbf9a5aefcb205aa 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 3c61046727f34fdb63dca5c6bf4c4a4f76608eee..ddeb80941ba76c43ff40bbcfd4faabcf61a111c9 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index b2fe23661464c28dd06af948e6c5adc108292849..f860a7cfc8868c61d6c8dcc20e64bbda22cc7749 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Authoring Tools sub-project
@@ -32,6 +33,7 @@ extern "C" {
 
 #include <gpac/isomedia.h>
 #include <gpac/avparse.h>
+#include <gpac/config_file.h>
 
 /*computes file hash. If file is ISO-based, computre hash according to OMA (P)DCF (without MutableDRMInformation box)*/
 GF_Err gf_media_get_file_hash(const char *file, u8 hash[20]);
@@ -206,7 +208,8 @@ typedef struct __track_import
        /*for text import*/
        u32 fontSize;
        char *fontName;
-       u32 twidth, theight;
+       u32 text_track_width, text_track_height, text_width, text_height;
+       s32 text_x, text_y;
 
        /*Initial offset of the first AU to import*/
        Double initial_time_offset;
@@ -251,19 +254,53 @@ GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level);
 /*rewrite AVC samples if nalu size_length has to be changed*/
 GF_Err gf_media_avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size_in_bits, u32 new_size_in_bits);
 
+/* Split SVC layers */
+GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll);
+
+/* Merge SVC layers*/
+GF_Err gf_media_merge_svc(GF_ISOFile *file, u32 track, Bool mergeAll);
+
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
 
-#ifndef GPAC_DISABLE_ISOM_WRITE
+typedef struct 
+{
+       char *file_name;
+       char representationID[100];
+       char periodID[100];
+       u32 bandwidth;
+} GF_DashSegmenterInput;
+
+typedef enum
+{
+       GF_DASH_PROFILE_FULL = 0,
+       /*live for ISOFF, SIMPLE for M2TS*/
+       GF_DASH_PROFILE_LIVE,
+       GF_DASH_PROFILE_ONDEMAND,
+       GF_DASH_PROFILE_MAIN,
+
+       /*internal use only*/
+       GF_DASH_PROFILE_UNKNOWN
+} GF_DashProfile;
+
+GF_Err gf_dasher_segment_files(const char *mpd_name, GF_DashSegmenterInput *inputs, u32 nb_inputs, GF_DashProfile profile, 
+                                                          const char *mpd_title, const char *mpd_source, const char *mpd_copyright,
+                                                          const char *mpd_moreInfoURL, const char **mpd_base_urls, u32 nb_mpd_base_urls, 
+                                                          Bool use_url_template, Bool single_segment, Bool single_file, Bool bitstream_switching_mode,
+                                                          Bool segments_start_with_rap, Double dash_duration_sec, char *seg_rad_name, char *seg_ext,
+                                                          Double frag_duration_sec, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool fragments_start_with_rap, const char *tmp_dir,  
+                                                          GF_Config *dash_ctx, Bool dash_dynamic, u32 mpd_update_time, u32 time_shift_depth, Double subduration);
+
+/*returns time to wait until end of currently generated segments*/
+u32 gf_dasher_next_update_time(GF_Config *dash_ctx, u32 mpd_update_time);
 
-/*starts MPD file */
-GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bool single_segment, char *dash_ctx, GF_ISOFile *init_segment, Double period_duration);
-GF_Err gf_media_mpd_end(char *mpd_name);
+#ifndef GPAC_DISABLE_ISOM_WRITE
 
 #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-/*save file as fragmented movie
-@dash_mode: 0 = DASH not used, 1 = DASH used without GOP spliting, 2 = DASH used with GOP spliting, */
-GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file_radical, const char *mpd_name, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, Bool use_single_segment, const char *dash_ctx, GF_ISOFile *sample_descs, u32 rep_id);
+/*save file as fragmented movie*/
+GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, Double max_duration_sec);
+
+
 #endif
 
 #endif
@@ -403,7 +440,10 @@ GF_Err gf_saf_mux_add_au(GF_SAFMuxer *mux, u32 stream_id, u32 CTS, char *data, u
 if force_end_of_session is set, this flushes the SAF Session - no more operations will be allowed on the muxer*/
 GF_Err gf_saf_mux_for_time(GF_SAFMuxer *mux, u32 time_ms, Bool force_end_of_session, char **out_data, u32 *out_size);
 
-
+/*reduces input width/height to common aspect ration num/denum values*/
+void gf_media_reduce_aspect_ratio(u32 *width, u32 *height);
+/*reduces input FPS to a more compact value (eg 25000/1000 -> 25/1)*/
+void gf_media_get_reduced_frame_rate(u32 *timescale, u32 *sample_dur);
 
 #ifdef __cplusplus
 }
index fd330eba5c2549f899a6751319513867bf9ba713..7358fdd2aaed46f344ace8ab23b7e8643413efef 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Stream Management sub-project
index 64184034689538b236e8412a33e8701627e267fb..14332b5730223e9079cbcfd72411cb343195435c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 94bbf8d1d23377e62e9bd34abd74f6235690c158..7153b77fb7308f32f0b01dcfe20863708b502a66 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
@@ -102,7 +103,7 @@ typedef struct _audiooutput
        /*if not using private thread, this should perform sleep & fill of HW buffer
                the audio render loop in this case is: while (run) {driver->WriteAudio(); if (reconf) Reconfig();}
        the driver must therefore give back the hand to the renderer as often as possible - the usual way is:
-               gf_sleep untill hw data can be written
+               gf_sleep until hw data can be written
                write HW data
                return
        */
index 14bb2cf3f380f643c4f3425d051d6b4b1abce68e..7a0cbbd056b77ac27dc847dbe081f45e4cbd3e27 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index 1b8e40d3231a83e842140ce544e945ad759bd3ad..f8822e1ed065f59bf5f1d3b9e3a5ebd32e908729 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index 10f0f1527f39ee77c5237506ede405206959911f..addb6f1079dafb7c496e91dfcdbc70cf500c0841 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Ivica Arsov, Jean Le Feuvre
+ *                     Authors: Jean Le Feuvre
  *                     Copyright (c) Telecom ParisTech 2012
  *                                     All rights reserved
  *
@@ -36,23 +36,24 @@ extern "C" {
 #include <gpac/compositor.h>
 
 /*interface name and version for Built-in proto User Extensions*/
-#define GF_HARDCODED_PROTO_INTERFACE           GF_4CC('G','H','P', '1')
+#define GF_HARDCODED_PROTO_INTERFACE           GF_4CC('G','H','P', '2')
 
 typedef struct _hc_proto_mod
 {
        /* interface declaration*/
        GF_DECL_MODULE_INTERFACE
 
-       /*load hardcoded proto
-        compositor: compositor used for loading
-        node: proto node to be loaded
+       /*Initialize hardcoded proto node.
+        compositor: GPAC compositor
+        node: node to be loaded - this node is always a PROTO instance
+        proto_uri: the proto URI
        */
-       Bool (*init)(GF_Compositor* compositor, GF_Node* node);
+       Bool (*init)(GF_Compositor* compositor, GF_Node* node, const char *proto_uri);
 
        /*check if the module can load a proto
-        url: url to check
+        uri: proto uri to check for support
        */
-       Bool (*can_load_proto)(const char* url);
+       Bool (*can_load_proto)(const char* uri);
 
        /*module private*/
        void *udta;
index 0b561db619518af63a1d76a14258985a702f2da4..de0342c0b07a3af4bd638ff97af9e0b13e73b72f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index 4d92f4bb0eca248d86ddbcd0a7fb7b5a0034615a..a84e08e46f2edbf80ee0581209dcf8ce0949a48a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index 9fd1702928ccc55f5755f98db1cf091ccb7ee191..750d19dc62d94b17c683d50f7fcca8d8e1283dfc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index bff5805d4071f839929856a03afbc9289aa9cfa0..388079fb07fc5255f4d89f2ad0f37d4556b4005d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
@@ -33,6 +34,7 @@ extern "C" {
 #include <gpac/mpeg4_odf.h>
 #include <gpac/events.h>
 #include <gpac/download.h>
+#include <gpac/module.h>
 
 /*handle to service*/
 typedef struct _net_service GF_ClientService;
@@ -322,6 +324,9 @@ typedef struct
                2: time discontinuity - seeking has occured and some segments were skipped
        */
        u32 discontinuity_type;
+       /*out: initialization/switching segment of next URL to play, if different from previous init segment*/
+       const char *next_url_init_or_switch_segment;
+       u64 switch_start_range, switch_end_range;
 } GF_NetURLQuery;
 
 /*GF_NET_SERVICE_QUALITY_SWITCH*/
index 4fd0e0dbeb1302a766bcdd8ad5aa0dace0bf7951..3a18fbf36ab0d7c8332ea4a7a0e7a5bcfbd804e6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index 4c376926fa96b9426aa2706aae8cee07a1f3338c..337651777435dd111726e088f0ecbb9f4bf9ec68 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / modules interfaces
index 9bc29fad19a435879d514dc8a14f753ebb29288b..a31acfb87bd12b1303c6e8992464ca6c53aee366 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 Object Descriptor sub-project
@@ -102,6 +103,8 @@ enum
        /*internal descriptor for LASeR config input description*/
        GF_ODF_LASER_CFG_TAG    = GF_ODF_USER_BEGIN_TAG + 6,
 
+       GF_ODF_GEN_SUB_CFG_TAG  = GF_ODF_USER_BEGIN_TAG + 7,
+
        GF_ODF_USER_END_TAG             = 0xFE,
 
        GF_ODF_OCI_BEGIN_TAG    = 0x40,
@@ -487,6 +490,35 @@ typedef struct
        s16 vert_offset;
 } GF_TextConfig;
 
+typedef struct
+{
+       /*this is defined as a descriptor for parsing*/
+       BASE_DESCRIPTOR
+
+       /*unused in isomedia but needed for streamingText*/
+       u8 sample_index;
+} GF_GenericSubtitleSampleDescriptor;
+
+typedef struct
+{
+       BASE_DESCRIPTOR
+       u32 timescale;
+       /*More negative layer values are towards the viewer*/
+       s16 layer;
+       /*text track width & height*/
+       u16 text_width;
+       u16 text_height;
+       /*defined in isomedia.h*/
+       GF_List *sample_descriptions;
+
+       /*if true info below are valid (cf 3GPP for their meaning)*/
+       Bool has_vid_info;
+       u16 video_width;
+       u16 video_height;
+       s16 horiz_offset;
+       s16 vert_offset;
+} GF_GenericSubtitleConfig;
+
 
 /*MuxInfo descriptor - parsing only, stored in ESD:extDescr*/
 typedef struct {
@@ -838,6 +870,13 @@ typedef struct
 
        /*for SVC*/
        u8 complete_representation;
+
+       /*for high profiles*/
+       u8 chroma_format;
+       u8 luma_bit_depth;
+       u8 chroma_bit_depth;
+       /*may be NULL*/
+       GF_List *sequenceParameterSetExtensions;
 } GF_AVCConfig;
 
 
index 9bc55da0286e9f1fa2598f0da02b94dc1138eee6..6bf26acc55e506cb2671db195025b3c1ec610280 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Walid B.H - Jean Le Feuvre
- *    Copyright (c)2006-200X ENST - All rights reserved
+ *                     Authors: Jean Le Feuvre, Cyril Concolato, Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *
  *  This file is part of GPAC / MPEG2-TS sub-project
  *
 #define _GF_MPEG_TS_H_
 
 #include <gpac/list.h>
-
-#ifndef GPAC_DISABLE_MPEG2TS
-
-#include <gpac/internal/odf_dev.h>
 #include <gpac/network.h>
-#include <gpac/esi.h>
 #include <gpac/thread.h>
-#include <time.h>
+#include <gpac/internal/odf_dev.h>
 
-typedef struct tag_m2ts_demux GF_M2TS_Demuxer;
-typedef struct tag_m2ts_es GF_M2TS_ES;
-typedef struct tag_m2ts_section_es GF_M2TS_SECTION_ES;
 
-#ifdef GPAC_HAS_LINUX_DVB
-typedef struct __gf_dvb_tuner GF_Tuner;
-#endif
 
-/*Maximum number of streams in a TS*/
-#define GF_M2TS_MAX_STREAMS    8192
+/*MPEG-2 Descriptor tags*/
+enum
+{
+       /* ... */
+       GF_M2TS_VIDEO_STREAM_DESCRIPTOR                                                 = 0x02,
+       GF_M2TS_AUDIO_STREAM_DESCRIPTOR                                                 = 0x03,
+       GF_M2TS_HIERARCHY_DESCRIPTOR                                                    = 0x04,
+       GF_M2TS_REGISTRATION_DESCRIPTOR                                                 = 0x05,
+       GF_M2TS_DATA_STREAM_ALIGNEMENT_DESCRIPTOR                               = 0x06,
+       GF_M2TS_TARGET_BACKGROUND_GRID_DESCRIPTOR                               = 0x07,
+       GF_M2TS_VIEW_WINDOW_DESCRIPTOR                                                  = 0x08,
+       GF_M2TS_CA_DESCRIPTOR                                                                   = 0x09,
+       GF_M2TS_ISO_639_LANGUAGE_DESCRIPTOR                                             = 0x0A,
+       GF_M2TS_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR                             = 0x0C,
+       GF_M2TS_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR    = 0x0D,
+       GF_M2TS_DVB_TARGET_IP_SLASH_DESCRIPTOR                  = 0x0F,
+       /* ... */
+       GF_M2TS_DVB_STREAM_LOCATION_DESCRIPTOR        =0x13,
+       /* ... */
+       GF_M2TS_STD_DESCRIPTOR                                  = 0x17,
+       /* ... */
+       GF_M2TS_MPEG4_VIDEO_DESCRIPTOR                          = 0x1B,
+       GF_M2TS_MPEG4_AUDIO_DESCRIPTOR                          = 0x1C,
+       GF_M2TS_MPEG4_IOD_DESCRIPTOR                            = 0x1D,
+       GF_M2TS_MPEG4_SL_DESCRIPTOR                             = 0x1E,
+       GF_M2TS_MPEG4_FMC_DESCRIPTOR                            = 0x1F,
+       /* ... */
+       GF_M2TS_AVC_VIDEO_DESCRIPTOR                            = 0x28,
+       /* ... */       
+       GF_M2TS_AVC_TIMING_HRD_DESCRIPTOR                       = 0x2A,
+       /* ... */
+       GF_M2TS_MPEG4_ODUPDATE_DESCRIPTOR                       = 0x35,
 
-/*Maximum number of service in a TS*/
-#define GF_M2TS_MAX_SERVICES   65535
+       /* 0x2D - 0x3F - ISO/IEC 13818-6 values */
+       /* 0x40 - 0xFF - User Private values */
+       GF_M2TS_DVB_NETWORK_NAME_DESCRIPTOR                     = 0x40,
+       GF_M2TS_DVB_SERVICE_LIST_DESCRIPTOR                     = 0x41,
+       GF_M2TS_DVB_STUFFING_DESCRIPTOR                         = 0x42,
+       GF_M2TS_DVB_SAT_DELIVERY_SYSTEM_DESCRIPTOR              = 0x43,
+       GF_M2TS_DVB_CABLE_DELIVERY_SYSTEM_DESCRIPTOR            = 0x44,
+       GF_M2TS_DVB_VBI_DATA_DESCRIPTOR                         = 0x45,
+       GF_M2TS_DVB_VBI_TELETEXT_DESCRIPTOR                     = 0x46,
+       GF_M2TS_DVB_BOUQUET_NAME_DESCRIPTOR                     = 0x47,
+       GF_M2TS_DVB_SERVICE_DESCRIPTOR                          = 0x48,
+       GF_M2TS_DVB_COUNTRY_AVAILABILITY_DESCRIPTOR             = 0x49,
+       GF_M2TS_DVB_LINKAGE_DESCRIPTOR                          = 0x4A,
+       GF_M2TS_DVB_NVOD_REFERENCE_DESCRIPTOR                   = 0x4B,
+       GF_M2TS_DVB_TIME_SHIFTED_SERVICE_DESCRIPTOR             = 0x4C,
+       GF_M2TS_DVB_SHORT_EVENT_DESCRIPTOR                      = 0x4D,
+       GF_M2TS_DVB_EXTENDED_EVENT_DESCRIPTOR                   = 0x4E,
+       GF_M2TS_DVB_TIME_SHIFTED_EVENT_DESCRIPTOR               = 0x4F,
+       GF_M2TS_DVB_COMPONENT_DESCRIPTOR                        = 0x50,
+       GF_M2TS_DVB_MOSAIC_DESCRIPTOR                           = 0x51,
+       GF_M2TS_DVB_STREAM_IDENTIFIER_DESCRIPTOR                = 0x52,
+       GF_M2TS_DVB_CA_IDENTIFIER_DESCRIPTOR                    = 0x53,
+       GF_M2TS_DVB_CONTENT_DESCRIPTOR                          = 0x54,
+       GF_M2TS_DVB_PARENTAL_RATING_DESCRIPTOR                  = 0x55,
+       GF_M2TS_DVB_TELETEXT_DESCRIPTOR                         = 0x56,
+       /* ... */
+       GF_M2TS_DVB_LOCAL_TIME_OFFSET_DESCRIPTOR                = 0x58,
+       GF_M2TS_DVB_SUBTITLING_DESCRIPTOR                       = 0x59,
+       GF_M2TS_DVB_PRIVATE_DATA_SPECIFIER_DESCRIPTOR = 0x5F,
+       /* ... */
+       GF_M2TS_DVB_DATA_BROADCAST_DESCRIPTOR                   = 0x64,
+       /* ... */
+       GF_M2TS_DVB_DATA_BROADCAST_ID_DESCRIPTOR                = 0x66,
+       /* ... */
+       GF_M2TS_DVB_AC3_DESCRIPTOR                              = 0x6A,
+       /* ... */
+       GF_M2TS_DVB_TIME_SLICE_FEC_DESCRIPTOR              = 0x77,
+       /* ... */
+       GF_M2TS_DVB_EAC3_DESCRIPTOR                             = 0x7A,
+       GF_M2TS_DVB_LOGICAL_CHANNEL_DESCRIPTOR = 0x83,          
+};
 
-/*Maximum size of the buffer in UDP */
-#define UDP_BUFFER_SIZE        0x40000
+/* Reserved PID values */
+enum {
+       GF_M2TS_PID_PAT                 = 0x0000,
+       GF_M2TS_PID_CAT                 = 0x0001,
+       GF_M2TS_PID_TSDT                = 0x0002,
+       /* reserved 0x0003 to 0x000F */ 
+       GF_M2TS_PID_NIT_ST              = 0x0010,
+       GF_M2TS_PID_SDT_BAT_ST  = 0x0011,
+       GF_M2TS_PID_EIT_ST_CIT  = 0x0012,
+       GF_M2TS_PID_RST_ST              = 0x0013,
+       GF_M2TS_PID_TDT_TOT_ST  = 0x0014,
+       GF_M2TS_PID_NET_SYNC    = 0x0015,
+       GF_M2TS_PID_RNT                 = 0x0016,
+       /* reserved 0x0017 to 0x001B */ 
+       GF_M2TS_PID_IN_SIG              = 0x001C,
+       GF_M2TS_PID_MEAS                = 0x001D,
+       GF_M2TS_PID_DIT                 = 0x001E,
+       GF_M2TS_PID_SIT                 = 0x001F
+};
+
+/* max size includes first header, second header, payload and CRC */
+enum {
+       GF_M2TS_TABLE_ID_PAT                    = 0x00,
+       GF_M2TS_TABLE_ID_CAT                    = 0x01, 
+       GF_M2TS_TABLE_ID_PMT                    = 0x02, 
+       GF_M2TS_TABLE_ID_TSDT                   = 0x03, /* max size for section 1024 */
+       GF_M2TS_TABLE_ID_MPEG4_BIFS             = 0x04, /* max size for section 4096 */
+       GF_M2TS_TABLE_ID_MPEG4_OD               = 0x05, /* max size for section 4096 */
+       GF_M2TS_TABLE_ID_METADATA               = 0x06, 
+       GF_M2TS_TABLE_ID_IPMP_CONTROL   = 0x07, 
+       /* 0x08 - 0x37 reserved */
+       /* 0x38 - 0x3D DSM-CC defined */
+       GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA               = 0x3A, 
+       GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE                              = 0x3B, /* used for MPE (only, not MPE-FEC) */
+       GF_M2TS_TABLE_ID_DSM_CC_DOWNLOAD_DATA_MESSAGE   = 0x3C, /* used for MPE (only, not MPE-FEC) */
+       GF_M2TS_TABLE_ID_DSM_CC_STREAM_DESCRIPTION              = 0x3D, /* used for MPE (only, not MPE-FEC) */
+       GF_M2TS_TABLE_ID_DSM_CC_PRIVATE                                 = 0x3E, /* used for MPE (only, not MPE-FEC) */
+       /* 0x3F DSM-CC defined */
+       GF_M2TS_TABLE_ID_NIT_ACTUAL             = 0x40, /* max size for section 1024 */
+       GF_M2TS_TABLE_ID_NIT_OTHER              = 0x41,
+       GF_M2TS_TABLE_ID_SDT_ACTUAL             = 0x42, /* max size for section 1024 */
+       /* 0x43 - 0x45 reserved */
+       GF_M2TS_TABLE_ID_SDT_OTHER              = 0x46, /* max size for section 1024 */
+       /* 0x47 - 0x49 reserved */
+       GF_M2TS_TABLE_ID_BAT                    = 0x4a, /* max size for section 1024 */
+       /* 0x4b reserved */
+       GF_M2TS_TABLE_ID_INT                    = 0x4c, /* max size for section 4096 */
+       /* 0x4d reserved */
+       
+       GF_M2TS_TABLE_ID_EIT_ACTUAL_PF  = 0x4E, /* max size for section 4096 */
+       GF_M2TS_TABLE_ID_EIT_OTHER_PF   = 0x4F,
+       /* 0x50 - 0x6f EIT SCHEDULE */
+       GF_M2TS_TABLE_ID_EIT_SCHEDULE_MIN       = 0x50,
+       GF_M2TS_TABLE_ID_EIT_SCHEDULE_ACTUAL_MAX= 0x5F,
+       GF_M2TS_TABLE_ID_EIT_SCHEDULE_MAX       = 0x6F,
+
+       GF_M2TS_TABLE_ID_TDT                    = 0x70, /* max size for section 1024 */
+       GF_M2TS_TABLE_ID_RST                    = 0x71, /* max size for section 1024 */
+       GF_M2TS_TABLE_ID_ST                     = 0x72, /* max size for section 4096 */
+       GF_M2TS_TABLE_ID_TOT                    = 0x73, /* max size for section 1024 */
+       GF_M2TS_TABLE_ID_AIT                    = 0x74,
+       GF_M2TS_TABLE_ID_CONT                   = 0x75,
+       GF_M2TS_TABLE_ID_RC                             = 0x76,
+       GF_M2TS_TABLE_ID_CID                    = 0x77,
+       GF_M2TS_TABLE_ID_MPE_FEC                = 0x78,
+       GF_M2TS_TABLE_ID_RES_NOT                = 0x79,
+       /* 0x7A - 0x7D reserved */
+       GF_M2TS_TABLE_ID_DIT                    = 0x7E,
+       GF_M2TS_TABLE_ID_SIT                    = 0x7F, /* max size for section 4096 */
+       /* 0x80 - 0xfe reserved */
+       /* 0xff reserved */
+};
 
 /*MPEG-2 TS Media types*/
 enum
@@ -91,9 +219,46 @@ enum
        GF_M2TS_DVB_VBI                                 = 0x153,
        GF_M2TS_DVB_SUBTITLE                    = 0x154,
 };
+
+
+#define SECTION_HEADER_LENGTH 3 /* header till the last bit of the section_length field */
+#define SECTION_ADDITIONAL_HEADER_LENGTH 5 /* header from the last bit of the section_length field to the payload */
+#define        CRC_LENGTH 4
+
+
+
+#ifndef GPAC_DISABLE_MPEG2TS
+
+#include <time.h>
+
+typedef struct tag_m2ts_demux GF_M2TS_Demuxer;
+typedef struct tag_m2ts_es GF_M2TS_ES;
+typedef struct tag_m2ts_section_es GF_M2TS_SECTION_ES;
+
+#ifdef GPAC_HAS_LINUX_DVB
+typedef struct __gf_dvb_tuner GF_Tuner;
+#endif
+
+/*Maximum number of streams in a TS*/
+#define GF_M2TS_MAX_STREAMS    8192
+
+/*Maximum number of service in a TS*/
+#define GF_M2TS_MAX_SERVICES   65535
+
+/*Maximum size of the buffer in UDP */
+#define UDP_BUFFER_SIZE        0x40000
+
 /*returns readable name for given stream type*/
 const char *gf_m2ts_get_stream_name(u32 streamType);
 
+/*returns 1 if file is an MPEG-2 TS */
+Bool gf_m2ts_probe_file(const char *fileName);
+
+/*shifts all timing by the given value 
+@is_pes: array of GF_M2TS_MAX_STREAMS u8 set to 1 for PES PIDs to be restamped
+*/
+GF_Err gf_m2ts_restamp(char *buffer, u32 size, s64 ts_shift, u8 *is_pes);
+
 /*PES data framing modes*/
 enum
 {
@@ -192,6 +357,7 @@ enum
        GF_M2TS_EVT_AIT_FOUND,
        /*DSCM-CC has been found (carousel) */
        GF_M2TS_EVT_DSMCC_FOUND,
+       GF_M2TS_EVT_EOS,
 
 };
 
@@ -300,16 +466,18 @@ typedef struct
 /*ES flags*/
 enum
 {
+       /*ES is a PES stream*/
+       GF_M2TS_ES_IS_PES = 1,
        /*ES is a section stream*/
-       GF_M2TS_ES_IS_SECTION = 1,
+       GF_M2TS_ES_IS_SECTION = 1<<1,
        /*ES is an mpeg-4 flexmux stream*/
-       GF_M2TS_ES_IS_FMC = 1<<1,
+       GF_M2TS_ES_IS_FMC = 1<<2,
        /*ES is an mpeg-4 SL-packetized stream*/
-       GF_M2TS_ES_IS_SL = 1<<2,
+       GF_M2TS_ES_IS_SL = 1<<3,
        /*ES is an mpeg-4 Object Descriptor SL-packetized stream*/
-       GF_M2TS_ES_IS_MPEG4_OD = 1<<3,
+       GF_M2TS_ES_IS_MPEG4_OD = 1<<4,
        /*ES is a DVB MPE stream*/
-       GF_M2TS_ES_IS_MPE = 1<<4,
+       GF_M2TS_ES_IS_MPE = 1<<5,
        
        /*all flags above this mask are used by importers & co*/
        GF_M2TS_ES_STATIC_FLAGS_MASK = 0x0000FFFF,
@@ -625,6 +793,7 @@ struct tag_m2ts_demux
        Bool direct_mpe;
 
        Bool dvb_h_demux;
+       Bool notify_pes_timing;
        
        /*user callback - MUST NOT BE NULL*/
        void (*on_mpe_event)(struct tag_m2ts_demux *ts, u32 evt_type, void *par);
@@ -665,159 +834,7 @@ void gf_m2ts_demux_dmscc_init(GF_M2TS_Demuxer *ts);
 
 u32 gf_m2ts_crc32_check(char *data, u32 len);
 
-/*MPEG-2 Descriptor tags*/
-enum
-{
-       /* ... */
-       GF_M2TS_VIDEO_STREAM_DESCRIPTOR                                                 = 0x02,
-       GF_M2TS_AUDIO_STREAM_DESCRIPTOR                                                 = 0x03,
-       GF_M2TS_HIERARCHY_DESCRIPTOR                                                    = 0x04,
-       GF_M2TS_REGISTRATION_DESCRIPTOR                                                 = 0x05,
-       GF_M2TS_DATA_STREAM_ALIGNEMENT_DESCRIPTOR                               = 0x06,
-       GF_M2TS_TARGET_BACKGROUND_GRID_DESCRIPTOR                               = 0x07,
-       GF_M2TS_VIEW_WINDOW_DESCRIPTOR                                                  = 0x08,
-       GF_M2TS_CA_DESCRIPTOR                                                                   = 0x09,
-       GF_M2TS_ISO_639_LANGUAGE_DESCRIPTOR                                             = 0x0A,
-       GF_M2TS_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR                             = 0x0C,
-       GF_M2TS_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR    = 0x0D,
-       GF_M2TS_DVB_TARGET_IP_SLASH_DESCRIPTOR                  = 0x0F,
-       /* ... */
-       GF_M2TS_DVB_STREAM_LOCATION_DESCRIPTOR        =0x13,
-       /* ... */
-       GF_M2TS_STD_DESCRIPTOR                                  = 0x17,
-       /* ... */
-       GF_M2TS_MPEG4_VIDEO_DESCRIPTOR                          = 0x1B,
-       GF_M2TS_MPEG4_AUDIO_DESCRIPTOR                          = 0x1C,
-       GF_M2TS_MPEG4_IOD_DESCRIPTOR                            = 0x1D,
-       GF_M2TS_MPEG4_SL_DESCRIPTOR                             = 0x1E,
-       GF_M2TS_MPEG4_FMC_DESCRIPTOR                            = 0x1F,
-       /* ... */
-       GF_M2TS_AVC_VIDEO_DESCRIPTOR                            = 0x28,
-       /* ... */       
-       GF_M2TS_AVC_TIMING_HRD_DESCRIPTOR                       = 0x2A,
-       /* ... */
-       GF_M2TS_MPEG4_ODUPDATE_DESCRIPTOR                       = 0x35,
 
-       /* 0x2D - 0x3F - ISO/IEC 13818-6 values */
-       /* 0x40 - 0xFF - User Private values */
-       GF_M2TS_DVB_NETWORK_NAME_DESCRIPTOR                     = 0x40,
-       GF_M2TS_DVB_SERVICE_LIST_DESCRIPTOR                     = 0x41,
-       GF_M2TS_DVB_STUFFING_DESCRIPTOR                         = 0x42,
-       GF_M2TS_DVB_SAT_DELIVERY_SYSTEM_DESCRIPTOR              = 0x43,
-       GF_M2TS_DVB_CABLE_DELIVERY_SYSTEM_DESCRIPTOR            = 0x44,
-       GF_M2TS_DVB_VBI_DATA_DESCRIPTOR                         = 0x45,
-       GF_M2TS_DVB_VBI_TELETEXT_DESCRIPTOR                     = 0x46,
-       GF_M2TS_DVB_BOUQUET_NAME_DESCRIPTOR                     = 0x47,
-       GF_M2TS_DVB_SERVICE_DESCRIPTOR                          = 0x48,
-       GF_M2TS_DVB_COUNTRY_AVAILABILITY_DESCRIPTOR             = 0x49,
-       GF_M2TS_DVB_LINKAGE_DESCRIPTOR                          = 0x4A,
-       GF_M2TS_DVB_NVOD_REFERENCE_DESCRIPTOR                   = 0x4B,
-       GF_M2TS_DVB_TIME_SHIFTED_SERVICE_DESCRIPTOR             = 0x4C,
-       GF_M2TS_DVB_SHORT_EVENT_DESCRIPTOR                      = 0x4D,
-       GF_M2TS_DVB_EXTENDED_EVENT_DESCRIPTOR                   = 0x4E,
-       GF_M2TS_DVB_TIME_SHIFTED_EVENT_DESCRIPTOR               = 0x4F,
-       GF_M2TS_DVB_COMPONENT_DESCRIPTOR                        = 0x50,
-       GF_M2TS_DVB_MOSAIC_DESCRIPTOR                           = 0x51,
-       GF_M2TS_DVB_STREAM_IDENTIFIER_DESCRIPTOR                = 0x52,
-       GF_M2TS_DVB_CA_IDENTIFIER_DESCRIPTOR                    = 0x53,
-       GF_M2TS_DVB_CONTENT_DESCRIPTOR                          = 0x54,
-       GF_M2TS_DVB_PARENTAL_RATING_DESCRIPTOR                  = 0x55,
-       GF_M2TS_DVB_TELETEXT_DESCRIPTOR                         = 0x56,
-       /* ... */
-       GF_M2TS_DVB_LOCAL_TIME_OFFSET_DESCRIPTOR                = 0x58,
-       GF_M2TS_DVB_SUBTITLING_DESCRIPTOR                       = 0x59,
-       GF_M2TS_DVB_PRIVATE_DATA_SPECIFIER_DESCRIPTOR = 0x5F,
-       /* ... */
-       GF_M2TS_DVB_DATA_BROADCAST_DESCRIPTOR                   = 0x64,
-       /* ... */
-       GF_M2TS_DVB_DATA_BROADCAST_ID_DESCRIPTOR                = 0x66,
-       /* ... */
-       GF_M2TS_DVB_AC3_DESCRIPTOR                              = 0x6A,
-       /* ... */
-       GF_M2TS_DVB_TIME_SLICE_FEC_DESCRIPTOR              = 0x77,
-       /* ... */
-       GF_M2TS_DVB_EAC3_DESCRIPTOR                             = 0x7A,
-       GF_M2TS_DVB_LOGICAL_CHANNEL_DESCRIPTOR = 0x83,          
-};
-
-/* Reserved PID values */
-enum {
-       GF_M2TS_PID_PAT                 = 0x0000,
-       GF_M2TS_PID_CAT                 = 0x0001,
-       GF_M2TS_PID_TSDT                = 0x0002,
-       /* reserved 0x0003 to 0x000F */ 
-       GF_M2TS_PID_NIT_ST              = 0x0010,
-       GF_M2TS_PID_SDT_BAT_ST  = 0x0011,
-       GF_M2TS_PID_EIT_ST_CIT  = 0x0012,
-       GF_M2TS_PID_RST_ST              = 0x0013,
-       GF_M2TS_PID_TDT_TOT_ST  = 0x0014,
-       GF_M2TS_PID_NET_SYNC    = 0x0015,
-       GF_M2TS_PID_RNT                 = 0x0016,
-       /* reserved 0x0017 to 0x001B */ 
-       GF_M2TS_PID_IN_SIG              = 0x001C,
-       GF_M2TS_PID_MEAS                = 0x001D,
-       GF_M2TS_PID_DIT                 = 0x001E,
-       GF_M2TS_PID_SIT                 = 0x001F
-};
-
-/* max size includes first header, second header, payload and CRC */
-enum {
-       GF_M2TS_TABLE_ID_PAT                    = 0x00,
-       GF_M2TS_TABLE_ID_CAT                    = 0x01, 
-       GF_M2TS_TABLE_ID_PMT                    = 0x02, 
-       GF_M2TS_TABLE_ID_TSDT                   = 0x03, /* max size for section 1024 */
-       GF_M2TS_TABLE_ID_MPEG4_BIFS             = 0x04, /* max size for section 4096 */
-       GF_M2TS_TABLE_ID_MPEG4_OD               = 0x05, /* max size for section 4096 */
-       GF_M2TS_TABLE_ID_METADATA               = 0x06, 
-       GF_M2TS_TABLE_ID_IPMP_CONTROL   = 0x07, 
-       /* 0x08 - 0x37 reserved */
-       /* 0x38 - 0x3D DSM-CC defined */
-       GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA               = 0x3A, 
-       GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE                              = 0x3B, /* used for MPE (only, not MPE-FEC) */
-       GF_M2TS_TABLE_ID_DSM_CC_DOWNLOAD_DATA_MESSAGE   = 0x3C, /* used for MPE (only, not MPE-FEC) */
-       GF_M2TS_TABLE_ID_DSM_CC_STREAM_DESCRIPTION              = 0x3D, /* used for MPE (only, not MPE-FEC) */
-       GF_M2TS_TABLE_ID_DSM_CC_PRIVATE                                 = 0x3E, /* used for MPE (only, not MPE-FEC) */
-       /* 0x3F DSM-CC defined */
-       GF_M2TS_TABLE_ID_NIT_ACTUAL             = 0x40, /* max size for section 1024 */
-       GF_M2TS_TABLE_ID_NIT_OTHER              = 0x41,
-       GF_M2TS_TABLE_ID_SDT_ACTUAL             = 0x42, /* max size for section 1024 */
-       /* 0x43 - 0x45 reserved */
-       GF_M2TS_TABLE_ID_SDT_OTHER              = 0x46, /* max size for section 1024 */
-       /* 0x47 - 0x49 reserved */
-       GF_M2TS_TABLE_ID_BAT                    = 0x4a, /* max size for section 1024 */
-       /* 0x4b reserved */
-       GF_M2TS_TABLE_ID_INT                    = 0x4c, /* max size for section 4096 */
-       /* 0x4d reserved */
-       
-       GF_M2TS_TABLE_ID_EIT_ACTUAL_PF  = 0x4E, /* max size for section 4096 */
-       GF_M2TS_TABLE_ID_EIT_OTHER_PF   = 0x4F,
-       /* 0x50 - 0x6f EIT SCHEDULE */
-       GF_M2TS_TABLE_ID_EIT_SCHEDULE_MIN       = 0x50,
-       GF_M2TS_TABLE_ID_EIT_SCHEDULE_ACTUAL_MAX= 0x5F,
-       GF_M2TS_TABLE_ID_EIT_SCHEDULE_MAX       = 0x6F,
-
-       GF_M2TS_TABLE_ID_TDT                    = 0x70, /* max size for section 1024 */
-       GF_M2TS_TABLE_ID_RST                    = 0x71, /* max size for section 1024 */
-       GF_M2TS_TABLE_ID_ST                     = 0x72, /* max size for section 4096 */
-       GF_M2TS_TABLE_ID_TOT                    = 0x73, /* max size for section 1024 */
-       GF_M2TS_TABLE_ID_AIT                    = 0x74,
-       GF_M2TS_TABLE_ID_CONT                   = 0x75,
-       GF_M2TS_TABLE_ID_RC                             = 0x76,
-       GF_M2TS_TABLE_ID_CID                    = 0x77,
-       GF_M2TS_TABLE_ID_MPE_FEC                = 0x78,
-       GF_M2TS_TABLE_ID_RES_NOT                = 0x79,
-       /* 0x7A - 0x7D reserved */
-       GF_M2TS_TABLE_ID_DIT                    = 0x7E,
-       GF_M2TS_TABLE_ID_SIT                    = 0x7F, /* max size for section 4096 */
-       /* 0x80 - 0xfe reserved */
-       /* 0xff reserved */
-};
-
-
-
-#define SECTION_HEADER_LENGTH 3 /* header till the last bit of the section_length field */
-#define SECTION_ADDITIONAL_HEADER_LENGTH 5 /* header from the last bit of the section_length field to the payload */
-#define        CRC_LENGTH 4
 
 typedef struct
 {
@@ -865,8 +882,14 @@ typedef struct
 
 void gf_m2ts_print_info(GF_M2TS_Demuxer *ts);
 
+
+#endif /*GPAC_DISABLE_MPEG2TS*/
+
+
 #ifndef GPAC_DISABLE_MPEG2TS_MUX
 
+#include <gpac/esi.h>
+
 /*
        MPEG-2 TS Multiplexer
 */
@@ -978,7 +1001,7 @@ typedef struct __m2ts_mux_stream {
        /*avg bitrate compute*/
        u64 last_br_time;
        u32 bytes_since_last_time, pes_since_last_time;
-
+       u64 last_dts;
        /*MPEG-4 over MPEG-2*/
        u8 table_id;
        GF_SLHeader sl_header;
@@ -1147,11 +1170,13 @@ struct __gf_dvb_tuner {
 };
 
 
-#define DVB_BUFFER_SIZE 3760                                                   // DVB buffer size 188x20
+// DVB buffer size 188x20
+#define DVB_BUFFER_SIZE 3760                                                   
 
-#endif
+#endif //GPAC_HAS_LINUX_DVB
 
 
+#ifndef GPAC_DISABLE_MPEG2TS
 GF_Err TSDemux_Demux_Setup(GF_M2TS_Demuxer *ts, const char *url, Bool loop);
 GF_Err TSDemux_DemuxPlay(GF_M2TS_Demuxer *ts);
 GF_Err TSDemux_CloseDemux(GF_M2TS_Demuxer *ts);
index b2292ea2a30cc7b8b4904475746d7ade1d864830..53430072471becbb87bc016e7aab2664ddafb7a5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -95,6 +96,26 @@ char *gf_url_percent_encode(const char *path);
  */
 void gf_url_to_fs_path(char *url);
 
+
+/*!
+ *\brief Extract resource name from URL
+ *
+ *Ectracts the reource name from the URL
+ *\param url input url 
+ *\return resource name.
+ */
+const char *gf_url_get_resource_name(const char *url);
+
+/*!
+ *\brief Extract resource path from URL
+ *
+ *Ectracts the reource path from the URL
+ *\param url input url 
+ *\param res_path buffer for resulting path storage
+ *\return 1 if path was extracted, 0 if url is a single file name.
+ */
+Bool gf_url_get_resource_path(const char *url, char *res_path);
+
 /*!
  *\brief gets UTC time 
  *
index 5520c08432beb54eff097e93abccbde84784528f..f2371cb67f530b68115d9b6182b07558b65cd9ef 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index ed2f2e3624e1b1943f1faa26267d2003b02021cc..26175bfe38d13f8b11a631c11cd21b466b3a9783 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean Le Feuvre
- *    Copyright (c)2004-200X ENST - All rights reserved
+ *    Copyright (c)2004-2012 Telecom ParisTech - All rights reserved
  *
  *  This file is part of GPAC / XML-based Scene Graph sub-project
  *
index b3a1fc1c4093e51e84f4a5755fb5141c432af7c6..096b345939a82e86756ce46ed74f676ff50d4c26 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / X3D Scene Graph sub-project
index 742f525a86144228b8729bc95ab11f0259e2264b..cfcd057e4df531b241e68a3cbd2796799bef2bae 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Cyril Concolato - Jean Le Feuvre
- *    Copyright (c)2004-200X ENST - All rights reserved
+ *                     Authors: Cyril Concolato
+ *    Copyright (c)2004-2012 Telecom ParisTech - All rights reserved
  *
  *  This file is part of GPAC / XBL Elements 
  *
index 9fbcba1dacb2b57d5ba79cf4632cff30f258cdb5..e6c92ecea67d4bc947b70a7967559346e560be63 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Stream Management sub-project
index ed767f60f5028e7f7bed254127109c7ea984ee6a..9a30ec1d1f691b97ba3f98c7a01c34f7b11b7cab 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index d6d1f675fb763bd5627b5cb6efab7f11b7ed717b..c7d4c2f3d4cd1ff9788ffce5664c916f59028d11 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Pierre Souchay
+ *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 77584f3ffcedc4c812af86d1a3a628f7fc116984..a25e198e2e27942fd3cd05f02d48cb0cbe012660 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2008-
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / media tools sub-project
index 56a99d5c27a876148e5a9b11754f0f7a763383d2..4a9a54a0647f897456dc7c38e796f811b18dd862 100644 (file)
@@ -2,7 +2,7 @@
  *                                     GPAC Multimedia Framework
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC 
index 368af1e2f7fe0a8f34de5daddab79e5ee79e680b..2fa534a687afa50b613a82ce019541b2e7853c16 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Authoring Tools sub-project
@@ -184,6 +185,8 @@ enum
        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*/
index 7d933dca62ca207f0fbf308e2fde0211f02f0bdd..73211ad11c6d3b84b6df8dca1a0e4425ddde648a 100644 (file)
@@ -2,7 +2,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index 168fc06fce7d920745638ad19b2cabb5fe4a01c3..d676256109961cd3e5858bf3d701ab689c2c60bb 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004
+ *                     Authors: Jean Le Feuvre - Cyril COncolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph sub-project
index fe9999368af5dd69d65f9b96bfa127a6bb6f712e..54d891bd3ac2345056b10de5e564362082a42885 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index 59dd39f279ccaf62fd83663b917b1932e839155b..cbf8d09227730e6765926dd81aeac9528cb4f663 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / general OS configuration file
index 43f8ae4bf5e36bd7f47e60de85fba53c584d7403..8b5a73b49d4e660902034d9ca8a2bc9df3890b8e 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean Le Feuvre
- *                     Copyright (c) 2004-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index 3c3284c7b080fffae6ab5bd0500b8b9fb0bcdb1a..57debcb72104957d21f276462ac0a93b63617635 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SL header file
index 8d75a041b044cf57ac4a92879ecf38e67fd6c682..ffbd6738291b192cc5f1425c4defad3f69e9db36 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Stream Management sub-project
index 9e3ccb7a9a4cefddf3c1272647720d56a8d9be23..993075597d17289a753cc2a9bf3f259cee69724b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Stream Management sub-project
index 0dddee65d2184cb4a6acc80daf74a6fa501b809b..8d5c20c4d331811f1d54340b69eb2d241f7a03c9 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 2ac86f65819ba92099c2bbe80d93825270d8ead1..651074eee062a3add4410fa1af8e2a5e339781a1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index f4e50d30b62ea329b7e0a174845cfe4fc78bb50b..bd99679476bc8a023ee10502430046b64fcf2ff4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -30,6 +31,7 @@ extern "C" {
 #endif
 
 #include <gpac/setup.h>
+#include <gpac/version.h>
 
 
 /*! \file "gpac/tools.h"
@@ -51,32 +53,6 @@ extern "C" {
  *     @{
  */
 
-/*!
- *     \brief GPAC Version
- *     \hideinitializer
- *
- *     Macro giving GPAC version expressed as a printable string
-*/
-/* KEEP SPACE SEPARATORS FOR MAKE / GREP (SEE MAIN MAKEFILE)
- * NO SPACE in GPAC_VERSION for proper install
- * SONAME versions must be digits (not strings)
- */
-#define GPAC_VERSION          "0.5.0"
-#define GPAC_VERSION_MAJOR    2
-#define GPAC_VERSION_MINOR    0
-#define GPAC_VERSION_MICRO    0
-
-#include <gpac/version.h>
-#define GPAC_FULL_VERSION       GPAC_VERSION"-rev"GPAC_SVN_REVISION
-
-/*!
- *     \brief GPAC Version
- *     \hideinitializer
- *
- *     Macro giving GPAC version expressed as an integer, where version X.Y.Z is coded as 0x00XXYYZZ
-*/
-#define GPAC_VERSION_INT       0x00000406
-
 /*!
  *     \brief Stringizer
  *     \hideinitializer
@@ -376,8 +352,12 @@ enum
        GF_LOG_MODULE,
        /*! Log for threads and mutexes */
        GF_LOG_MUTEX,
+       /*! Log for all HTTP streaming */
+       GF_LOG_DASH,
        /*! Log for all messages coming from GF_Terminal or script alert()*/
        GF_LOG_CONSOLE,
+       /*! Log for all messages coming the application, not used by libgpac or the modules*/
+       GF_LOG_APP,
 
        /*! special value used to set a level for all tools*/
        GF_LOG_ALL,
@@ -397,7 +377,7 @@ void gf_log_set_tool_level(u32 tool, u32 level);
 /*!
  *     \brief Log Message Callback
  *
- * The gf_log_cbk type is the type for the callback of the \ref gf_log_set_callback function. By default all logs are redirected to stdout
+ * The gf_log_cbk type is the type for the callback of the \ref gf_log_set_callback function. By default all logs are redirected to stderr
  *     \param cbck Opaque user data.
  *     \param log_level level of the log. This value is not guaranteed in multi-threaded context.
  *     \param log_tool tool emitting the log. This value is not guaranteed in multi-threaded context.
@@ -410,7 +390,7 @@ typedef void (*gf_log_cbk)(void *cbck, u32 log_level, u32 log_tool, const char*
 /*!
  *     \brief Log overwrite
  *
- *     Assigns a user-defined callback for printing log messages. By default all logs are redirected to stdout
+ *     Assigns a user-defined callback for printing log messages. By default all logs are redirected to stderr
  *     \param usr_cbk Opaque user data
  *     \param cbk  callback log function
  *     \return previous callback function
@@ -558,7 +538,7 @@ GF_Err gf_delete_file(const char *fileName);
  *     \param fileName absolute path of the file / directory to move or rename
  *     \param newFileName absolute new path/name of the file / directory
 */
-void gf_move_file(const char *fileName, const char *newFileName);
+GF_Err gf_move_file(const char *fileName, const char *newFileName);
 
 /*!
  *     \brief Temporary File Creation
@@ -605,7 +585,7 @@ typedef void (*gf_on_progress_cbk)(const void *cbck, const char *title, u64 done
  *
  *     Iverwrites the progress signaling function by a user-defined one.
  *     \param user_cbk Opaque user data
- *     \param prog_cbk new callback function to use. Passing NULL restore default GPAC stdout notification.
+ *     \param prog_cbk new callback function to use. Passing NULL restore default GPAC stderr notification.
  */
 void gf_set_progress_callback(void *user_cbk, gf_on_progress_cbk prog_cbk);
 
index e2019fba7c1fdaa8fa8173ee414fcbc99aad3524..c94bfcafaaaf93eb3415a3098a3fdb7b5a07a455 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 43572317ef864777ec6ce5aa20340c119af2b9d2..571a23aafd65b2de4b5c9fd4e3941b94a90d4429 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Stream Management sub-project
index 0863b1afd786ff043c302d1b78fcca0881bce6c4..3008d7b3ad8d2c9d59eae24a3a80ccda350bba1b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
diff --git a/include/gpac/version.h b/include/gpac/version.h
new file mode 100644 (file)
index 0000000..c68da7f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *                     GPAC - Multimedia Framework C SDK
+ *
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2012
+ *                                     All rights reserved
+ *
+ *  This file is part of GPAC
+ *
+ *  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_VERSION_H
+
+/*!
+ *     \brief GPAC Version
+ *     \hideinitializer
+ *
+ *     Macro giving GPAC version expressed as a printable string
+*/
+/* KEEP SPACE SEPARATORS FOR MAKE / GREP (SEE MAIN MAKEFILE & CONFIGURE & CO)
+ * NO SPACE in GPAC_VERSION / GPAC_FULL_VERSION for proper install
+ * SONAME versions must be digits (not strings)
+ */
+#define GPAC_VERSION          "0.5.1-DEV"
+#define GPAC_VERSION_MAJOR 2
+#define GPAC_VERSION_MINOR 0
+#define GPAC_VERSION_MICRO 0
+
+#include <gpac/revision.h>
+#define GPAC_FULL_VERSION       GPAC_VERSION"-rev"GPAC_SVN_REVISION
+
+
+#endif //_GF_VERSION_H
+
index 41d137498067f60d3b6eb677c81a54848de981af..465957e2060b00f3d1c09f58bff554424d924367 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 921f0b249d837d6d740d29c6c5472de74f5beb93..4db18dbbc1d9b08e50f17efddbb82317bf37a561 100644 (file)
@@ -14,9 +14,4 @@ typedef signed __int64   int64_t;
 typedef unsigned __int64 uint64_t;\r
 
 
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* ndef _INTTYPES_H */
index 89f83c6b76d07387ee9ac1bfd54daa17f703d6ef..df1849226dc7fb659a1921d597a574c8d3806379 100755 (executable)
--- a/mkdmg.sh
+++ b/mkdmg.sh
@@ -65,7 +65,7 @@ echo Copying GUI
 rsync -r --exclude=.svn $source_path/gui ./tmpdmg/Osmo4.app/Contents/MacOS/
 
 echo Building DMG
-version=`grep '#define GPAC_VERSION ' $source_path/include/gpac/tools.h | cut -d '"' -f 2`
+version=`grep '#define GPAC_VERSION ' $source_path/include/gpac/version.h | cut -d '"' -f 2`
 
 cur_dir=`pwd`
 cd $source_path
index 7e313c2d0b04d5db2c5a01f8e904a6f40fb72dcb..6b5a461dc83e4f21534633e327590957a3d79ba8 100644 (file)
@@ -1,7 +1,15 @@
 include ../config.mak
 
 #all OS and lib independent
-PLUGDIRS=aac_in ac3_in audio_filter bifs_dec dummy_in soft_raster mp3_in isom_in odf_dec rtp_in timedtext img_in saf_in mpegts_in ismacryp mpd_in
+PLUGDIRS=aac_in ac3_in audio_filter bifs_dec dummy_in soft_raster mp3_in isom_in odf_dec rtp_in timedtext img_in saf_in ismacryp
+
+ifeq ($(DISABLE_DASH_CLIENT), no)
+PLUGDIRS+=mpd_in
+endif
+
+ifeq ($(DISABLE_MEDIA_IMPORT), no)
+PLUGDIRS+=mpegts_in 
+endif
 
 ifeq ($(DISABLE_SMGR), no)
 PLUGDIRS+=ctx_load svg_in
index 980c110b0344fd228a11d526a81507a15b596789..01ebf206bd1835a3527c0825705b59265a49831a 100644 (file)
@@ -47,11 +47,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_aac_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS)
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 3a74968ef2b7d4ac1104bab3f89b80d7f37ad4f9..01c450e4536171197cd8bb0947ef08dfc89938c0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AAC reader module
index fd5c0297a23de9a89f880c064c183836468412a5..f064014fea999bb158c761f82853ee41a6bd8932 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AAC reader module
@@ -100,14 +101,13 @@ static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd)
                        case GF_M4A_AAC_PS:
                                s_base_object_type = gf_stringizer(GF_M4A_AAC_PS);
                                base_object_type_error: /*error case*/
-                               GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error: unsupported %s format for stream %d\n", s_base_object_type, esd->ESID));
-                               return GF_NOT_SUPPORTED;
+                               GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error: unsupported %s format for stream %d - defaulting to AAC LC\n", s_base_object_type, esd->ESID));
                        default:
                                break;
                }
                a_cfg.base_object_type = GF_M4A_AAC_LC;
                a_cfg.has_sbr = 0;
-               a_cfg.nb_chan = 1;
+               a_cfg.nb_chan = a_cfg.nb_chan > 2 ? 1 : a_cfg.nb_chan;
 
                gf_m4a_write_config(&a_cfg, &dsi, &dsi_len);
                res = faacDecInit2(ctx->codec, (unsigned char *) dsi, dsi_len, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels);
index f7c146fbb78cb95b396bed0dda8cae1a85782c1c..59bb66f1f0f019b2a810221d7baa9d7f7cb26095 100644 (file)
@@ -44,11 +44,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index df933f7315d831e9257e2ebec6b2c55aa3e2dbbc..401886fbd0b7cf24971d4dedc4bf994e9799a0f6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AC3 reader module
index 265f088c1746d565310301577a5fc4812efeb15b..ac0750058b20d0295c07b529cfe7c36d316a97e8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AAC reader module
@@ -300,7 +301,7 @@ static u32 AC3_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd,
        /*media type query*/
        if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED;
        switch (esd->decoderConfig->objectTypeIndication) {
-       case 0xA5:
+       case GPAC_OTI_AUDIO_AC3:
                return GF_CODEC_SUPPORTED;
        }
        return GF_CODEC_NOT_SUPPORTED;
index 9f617d282ccd8ed742a6630a60e0100df97cdd3a..b34d1c82e7286857881790c06930bd520db766dc 100644 (file)
@@ -29,10 +29,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -lasound
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 2f5f809715bd782e5d4618e901c57cde94da5eea..840b5265ed4ed265508e65a6a8d3310c3258bd3a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / alsa audio output module
index 77ef22c5bd004dc0ac32ed6aca637754c34bbffa..32e6707c067f7e845477ff7cd568c9c6b76f5bb1 100644 (file)
@@ -57,10 +57,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 15f1146d254af0124ae817ece85fef5be790adf3..d0fb6385f9ca694703a2e67721af5fe289a58e5a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AMR decoder module
index bce7442f31beb7297a8880d146416064b1f2fed2..02fcf2a1a125ab73e71fea660e985e049b8711c3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AMR&EVRC&SMV reader module
index dac45b98efb5f95ef911e79968cca26d79f5714a..aef75dcab592a7d0b276850e24004ff239282715 100644 (file)
@@ -47,11 +47,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 682d2054ea3f8bd13b0a5edb2f654e19f50d5e33..997738c1ab337ef8b7552dbc7e30fd2e0f674bc3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AMR decoder module
index 123176b7b5827f3c1026c590964a22b7f0537f8a..390e42165af960a6d68b36bec4a4aad0c31ad893 100644 (file)
@@ -27,10 +27,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index b1830cc3e0ee278c40a17fb6f6844b7b271cc307..73251fc2d69a3acf0721eec672ef09a2f5323d58 100644 (file)
@@ -1,10 +1,10 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Telecom ParisTech 20010-
+ *                             Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
- *                             Authors: Jean Le Feuvre
  *
  *  This file is part of GPAC / sample audio filter module
  *
index 81456eec8f99447b837a6990185471680aa4a393..b78b7bc4239bd22ac16ced5fb7269784033a6cf0 100644 (file)
@@ -31,11 +31,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CXX) -w $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKLIBS)
 
-
-%.o: %.cpp
-       $(CXX) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 8d69650316b93b38a29da6e7099130f462fae01d..43f181ab5328a0016b72e64065a996b4aea401ca 100644 (file)
  */
 
 
+#include <avcap/avcap.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <gpac/modules/service.h>
 #include <gpac/modules/codec.h>
 /*for GF_STREAM_PRIVATE_SCENE definition*/
 #include <gpac/constants.h>
 #include <gpac/download.h>
 
+#ifdef __cplusplus
+}
+#endif
+
+
 #if !defined(__GNUC__)&& (defined(_WIN32_WCE) || defined (WIN32))
 #  pragma comment(lib, "strmiids")
 #ifdef _DEBUG
@@ -43,8 +55,6 @@
 #endif
 
 
-
-#include <avcap/avcap.h>
 using namespace avcap;
 
 class GPACCaptureHandler : public CaptureHandler
index 516bd857f42fa3c63c7d75369f9d0af0ec666b8b..3218e4d582a55472ae1582884e334fa5fe84f1b0 100644 (file)
@@ -35,10 +35,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index ea08debc61208c3ae08cb2835be2898c51c5b814..3f9bf357e108998f36c90b46fe792a2cd574a123 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS decoder module
index ac62a0b810446cf8e11ef079d0d5b2b66681d9ad..b3220309c3d42928723c13d5a5ff9e0afb843857 100644 (file)
@@ -34,11 +34,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ctx_load-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 0a273e8f60dd3128b0d87cc897a4ea1603d8c4f4..87e708261ac781e79030e1716eeb6a45e45c7790 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GPAC Scene Context loader module
index 6c389b05b36144955dbbe53bede0fbd01feda734..8acb0a410d46bbecd9f8bf4f164fd5b4c5249a86 100644 (file)
@@ -31,11 +31,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 06e4209f7cd19709f6c22a12c5d4c923ce1d841d..5846395dc4de81e564e9562dd2d7676597795981 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Dummy input module
index 48ec61cf029dc49ff90237a471007489ff2d8bab..764f435941d878b62e69d213c5f3588ef5c4a49a 100644 (file)
@@ -32,10 +32,6 @@ all: $(LIB)
 
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LDFLAGS) -L../../bin/gcc -lgpac
-                                                                                               
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
 
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
index 174f9347e7383ed9c9369569cbbcdf292c867698..622df2f686fe02a0cb38c5cda2c89ea294a201b4 100755 (executable)
@@ -1,7 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                             Copyright (c) 2005-20XX Telecom-Paristech
+ *                     Authors: Romain Bouqueau - Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectFB video output module
index 30ac3cf164db1d3b4954b337d2fccd873c1fa0b7..2dfa1fa75a29c03f3f94756d6ee7fd3099db649d 100755 (executable)
@@ -1,7 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                             Copyright (c) 2005-20XX Telecom-Paristech
+ *                     Authors: Romain Bouqueau - Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectFB video output module
index fa536ed424e5aa497fe6f5cb84a5a17554711559..e87906ca3f7cedaa3c0109465302a9e11d3fc0ad 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                             Copyright (c) 2005-20XX Telecom-Paristech
+ *                     Authors: Romain Bouqueau - Jean Le Feuvre \r
+ *                     Copyright (c) Telecom ParisTech 2010-2012\r
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectFB video output module
@@ -552,7 +553,7 @@ u32 DirectFBVid_ProcessMessageQueueWrapper(DirectFBVidCtx *ctx, u8 *type, u32 *f
                                                *button = GF_MOUSE_MIDDLE;
                                                break;
                                        default:
-                                               printf("in here for others\n");
+                                               //fprintf(stderr, "in here for others\n");
                                                break;
                                }
                                break;
@@ -617,47 +618,47 @@ u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 gpacpf)
  **/
 void directfb_translate_key(DFBInputDeviceKeyIdentifier DirectFBkey, u32 *flags, u32 *key_code)
 {
-       //~ printf("DirectFBkey=%d\n", DirectFBkey);
+       //~ fprintf(stderr, "DirectFBkey=%d\n", DirectFBkey);
 
        switch (DirectFBkey) {
                case DIKI_BACKSPACE:
                        *key_code = GF_KEY_BACKSPACE; 
-                       //~ printf("DIKI_BACKSPACE\n"); 
+                       //~ fprintf(stderr, "DIKI_BACKSPACE\n"); 
                        break;
                case DIKI_TAB:
                        *key_code = GF_KEY_TAB; 
-                       //~ printf("DIKI_TAB\n"); 
+                       //~ fprintf(stderr, "DIKI_TAB\n"); 
                        break;
                case DIKI_ENTER:
                        *key_code = GF_KEY_ENTER; 
-                       //~ printf("DIKI_ENTER\n"); 
+                       //~ fprintf(stderr, "DIKI_ENTER\n"); 
                        break;
                case DIKI_ESCAPE:
                        *key_code = GF_KEY_ESCAPE; 
-                       //~ printf("DIKI_ESCAPE\n"); 
+                       //~ fprintf(stderr, "DIKI_ESCAPE\n"); 
                        break;
                case DIKI_SPACE:
                        *key_code = GF_KEY_SPACE; 
-                       //~ printf("DIKI_SPACE\n"); 
+                       //~ fprintf(stderr, "DIKI_SPACE\n"); 
                        break;
                case DIKI_SHIFT_L:
                case DIKI_SHIFT_R:
                        *key_code = GF_KEY_SHIFT; 
-                       //~ printf("DIKI_SHIFT_R/DIKI_SHIFT_L\n"); 
+                       //~ fprintf(stderr, "DIKI_SHIFT_R/DIKI_SHIFT_L\n"); 
                        break;
                case DIKI_CONTROL_L:
                case DIKI_CONTROL_R:
                        *key_code = GF_KEY_CONTROL; 
-                       //~ printf("DIKI_CONTROL_L/DIKI_CONTROL_R\n"); 
+                       //~ fprintf(stderr, "DIKI_CONTROL_L/DIKI_CONTROL_R\n"); 
                        break;
                case DIKI_ALT_L:
                case DIKI_ALT_R:
                        *key_code = GF_KEY_ALT; 
-                       //~ printf("DIKI_ALT_L/DIKI_ALT_R\n"); 
+                       //~ fprintf(stderr, "DIKI_ALT_L/DIKI_ALT_R\n"); 
                        break;
                case DIKI_CAPS_LOCK:
                        *key_code = GF_KEY_CAPSLOCK; 
-                       //~ printf("DIKI_CAPS_LOCK\n"); 
+                       //~ fprintf(stderr, "DIKI_CAPS_LOCK\n"); 
                        break;
                case DIKI_META_L:
                case DIKI_META_R:
@@ -671,23 +672,23 @@ void directfb_translate_key(DFBInputDeviceKeyIdentifier DirectFBkey, u32 *flags,
                /* alphabets */
                case DIKI_A:
                        *key_code = GF_KEY_A; 
-                       //~ printf("DIKI_A\n"); 
+                       //~ fprintf(stderr, "DIKI_A\n"); 
                        break;
                case DIKI_B:
                        *key_code = GF_KEY_B; 
-                       //~ printf("DIKI_B\n"); 
+                       //~ fprintf(stderr, "DIKI_B\n"); 
                        break;
                case DIKI_C:
                        *key_code = GF_KEY_C; 
-                       //~ printf("DIKI_C\n"); 
+                       //~ fprintf(stderr, "DIKI_C\n"); 
                        break;
                case DIKI_D:
                        *key_code = GF_KEY_D; 
-                       //~ printf("DIKI_D\n"); 
+                       //~ fprintf(stderr, "DIKI_D\n"); 
                        break;
                case DIKI_E:
                        *key_code = GF_KEY_E; 
-                       //~ printf("DIKI_E\n"); 
+                       //~ fprintf(stderr, "DIKI_E\n"); 
                        break;
                case DIKI_F:
                        *key_code = GF_KEY_F; break;
index 1b9def076f2fd5b9995248c605a7f711d1b87c65..c16547c0b1ed9a83f1a72f616d1c6b81de4ed4be 100644 (file)
@@ -1,13 +1,10 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Ivica Arsov, Jean Le Feuvre
+ *                     Copyright (c) Mines-Telecom 2009-
  *                                     All rights reserved
  *
- *     Created by NGO Van Luyen / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010
- * nvluyen81@gmail.com
- *
  *  This file is part of GPAC / Wrapper
  *
  *  GPAC is free software; you can redistribute it and/or modify
index 26148bf6bca421b5d86a448f5ae956e7828ce57e..291f1085e3e9efbbf00ff5f70a5b1c64497737f5 100644 (file)
@@ -1,12 +1,10 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Ivica Arsov, Jean Le Feuvre
+ *                     Copyright (c) Mines-Telecom 2009-
  *                                     All rights reserved
  *
- *     Created by Arsov Ivica / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010
- *
  *  This file is part of GPAC / Wrapper
  *
  *  GPAC is free software; you can redistribute it and/or modify
index 813ee82b5983ae9529b6de71c7279dfbcbc3dc4c..dc80f3146437c96940d97c92daa88343753ed452 100644 (file)
@@ -1,12 +1,10 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Ivica Arsov, Jean Le Feuvre
+ *                     Copyright (c) Mines-Telecom 2009-
  *                                     All rights reserved
  *
- *     Created by Arsov Ivica / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010
- *
  *  This file is part of GPAC / Wrapper
  *
  *  GPAC is free software; you can redistribute it and/or modify
index ec6cbd79d2439ad6c59d89259130e8fccf26c984..bf210a30b16d720388cd4e5337f93539eb513d11 100644 (file)
-/*
- *                     GPAC - Multimedia Framework C SDK
- *
- *                     Authors: Ivica Arsov
- *                     Copyright (c) Institut Telecom 2011-20XX
- *                                     All rights reserved
- *
- *  This file is part of GPAC / Android camera module
- *
- *  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.
- *
- */
-
-#include <gpac/terminal.h>
-#include <gpac/internal/terminal_dev.h>
-#include <gpac/modules/codec.h>
-#include <gpac/constants.h>
-#include <gpac/modules/service.h>
-#include <gpac/thread.h>
-#include <gpac/media_tools.h>
-
-#include <jni.h>
-#include <android/log.h>
-
-#define LOG_TAG "ANDROID_CAMERA"
-#ifdef ANDROID
-#  define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
-#  define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
-#else
-#  define QUOTEME_(x) #x
-#  define QUOTEME(x) QUOTEME_(x)
-#  define LOGI(...) printf("I/" LOG_TAG " (" __FILE__ ":" QUOTEME(__LINE__) "): " __VA_ARGS__)
-#  define LOGE(...) printf("E/" LOG_TAG "(" ")" __VA_ARGS__)
-#endif
-
-static JavaVM* javaVM = 0;
-static jclass camCtrlClass;
-static jmethodID cid;
-static jmethodID startCamera;
-static jmethodID stopCamera;
-static jmethodID startProcessing;
-static jmethodID stopProcessing;
-static jmethodID getImageFormat;
-static jmethodID getImageHeight;
-static jmethodID getImageWidth;
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-       JNIEnv* env = 0;
-  javaVM = vm;
-
-       if ( (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2) != JNI_OK )
-               return -1;
-
-       // Get the class and its methods in the main env
-
-       // Get the CameraController class
-       // This is just a local refenrece. Cannot be used in the other JNI calls.
-       camCtrlClass = (*env)->FindClass(env, "com/gpac/Osmo4/Preview");
-       if (camCtrlClass == 0)
-       {
-               LOGE("CameraController class = null [myCamera.c, startCameraNative()]");
-               return -1;
-       }
-
-       // Get Global Reference to be able to use the class
-       camCtrlClass = (*env)->NewGlobalRef(env, camCtrlClass);
-       if ( camCtrlClass == 0 )
-       {
-               LOGE("[MPEG-V_IN] Cannot create Global Reference\n");
-               return -1;
-       }
-
-       // Get the method ID for the CameraController constructor.
-       cid = (*env)->GetMethodID(env, camCtrlClass, "<init>", "()V");
-       if (cid == 0)
-       {
-               LOGE("Method ID for CameraController constructor is null [myCamera.c, startCameraNative()]");
-               return -1;
-       }
-
-       // Get startCamera() method from class CameraController
-       startCamera = (*env)->GetMethodID(env, camCtrlClass, "initializeCamera", "(Z)Z");
-       if (startCamera == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function startCamera not found");
-               return -1;
-       }
-
-       stopCamera = (*env)->GetMethodID(env, camCtrlClass, "stopCamera", "()V");
-       if (stopCamera == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function stopCamera not found");
-               return -1;
-       }
-
-       startProcessing = (*env)->GetMethodID(env, camCtrlClass, "resumePreview", "()V");
-       if (startProcessing == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function startProcessing not found");
-               return -1;
-       }
-
-       stopProcessing = (*env)->GetMethodID(env, camCtrlClass, "pausePreview", "()V");
-       if (stopProcessing == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function stopProcessing not found");
-               return -1;
-       }
-
-       getImageFormat = (*env)->GetMethodID(env, camCtrlClass, "getPreviewFormat", "()I");
-       if (getImageFormat == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function getImageFormat not found");
-               return -1;
-       }
-
-       getImageHeight = (*env)->GetMethodID(env, camCtrlClass, "getImageHeight", "()I");
-       if (getImageHeight == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function getImageHeight not found");
-               return -1;
-       }
-
-       getImageWidth = (*env)->GetMethodID(env, camCtrlClass, "getImageWidth", "()I");
-       if (getImageWidth == 0)
-       {
-               LOGE("[ANDROID_CAMERA] Function getImageWidth not found");
-               return -1;
-       }
-
-       return JNI_VERSION_1_2;
-}
-//----------------------------------------------------------------------
-JavaVM* GetJavaVM()
-{
-    return javaVM;
-}
-
-JNIEnv* GetEnv()
-{
-       JNIEnv* env;
-       if ( (*GetJavaVM())->GetEnv(GetJavaVM(), (void**)&env, JNI_VERSION_1_2) != JNI_OK )
-               return NULL;
-
-       return env;
-}
-
-void JNI_OnUnload(JavaVM *vm, void *reserved)
-{
-       JNIEnv* env = 0;
-       
-       if ( (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_2) != JNI_OK )
-               return;
-       
-       (*env)->DeleteGlobalRef(env, camCtrlClass);
-}
-//----------------------------------------------------------------------
-
-
-#define CAM_PIXEL_FORMAT GF_PIXEL_NV21
-//GF_PIXEL_RGB_32
-#define CAM_PIXEL_SIZE 1.5f
-//4
-#define CAM_WIDTH 640
-#define CAM_HEIGHT 480
-
-//GF_PIXEL_RGB_24;
-
-typedef struct
-{
-       GF_InputService *input;
-       /*the service we're responsible for*/
-       GF_ClientService *service;
-       LPNETCHANNEL* channel;
-
-       /*input file*/
-       u32 time_scale;
-
-       u32 base_track_id;
-
-       struct _tag_terminal *term;
-
-       u32 cntr;
-
-       u32 width;
-       u32 height;
-
-       Bool started;
-
-       JNIEnv* env;
-       u8 isAttached;
-       jclass camCtrlClass;
-       jmethodID cid;
-       jobject camCtrlObj;
-       jmethodID startCamera;
-       jmethodID stopCamera;
-       jmethodID startProcessing;
-       jmethodID stopProcessing;
-       jmethodID getImageFormat;
-       jmethodID getImageHeight;
-       jmethodID getImageWidth;
-
-} ISOMReader;
-
-ISOMReader* globReader;
-
-void loadCameraControler(ISOMReader *read);
-void camStartCamera(ISOMReader *read);
-void camStopCamera(ISOMReader *read);
-
-Bool CAM_CanHandleURL(GF_InputService *plug, const char *url)
-{
-       if (!strnicmp(url, "hw://camera", 11)) return 1;
-
-       return 0;
-}
-
-void unloadCameraControler(ISOMReader *read)
-{
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] unloadCameraControler: %d\n", gf_th_id()));
-       if ( read->isAttached )
-       {
-               //(*rc->env)->PopLocalFrame(rc->env, NULL);
-               (*GetJavaVM())->DetachCurrentThread(GetJavaVM());
-               read->isAttached = 0;
-       }
-
-       read->env = NULL;
-}
-
-u32 unregisterFunc(void* data)
-{
-       unloadCameraControler(globReader);
-}
-
-void loadCameraControler(ISOMReader *read)
-{
-       JNIEnv* env = NULL;
-       jint res = 0;
-
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] loadCameraControler: %d\n", gf_th_id()));
-
-       // Get the JNI interface pointer
-       res = (*GetJavaVM())->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2);
-       if ( res == JNI_EDETACHED )
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] The current thread is not attached to the VM, assuming native thread\n"));
-               if ( res = (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL) )
-               {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] Attach current thread failed: %d\n", res));
-                       return;
-               }
-               gf_register_before_exit_function(gf_th_current(), unregisterFunc);
-               read->isAttached = 1;
-               //(*rc->env)->PushLocalFrame(rc->env, 2);
-       }
-       else 
-               if ( res == JNI_EVERSION )
-               {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] The specified version is not supported\n"));
-                       return;
-               }
-
-       read->env = env;
-       read->camCtrlClass = camCtrlClass;
-       read->cid = cid;
-       read->startCamera = startCamera;
-       read->stopCamera = stopCamera;
-       read->startProcessing = startProcessing;
-       read->stopProcessing = stopProcessing;
-       read->getImageFormat = getImageFormat;
-       read->getImageHeight = getImageHeight;
-       read->getImageWidth = getImageWidth;
-
-       // Create the object.
-       read->camCtrlObj = (*env)->NewObject(env, read->camCtrlClass, read->cid);
-       if (read->camCtrlObj == 0)
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("CameraController object creation failed. [myCamera.c, startCameraNative()]"));
-               return;
-       }
-}
-
-GF_Err CAM_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
-{
-       ISOMReader *read;
-       if (!plug || !plug->priv || !serv) return GF_SERVICE_ERROR;
-       read = (ISOMReader *) plug->priv;
-
-       read->input = plug;
-       read->service = serv;
-       read->base_track_id = 1;
-       read->time_scale = 1000;
-
-       read->term = serv->term;
-
-       loadCameraControler(read);
-
-       /*reply to user*/
-       gf_term_on_connect(serv, NULL, GF_OK);
-       //if (read->no_service_desc) isor_declare_objects(read);
-
-       return GF_OK;
-}
-
-GF_Err CAM_CloseService(GF_InputService *plug)
-{
-       GF_Err reply;
-       ISOMReader *read;
-       if (!plug || !plug->priv) return GF_SERVICE_ERROR;
-       read = (ISOMReader *) plug->priv;
-       reply = GF_OK;
-
-       (*GetEnv())->DeleteLocalRef( GetEnv(), read->camCtrlObj ); 
-
-       //unloadCameraControler(read);
-
-       gf_term_on_disconnect(read->service, NULL, reply);
-       return GF_OK;
-}
-
-u32 getWidth(ISOMReader *read);
-u32 getHeight(ISOMReader *read);
-
-static GF_Descriptor *CAM_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url)
-{
-       u32 trackID;
-       GF_ESD *esd;
-       ISOMReader *read;
-       GF_ObjectDescriptor *od;
-       GF_BitStream *bs;
-       char *buf;
-       u32 buf_size;
-       if (!plug || !plug->priv) return NULL;
-       read = (ISOMReader *) plug->priv;
-
-       trackID = 0;
-       trackID = read->base_track_id;
-       read->base_track_id = 0;
-
-       if (trackID && (expect_type==GF_MEDIA_OBJECT_VIDEO) ) {
-               od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
-               od->objectDescriptorID = 1;
-
-               esd = gf_odf_desc_esd_new(0);
-               esd->slConfig->timestampResolution = 1000;
-               esd->decoderConfig->streamType = GF_STREAM_VISUAL;
-               esd->ESID = 1;
-               esd->decoderConfig->objectTypeIndication = GPAC_OTI_RAW_MEDIA_STREAM;
-               
-               bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
-
-               read->width = getWidth(read);
-               read->height = getHeight(read);
-
-               gf_bs_write_u32(bs, CAM_PIXEL_FORMAT); // fourcc
-               gf_bs_write_u16(bs, read->width); // width
-               gf_bs_write_u16(bs, read->height); // height
-               gf_bs_write_u32(bs, read->width * read->height * CAM_PIXEL_SIZE); // framesize
-               gf_bs_write_u32(bs, read->width * CAM_PIXEL_SIZE); // stride
-
-               gf_bs_align(bs);
-               gf_bs_get_content(bs, &buf, &buf_size);
-               gf_bs_del(bs);
-
-               esd->decoderConfig->decoderSpecificInfo->data = buf;
-               esd->decoderConfig->decoderSpecificInfo->dataLength = buf_size;
-
-               gf_list_add(od->ESDescriptors, esd);
-               return (GF_Descriptor *) od;
-       }
-
-       return NULL;
-}
-
-
-
-
-GF_Err CAM_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream)
-{
-       GF_Err e;
-       ISOMReader *read;
-       if (!plug || !plug->priv) return GF_SERVICE_ERROR;
-       read = (ISOMReader *) plug->priv;
-
-       e = GF_OK;
-       if (upstream) {
-               e = GF_ISOM_INVALID_FILE;
-       }
-
-       read->channel = channel;
-
-       camStartCamera(read);
-
-       gf_term_on_connect(read->service, channel, e);
-       return e;
-}
-
-GF_Err CAM_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel)
-{
-       GF_Err e;
-       ISOMReader *read;
-       if (!plug || !plug->priv) return GF_SERVICE_ERROR;
-       read = (ISOMReader *) plug->priv;
-
-       e = GF_OK;
-
-       camStopCamera(read);
-
-       gf_term_on_disconnect(read->service, channel, e);
-       return e;
-}
-
-int* decodeYUV420SP( char* yuv420sp, int width, int height)
-{
-       int frameSize = width * height;
-       int j, yp, uvp, i, y, y1192, r, g, b, u, v;
-       int ti, tj;
-
-       int* rgb = (int*)gf_malloc(width*height*4);
-       for (j = 0, yp = 0, tj=height-1; j < height; j++, tj--)
-       {
-               uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
-               for (i = 0, ti=0; i < width; i++, yp++, ti+=width)
-               {
-                       y = (0xff & ((int) yuv420sp[yp])) - 16;
-                       if (y < 0) y = 0;
-                       if ((i & 1) == 0)
-                       {
-                               v = (0xff & yuv420sp[uvp++]) - 128;
-                               u = (0xff & yuv420sp[uvp++]) - 128;
-                       }
-
-                       y1192 = 1192 * y;
-                       r = (y1192 + 1634 * v);
-                       g = (y1192 - 833 * v - 400 * u);
-                       b = (y1192 + 2066 * u);
-
-                       if (r < 0)
-                               r = 0;
-                       else if (r > 262143)
-                               r = 262143;
-                       if (g < 0)
-                               g = 0;
-                       else if (g > 262143)
-                               g = 262143;
-                       if (b < 0)
-                               b = 0;
-                       else if (b > 262143)
-                               b = 262143;
-
-                       rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
-                                               | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
-//                     rgb[ti+tj] = 0xff000000 | ((r << 6) & 0xff0000)
-//                                     | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
-               }
-       }
-       return rgb;
-}
-
-void Java_com_gpac_Osmo4_Preview_processFrameBuf( JNIEnv* env, jobject thiz, jbyteArray arr)
-{
-       u8* data;
-       u32 datasize;
-       ISOMReader* ctx = globReader;
-       GF_SLHeader hdr;
-       u32 cts = 0;
-       u32 convTime = 0;
-       u32 j = 0;
-       jbyte *jdata;
-       jsize len;
-
-       if ( ctx->started )
-       {
-               len = (*env)->GetArrayLength(env, arr);
-               jdata = (*env)->GetByteArrayElements(env,arr,0);
-
-               convTime = gf_term_get_time(ctx->term);
-
-               data = (u8*)jdata;//(u8*)decodeYUV420SP((char*)jdata, ctx->width, ctx->height); //
-               datasize = len;//ctx->width * ctx->height * CAM_PIXEL_SIZE;//
-
-               cts = gf_term_get_time(ctx->term);
-
-               convTime = cts - convTime;
-
-               memset(&hdr, 0, sizeof(hdr));
-               hdr.compositionTimeStampFlag = 1;
-               hdr.compositionTimeStamp = cts;
-               gf_term_on_sl_packet(ctx->service, ctx->channel, (void*)data, datasize, &hdr, GF_OK);
-
-               //gf_free(data);
-
-               (*env)->ReleaseByteArrayElements(env,arr,jdata,JNI_ABORT);
-
-               //GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Camera Frame Sent %d\n", gf_sys_clock()));
-       }
-}
-
-void CallCamMethod(ISOMReader *read, jmethodID methodID)
-{
-       JNIEnv* env = NULL;
-       jint res = 0;
-       u8 isAttached = 0;
-
-       // Get the JNI interface pointer
-       res = (*GetJavaVM())->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2);
-       if ( res == JNI_EDETACHED )
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] The current thread is not attached to the VM, assuming native thread\n"));
-               if ( res = (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL) )
-               {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] Attach current thread failed: %d\n", res));
-                       return;
-               }
-               if ( env != read->env )
-                       isAttached = 1;
-       }
-
-       (*env)->CallNonvirtualVoidMethod(env, read->camCtrlObj, read->camCtrlClass, methodID);
-
-       if (isAttached)
-       {       
-               (*GetJavaVM())->DetachCurrentThread(GetJavaVM());
-       }
-}
-
-void camStartCamera(ISOMReader *read)
-{
-       JNIEnv* env = NULL;
-       jboolean isPortrait = JNI_FALSE;
-
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] startCamera: %d\n", gf_th_id()));
-
-       // Get the JNI interface pointer
-       env = read->env;
-
-       (*env)->CallNonvirtualBooleanMethod(env, read->camCtrlObj, read->camCtrlClass, read->startCamera, isPortrait);
-}
-
-void camStopCamera(ISOMReader *read)
-{
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] stopCamera: %d\n", gf_th_id()));
-
-       CallCamMethod(read, read->stopCamera);
-}
-
-void pauseCamera(ISOMReader *read)
-{
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] pauseCamera: %d\n", gf_th_id()));
-
-       read->started = 0;
-       CallCamMethod(read, read->stopProcessing);
-}
-
-void resumeCamera(ISOMReader *read)
-{
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] resumeCamera: %d\n", gf_th_id()));
-
-       read->started = 1;
-       CallCamMethod(read, read->startProcessing);
-}
-
-u32 getWidth(ISOMReader *read)
-{
-       JNIEnv* env = NULL;
-
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] getWidth: %d\n", gf_th_id()));
-
-       // Get the JNI interface pointer
-       env = read->env;
-
-       return (*env)->CallNonvirtualIntMethod(env, read->camCtrlObj, read->camCtrlClass, read->getImageWidth);
-}
-
-u32 getHeight(ISOMReader *read)
-{
-       JNIEnv* env = NULL;
-
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] getHeight: %d\n", gf_th_id()));
-
-       // Get the JNI interface pointer
-       env = read->env;
-
-       return (*env)->CallNonvirtualIntMethod(env, read->camCtrlObj, read->camCtrlClass, read->getImageHeight);
-}
-
-GF_Err CAM_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
-{
-       ISOMReader *read;
-       GF_BitStream *bs;
-       char *buf;
-       u32 buf_size;
-       if (!plug || !plug->priv || !com) return GF_SERVICE_ERROR;
-       read = (ISOMReader *) plug->priv;
-
-       if (com->command_type==GF_NET_SERVICE_INFO) {
-               return GF_OK;
-       }
-       if (com->command_type==GF_NET_SERVICE_HAS_AUDIO) {
-               return GF_NOT_SUPPORTED;
-       }
-       if (!com->base.on_channel) return GF_NOT_SUPPORTED;
-
-       switch (com->command_type) {
-       case GF_NET_CHAN_INTERACTIVE:
-               return GF_OK;
-       case GF_NET_CHAN_BUFFER:
-               com->buffer.max = com->buffer.min = 0;
-               return GF_OK;
-       case GF_NET_CHAN_PLAY:
-               resumeCamera(read);
-               return GF_OK;
-       case GF_NET_CHAN_STOP:
-               pauseCamera(read);
-               return GF_OK;
-       /*nothing to do on MP4 for channel config*/
-       case GF_NET_CHAN_CONFIG:
-               return GF_OK;
-       case GF_NET_CHAN_GET_PIXEL_AR:
-               return 1<<16;//gf_isom_get_pixel_aspect_ratio(read->mov, ch->track, 1, &com->par.hSpacing, &com->par.vSpacing);
-       case GF_NET_CHAN_GET_DSI:
-               {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Cam get DSI\n"));
-                       /*it may happen that there are conflicting config when using ESD URLs...*/
-                       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
-
-                       read->width = getWidth(read);
-                       read->height = getHeight(read);
-
-                       gf_bs_write_u32(bs, CAM_PIXEL_FORMAT); // fourcc
-                       gf_bs_write_u16(bs, read->width); // width
-                       gf_bs_write_u16(bs, read->height); // height
-                       gf_bs_write_u32(bs, read->width * read->height * CAM_PIXEL_SIZE); // framesize
-                       gf_bs_write_u32(bs, read->width * CAM_PIXEL_SIZE); // stride
-
-                       gf_bs_align(bs);
-                       gf_bs_get_content(bs, &buf, &buf_size);
-                       gf_bs_del(bs);
-
-                       com->get_dsi.dsi = buf;
-                       com->get_dsi.dsi_len = buf_size;
-                       return GF_OK;
-               }
-       }
-       return GF_NOT_SUPPORTED;
-}
-
-GF_InputService *CAM_client_load()
-{
-       ISOMReader *reader;
-       GF_InputService *plug;
-       GF_SAFEALLOC(plug, GF_InputService);
-       GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC Camera Plugin", "gpac distribution")
-       plug->CanHandleURL = CAM_CanHandleURL;
-       plug->ConnectService = CAM_ConnectService;
-       plug->CloseService = CAM_CloseService;
-       plug->GetServiceDescriptor = CAM_GetServiceDesc;
-       plug->ConnectChannel = CAM_ConnectChannel;
-       plug->DisconnectChannel = CAM_DisconnectChannel;
-       plug->ServiceCommand = CAM_ServiceCommand;
-
-       GF_SAFEALLOC(reader, ISOMReader);
-       plug->priv = reader;
-       globReader = reader;
-       return plug;
-}
-
-void CAM_client_del(GF_BaseInterface *bi)
-{
-       GF_InputService *plug = (GF_InputService *) bi;
-       ISOMReader *read = (ISOMReader *)plug->priv;
-
-       gf_free(read);
-       gf_free(bi);
-}
-
-GF_EXPORT
-const u32 *QueryInterfaces()
-{
-       static u32 si [] = {
-               GF_NET_CLIENT_INTERFACE,
-               0
-       };
-       return si;
-}
-
-GF_EXPORT
-GF_BaseInterface *LoadInterface(u32 InterfaceType)
-{
-       if (InterfaceType == GF_NET_CLIENT_INTERFACE)
-               return (GF_BaseInterface *)CAM_client_load();
-       return NULL;
-}
-
-GF_EXPORT
-void ShutdownInterface(GF_BaseInterface *ifce)
-{
-       switch (ifce->InterfaceType) {
-       case GF_NET_CLIENT_INTERFACE: CAM_client_del(ifce); break;
-       }
-}
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Ivica Arsov, Jean Le Feuvre\r
+ *                     Copyright (c) Mines-Telecom 2009-\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / Android camera module\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *\r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ *\r
+ */\r
+\r
+#include <gpac/terminal.h>\r
+#include <gpac/internal/terminal_dev.h>\r
+#include <gpac/modules/codec.h>\r
+#include <gpac/constants.h>\r
+#include <gpac/modules/service.h>\r
+#include <gpac/thread.h>\r
+#include <gpac/media_tools.h>\r
+\r
+#include <jni.h>\r
+#include <android/log.h>\r
+\r
+#define LOG_TAG "ANDROID_CAMERA"\r
+#ifdef ANDROID\r
+#  define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)\r
+#  define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)\r
+#else\r
+#  define QUOTEME_(x) #x\r
+#  define QUOTEME(x) QUOTEME_(x)\r
+#  define LOGI(...) fprintf(stderr, "I/" LOG_TAG " (" __FILE__ ":" QUOTEME(__LINE__) "): " __VA_ARGS__)\r
+#  define LOGE(...) fprintf(stderr, "E/" LOG_TAG "(" ")" __VA_ARGS__)\r
+#endif\r
+\r
+static JavaVM* javaVM = 0;\r
+static jclass camCtrlClass;\r
+static jmethodID cid;\r
+static jmethodID startCamera;\r
+static jmethodID stopCamera;\r
+static jmethodID startProcessing;\r
+static jmethodID stopProcessing;\r
+static jmethodID getImageFormat;\r
+static jmethodID getImageHeight;\r
+static jmethodID getImageWidth;\r
+\r
+jint JNI_OnLoad(JavaVM* vm, void* reserved)\r
+{\r
+       JNIEnv* env = 0;\r
+  javaVM = vm;\r
+\r
+       if ( (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2) != JNI_OK )\r
+               return -1;\r
+\r
+       // Get the class and its methods in the main env\r
+\r
+       // Get the CameraController class\r
+       // This is just a local refenrece. Cannot be used in the other JNI calls.\r
+       camCtrlClass = (*env)->FindClass(env, "com/gpac/Osmo4/Preview");\r
+       if (camCtrlClass == 0)\r
+       {\r
+               LOGE("CameraController class = null [myCamera.c, startCameraNative()]");\r
+               return -1;\r
+       }\r
+\r
+       // Get Global Reference to be able to use the class\r
+       camCtrlClass = (*env)->NewGlobalRef(env, camCtrlClass);\r
+       if ( camCtrlClass == 0 )\r
+       {\r
+               LOGE("[MPEG-V_IN] Cannot create Global Reference\n");\r
+               return -1;\r
+       }\r
+\r
+       // Get the method ID for the CameraController constructor.\r
+       cid = (*env)->GetMethodID(env, camCtrlClass, "<init>", "()V");\r
+       if (cid == 0)\r
+       {\r
+               LOGE("Method ID for CameraController constructor is null [myCamera.c, startCameraNative()]");\r
+               return -1;\r
+       }\r
+\r
+       // Get startCamera() method from class CameraController\r
+       startCamera = (*env)->GetMethodID(env, camCtrlClass, "initializeCamera", "(Z)Z");\r
+       if (startCamera == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function startCamera not found");\r
+               return -1;\r
+       }\r
+\r
+       stopCamera = (*env)->GetMethodID(env, camCtrlClass, "stopCamera", "()V");\r
+       if (stopCamera == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function stopCamera not found");\r
+               return -1;\r
+       }\r
+\r
+       startProcessing = (*env)->GetMethodID(env, camCtrlClass, "resumePreview", "()V");\r
+       if (startProcessing == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function startProcessing not found");\r
+               return -1;\r
+       }\r
+\r
+       stopProcessing = (*env)->GetMethodID(env, camCtrlClass, "pausePreview", "()V");\r
+       if (stopProcessing == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function stopProcessing not found");\r
+               return -1;\r
+       }\r
+\r
+       getImageFormat = (*env)->GetMethodID(env, camCtrlClass, "getPreviewFormat", "()I");\r
+       if (getImageFormat == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function getImageFormat not found");\r
+               return -1;\r
+       }\r
+\r
+       getImageHeight = (*env)->GetMethodID(env, camCtrlClass, "getImageHeight", "()I");\r
+       if (getImageHeight == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function getImageHeight not found");\r
+               return -1;\r
+       }\r
+\r
+       getImageWidth = (*env)->GetMethodID(env, camCtrlClass, "getImageWidth", "()I");\r
+       if (getImageWidth == 0)\r
+       {\r
+               LOGE("[ANDROID_CAMERA] Function getImageWidth not found");\r
+               return -1;\r
+       }\r
+\r
+       return JNI_VERSION_1_2;\r
+}\r
+//----------------------------------------------------------------------\r
+JavaVM* GetJavaVM()\r
+{\r
+    return javaVM;\r
+}\r
+\r
+JNIEnv* GetEnv()\r
+{\r
+       JNIEnv* env;\r
+       if ( (*GetJavaVM())->GetEnv(GetJavaVM(), (void**)&env, JNI_VERSION_1_2) != JNI_OK )\r
+               return NULL;\r
+\r
+       return env;\r
+}\r
+\r
+void JNI_OnUnload(JavaVM *vm, void *reserved)\r
+{\r
+       JNIEnv* env = 0;\r
+       \r
+       if ( (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_2) != JNI_OK )\r
+               return;\r
+       \r
+       (*env)->DeleteGlobalRef(env, camCtrlClass);\r
+}\r
+//----------------------------------------------------------------------\r
+\r
+\r
+#define CAM_PIXEL_FORMAT GF_PIXEL_NV21\r
+//GF_PIXEL_RGB_32\r
+#define CAM_PIXEL_SIZE 1.5f\r
+//4\r
+#define CAM_WIDTH 640\r
+#define CAM_HEIGHT 480\r
+\r
+//GF_PIXEL_RGB_24;\r
+\r
+typedef struct\r
+{\r
+       GF_InputService *input;\r
+       /*the service we're responsible for*/\r
+       GF_ClientService *service;\r
+       LPNETCHANNEL* channel;\r
+\r
+       /*input file*/\r
+       u32 time_scale;\r
+\r
+       u32 base_track_id;\r
+\r
+       struct _tag_terminal *term;\r
+\r
+       u32 cntr;\r
+\r
+       u32 width;\r
+       u32 height;\r
+\r
+       Bool started;\r
+\r
+       JNIEnv* env;\r
+       u8 isAttached;\r
+       jclass camCtrlClass;\r
+       jmethodID cid;\r
+       jobject camCtrlObj;\r
+       jmethodID startCamera;\r
+       jmethodID stopCamera;\r
+       jmethodID startProcessing;\r
+       jmethodID stopProcessing;\r
+       jmethodID getImageFormat;\r
+       jmethodID getImageHeight;\r
+       jmethodID getImageWidth;\r
+\r
+} ISOMReader;\r
+\r
+ISOMReader* globReader;\r
+\r
+void loadCameraControler(ISOMReader *read);\r
+void camStartCamera(ISOMReader *read);\r
+void camStopCamera(ISOMReader *read);\r
+\r
+Bool CAM_CanHandleURL(GF_InputService *plug, const char *url)\r
+{\r
+       if (!strnicmp(url, "hw://camera", 11)) return 1;\r
+\r
+       return 0;\r
+}\r
+\r
+void unloadCameraControler(ISOMReader *read)\r
+{\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] unloadCameraControler: %d\n", gf_th_id()));\r
+       if ( read->isAttached )\r
+       {\r
+               //(*rc->env)->PopLocalFrame(rc->env, NULL);\r
+               (*GetJavaVM())->DetachCurrentThread(GetJavaVM());\r
+               read->isAttached = 0;\r
+       }\r
+\r
+       read->env = NULL;\r
+}\r
+\r
+u32 unregisterFunc(void* data)\r
+{\r
+       unloadCameraControler(globReader);\r
+}\r
+\r
+void loadCameraControler(ISOMReader *read)\r
+{\r
+       JNIEnv* env = NULL;\r
+       jint res = 0;\r
+\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] loadCameraControler: %d\n", gf_th_id()));\r
+\r
+       // Get the JNI interface pointer\r
+       res = (*GetJavaVM())->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2);\r
+       if ( res == JNI_EDETACHED )\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] The current thread is not attached to the VM, assuming native thread\n"));\r
+               if ( res = (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL) )\r
+               {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] Attach current thread failed: %d\n", res));\r
+                       return;\r
+               }\r
+               gf_register_before_exit_function(gf_th_current(), unregisterFunc);\r
+               read->isAttached = 1;\r
+               //(*rc->env)->PushLocalFrame(rc->env, 2);\r
+       }\r
+       else \r
+               if ( res == JNI_EVERSION )\r
+               {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] The specified version is not supported\n"));\r
+                       return;\r
+               }\r
+\r
+       read->env = env;\r
+       read->camCtrlClass = camCtrlClass;\r
+       read->cid = cid;\r
+       read->startCamera = startCamera;\r
+       read->stopCamera = stopCamera;\r
+       read->startProcessing = startProcessing;\r
+       read->stopProcessing = stopProcessing;\r
+       read->getImageFormat = getImageFormat;\r
+       read->getImageHeight = getImageHeight;\r
+       read->getImageWidth = getImageWidth;\r
+\r
+       // Create the object.\r
+       read->camCtrlObj = (*env)->NewObject(env, read->camCtrlClass, read->cid);\r
+       if (read->camCtrlObj == 0)\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("CameraController object creation failed. [myCamera.c, startCameraNative()]"));\r
+               return;\r
+       }\r
+}\r
+\r
+GF_Err CAM_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)\r
+{\r
+       ISOMReader *read;\r
+       if (!plug || !plug->priv || !serv) return GF_SERVICE_ERROR;\r
+       read = (ISOMReader *) plug->priv;\r
+\r
+       read->input = plug;\r
+       read->service = serv;\r
+       read->base_track_id = 1;\r
+       read->time_scale = 1000;\r
+\r
+       read->term = serv->term;\r
+\r
+       loadCameraControler(read);\r
+\r
+       /*reply to user*/\r
+       gf_term_on_connect(serv, NULL, GF_OK);\r
+       //if (read->no_service_desc) isor_declare_objects(read);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+GF_Err CAM_CloseService(GF_InputService *plug)\r
+{\r
+       GF_Err reply;\r
+       ISOMReader *read;\r
+       if (!plug || !plug->priv) return GF_SERVICE_ERROR;\r
+       read = (ISOMReader *) plug->priv;\r
+       reply = GF_OK;\r
+\r
+       (*GetEnv())->DeleteLocalRef( GetEnv(), read->camCtrlObj ); \r
+\r
+       //unloadCameraControler(read);\r
+\r
+       gf_term_on_disconnect(read->service, NULL, reply);\r
+       return GF_OK;\r
+}\r
+\r
+u32 getWidth(ISOMReader *read);\r
+u32 getHeight(ISOMReader *read);\r
+\r
+static GF_Descriptor *CAM_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url)\r
+{\r
+       u32 trackID;\r
+       GF_ESD *esd;\r
+       ISOMReader *read;\r
+       GF_ObjectDescriptor *od;\r
+       GF_BitStream *bs;\r
+       char *buf;\r
+       u32 buf_size;\r
+       if (!plug || !plug->priv) return NULL;\r
+       read = (ISOMReader *) plug->priv;\r
+\r
+       trackID = 0;\r
+       trackID = read->base_track_id;\r
+       read->base_track_id = 0;\r
+\r
+       if (trackID && (expect_type==GF_MEDIA_OBJECT_VIDEO) ) {\r
+               od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);\r
+               od->objectDescriptorID = 1;\r
+\r
+               esd = gf_odf_desc_esd_new(0);\r
+               esd->slConfig->timestampResolution = 1000;\r
+               esd->decoderConfig->streamType = GF_STREAM_VISUAL;\r
+               esd->ESID = 1;\r
+               esd->decoderConfig->objectTypeIndication = GPAC_OTI_RAW_MEDIA_STREAM;\r
+               \r
+               bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);\r
+\r
+               read->width = getWidth(read);\r
+               read->height = getHeight(read);\r
+\r
+               gf_bs_write_u32(bs, CAM_PIXEL_FORMAT); // fourcc\r
+               gf_bs_write_u16(bs, read->width); // width\r
+               gf_bs_write_u16(bs, read->height); // height\r
+               gf_bs_write_u32(bs, read->width * read->height * CAM_PIXEL_SIZE); // framesize\r
+               gf_bs_write_u32(bs, read->width * CAM_PIXEL_SIZE); // stride\r
+\r
+               gf_bs_align(bs);\r
+               gf_bs_get_content(bs, &buf, &buf_size);\r
+               gf_bs_del(bs);\r
+\r
+               esd->decoderConfig->decoderSpecificInfo->data = buf;\r
+               esd->decoderConfig->decoderSpecificInfo->dataLength = buf_size;\r
+\r
+               gf_list_add(od->ESDescriptors, esd);\r
+               return (GF_Descriptor *) od;\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+\r
+\r
+\r
+GF_Err CAM_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream)\r
+{\r
+       GF_Err e;\r
+       ISOMReader *read;\r
+       if (!plug || !plug->priv) return GF_SERVICE_ERROR;\r
+       read = (ISOMReader *) plug->priv;\r
+\r
+       e = GF_OK;\r
+       if (upstream) {\r
+               e = GF_ISOM_INVALID_FILE;\r
+       }\r
+\r
+       read->channel = channel;\r
+\r
+       camStartCamera(read);\r
+\r
+       gf_term_on_connect(read->service, channel, e);\r
+       return e;\r
+}\r
+\r
+GF_Err CAM_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel)\r
+{\r
+       GF_Err e;\r
+       ISOMReader *read;\r
+       if (!plug || !plug->priv) return GF_SERVICE_ERROR;\r
+       read = (ISOMReader *) plug->priv;\r
+\r
+       e = GF_OK;\r
+\r
+       camStopCamera(read);\r
+\r
+       gf_term_on_disconnect(read->service, channel, e);\r
+       return e;\r
+}\r
+\r
+int* decodeYUV420SP( char* yuv420sp, int width, int height)\r
+{\r
+       int frameSize = width * height;\r
+       int j, yp, uvp, i, y, y1192, r, g, b, u, v;\r
+       int ti, tj;\r
+\r
+       int* rgb = (int*)gf_malloc(width*height*4);\r
+       for (j = 0, yp = 0, tj=height-1; j < height; j++, tj--)\r
+       {\r
+               uvp = frameSize + (j >> 1) * width, u = 0, v = 0;\r
+               for (i = 0, ti=0; i < width; i++, yp++, ti+=width)\r
+               {\r
+                       y = (0xff & ((int) yuv420sp[yp])) - 16;\r
+                       if (y < 0) y = 0;\r
+                       if ((i & 1) == 0)\r
+                       {\r
+                               v = (0xff & yuv420sp[uvp++]) - 128;\r
+                               u = (0xff & yuv420sp[uvp++]) - 128;\r
+                       }\r
+\r
+                       y1192 = 1192 * y;\r
+                       r = (y1192 + 1634 * v);\r
+                       g = (y1192 - 833 * v - 400 * u);\r
+                       b = (y1192 + 2066 * u);\r
+\r
+                       if (r < 0)\r
+                               r = 0;\r
+                       else if (r > 262143)\r
+                               r = 262143;\r
+                       if (g < 0)\r
+                               g = 0;\r
+                       else if (g > 262143)\r
+                               g = 262143;\r
+                       if (b < 0)\r
+                               b = 0;\r
+                       else if (b > 262143)\r
+                               b = 262143;\r
+\r
+                       rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)\r
+                                               | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);\r
+//                     rgb[ti+tj] = 0xff000000 | ((r << 6) & 0xff0000)\r
+//                                     | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);\r
+               }\r
+       }\r
+       return rgb;\r
+}\r
+\r
+void Java_com_gpac_Osmo4_Preview_processFrameBuf( JNIEnv* env, jobject thiz, jbyteArray arr)\r
+{\r
+       u8* data;\r
+       u32 datasize;\r
+       ISOMReader* ctx = globReader;\r
+       GF_SLHeader hdr;\r
+       u32 cts = 0;\r
+       u32 convTime = 0;\r
+       u32 j = 0;\r
+       jbyte *jdata;\r
+       jsize len;\r
+\r
+       if ( ctx->started )\r
+       {\r
+               len = (*env)->GetArrayLength(env, arr);\r
+               jdata = (*env)->GetByteArrayElements(env,arr,0);\r
+\r
+               convTime = gf_term_get_time(ctx->term);\r
+\r
+               data = (u8*)jdata;//(u8*)decodeYUV420SP((char*)jdata, ctx->width, ctx->height); //\r
+               datasize = len;//ctx->width * ctx->height * CAM_PIXEL_SIZE;//\r
+\r
+               cts = gf_term_get_time(ctx->term);\r
+\r
+               convTime = cts - convTime;\r
+\r
+               memset(&hdr, 0, sizeof(hdr));\r
+               hdr.compositionTimeStampFlag = 1;\r
+               hdr.compositionTimeStamp = cts;\r
+               gf_term_on_sl_packet(ctx->service, ctx->channel, (void*)data, datasize, &hdr, GF_OK);\r
+\r
+               //gf_free(data);\r
+\r
+               (*env)->ReleaseByteArrayElements(env,arr,jdata,JNI_ABORT);\r
+\r
+               //GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Camera Frame Sent %d\n", gf_sys_clock()));\r
+       }\r
+}\r
+\r
+void CallCamMethod(ISOMReader *read, jmethodID methodID)\r
+{\r
+       JNIEnv* env = NULL;\r
+       jint res = 0;\r
+       u8 isAttached = 0;\r
+\r
+       // Get the JNI interface pointer\r
+       res = (*GetJavaVM())->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2);\r
+       if ( res == JNI_EDETACHED )\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] The current thread is not attached to the VM, assuming native thread\n"));\r
+               if ( res = (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL) )\r
+               {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] Attach current thread failed: %d\n", res));\r
+                       return;\r
+               }\r
+               if ( env != read->env )\r
+                       isAttached = 1;\r
+       }\r
+\r
+       (*env)->CallNonvirtualVoidMethod(env, read->camCtrlObj, read->camCtrlClass, methodID);\r
+\r
+       if (isAttached)\r
+       {       \r
+               (*GetJavaVM())->DetachCurrentThread(GetJavaVM());\r
+       }\r
+}\r
+\r
+void camStartCamera(ISOMReader *read)\r
+{\r
+       JNIEnv* env = NULL;\r
+       jboolean isPortrait = JNI_FALSE;\r
+\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] startCamera: %d\n", gf_th_id()));\r
+\r
+       // Get the JNI interface pointer\r
+       env = read->env;\r
+\r
+       (*env)->CallNonvirtualBooleanMethod(env, read->camCtrlObj, read->camCtrlClass, read->startCamera, isPortrait);\r
+}\r
+\r
+void camStopCamera(ISOMReader *read)\r
+{\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] stopCamera: %d\n", gf_th_id()));\r
+\r
+       CallCamMethod(read, read->stopCamera);\r
+}\r
+\r
+void pauseCamera(ISOMReader *read)\r
+{\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] pauseCamera: %d\n", gf_th_id()));\r
+\r
+       read->started = 0;\r
+       CallCamMethod(read, read->stopProcessing);\r
+}\r
+\r
+void resumeCamera(ISOMReader *read)\r
+{\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] resumeCamera: %d\n", gf_th_id()));\r
+\r
+       read->started = 1;\r
+       CallCamMethod(read, read->startProcessing);\r
+}\r
+\r
+u32 getWidth(ISOMReader *read)\r
+{\r
+       JNIEnv* env = NULL;\r
+\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] getWidth: %d\n", gf_th_id()));\r
+\r
+       // Get the JNI interface pointer\r
+       env = read->env;\r
+\r
+       return (*env)->CallNonvirtualIntMethod(env, read->camCtrlObj, read->camCtrlClass, read->getImageWidth);\r
+}\r
+\r
+u32 getHeight(ISOMReader *read)\r
+{\r
+       JNIEnv* env = NULL;\r
+\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[ANDROID_CAMERA] getHeight: %d\n", gf_th_id()));\r
+\r
+       // Get the JNI interface pointer\r
+       env = read->env;\r
+\r
+       return (*env)->CallNonvirtualIntMethod(env, read->camCtrlObj, read->camCtrlClass, read->getImageHeight);\r
+}\r
+\r
+GF_Err CAM_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)\r
+{\r
+       ISOMReader *read;\r
+       GF_BitStream *bs;\r
+       char *buf;\r
+       u32 buf_size;\r
+       if (!plug || !plug->priv || !com) return GF_SERVICE_ERROR;\r
+       read = (ISOMReader *) plug->priv;\r
+\r
+       if (com->command_type==GF_NET_SERVICE_INFO) {\r
+               return GF_OK;\r
+       }\r
+       if (com->command_type==GF_NET_SERVICE_HAS_AUDIO) {\r
+               return GF_NOT_SUPPORTED;\r
+       }\r
+       if (!com->base.on_channel) return GF_NOT_SUPPORTED;\r
+\r
+       switch (com->command_type) {\r
+       case GF_NET_CHAN_INTERACTIVE:\r
+               return GF_OK;\r
+       case GF_NET_CHAN_BUFFER:\r
+               com->buffer.max = com->buffer.min = 0;\r
+               return GF_OK;\r
+       case GF_NET_CHAN_PLAY:\r
+               resumeCamera(read);\r
+               return GF_OK;\r
+       case GF_NET_CHAN_STOP:\r
+               pauseCamera(read);\r
+               return GF_OK;\r
+       /*nothing to do on MP4 for channel config*/\r
+       case GF_NET_CHAN_CONFIG:\r
+               return GF_OK;\r
+       case GF_NET_CHAN_GET_PIXEL_AR:\r
+               return 1<<16;//gf_isom_get_pixel_aspect_ratio(read->mov, ch->track, 1, &com->par.hSpacing, &com->par.vSpacing);\r
+       case GF_NET_CHAN_GET_DSI:\r
+               {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Cam get DSI\n"));\r
+                       /*it may happen that there are conflicting config when using ESD URLs...*/\r
+                       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);\r
+\r
+                       read->width = getWidth(read);\r
+                       read->height = getHeight(read);\r
+\r
+                       gf_bs_write_u32(bs, CAM_PIXEL_FORMAT); // fourcc\r
+                       gf_bs_write_u16(bs, read->width); // width\r
+                       gf_bs_write_u16(bs, read->height); // height\r
+                       gf_bs_write_u32(bs, read->width * read->height * CAM_PIXEL_SIZE); // framesize\r
+                       gf_bs_write_u32(bs, read->width * CAM_PIXEL_SIZE); // stride\r
+\r
+                       gf_bs_align(bs);\r
+                       gf_bs_get_content(bs, &buf, &buf_size);\r
+                       gf_bs_del(bs);\r
+\r
+                       com->get_dsi.dsi = buf;\r
+                       com->get_dsi.dsi_len = buf_size;\r
+                       return GF_OK;\r
+               }\r
+       }\r
+       return GF_NOT_SUPPORTED;\r
+}\r
+\r
+GF_InputService *CAM_client_load()\r
+{\r
+       ISOMReader *reader;\r
+       GF_InputService *plug;\r
+       GF_SAFEALLOC(plug, GF_InputService);\r
+       GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC Camera Plugin", "gpac distribution")\r
+       plug->CanHandleURL = CAM_CanHandleURL;\r
+       plug->ConnectService = CAM_ConnectService;\r
+       plug->CloseService = CAM_CloseService;\r
+       plug->GetServiceDescriptor = CAM_GetServiceDesc;\r
+       plug->ConnectChannel = CAM_ConnectChannel;\r
+       plug->DisconnectChannel = CAM_DisconnectChannel;\r
+       plug->ServiceCommand = CAM_ServiceCommand;\r
+\r
+       GF_SAFEALLOC(reader, ISOMReader);\r
+       plug->priv = reader;\r
+       globReader = reader;\r
+       return plug;\r
+}\r
+\r
+void CAM_client_del(GF_BaseInterface *bi)\r
+{\r
+       GF_InputService *plug = (GF_InputService *) bi;\r
+       ISOMReader *read = (ISOMReader *)plug->priv;\r
+\r
+       gf_free(read);\r
+       gf_free(bi);\r
+}\r
+\r
+GF_EXPORT\r
+const u32 *QueryInterfaces()\r
+{\r
+       static u32 si [] = {\r
+               GF_NET_CLIENT_INTERFACE,\r
+               0\r
+       };\r
+       return si;\r
+}\r
+\r
+GF_EXPORT\r
+GF_BaseInterface *LoadInterface(u32 InterfaceType)\r
+{\r
+       if (InterfaceType == GF_NET_CLIENT_INTERFACE)\r
+               return (GF_BaseInterface *)CAM_client_load();\r
+       return NULL;\r
+}\r
+\r
+GF_EXPORT\r
+void ShutdownInterface(GF_BaseInterface *ifce)\r
+{\r
+       switch (ifce->InterfaceType) {\r
+       case GF_NET_CLIENT_INTERFACE: CAM_client_del(ifce); break;\r
+       }\r
+}\r
index b4d6797cab3996eebc9d904c39fc031e876678bb..73b35d2a2fba20091a7c97dfbb3808d2f22864ba 100644 (file)
-/*
- *                     GPAC - Multimedia Framework C SDK
- *
- *                     Authors: Ivica Arsov
- *                     Copyright (c) Institut Telecom 2011-20XX
- *                                     All rights reserved
- *
- *  This file is part of GPAC / MPEG-V Input sensor for android
- *
- *  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. 
- *             
- */
-
-#include <jni.h>
-#include <android/log.h>
-
-/*driver interfaces*/
-
-#include <gpac/list.h>
-#include <gpac/constants.h>
-
-#include <gpac/setup.h>
-
-#include <gpac/modules/codec.h>
-#include <gpac/scenegraph_vrml.h>
-
-#include <gpac/thread.h>
-
-#define LOG_TAG "MPEG-V_IN"
-#ifdef ANDROID
-#  define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
-#  define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
-#else
-#  define QUOTEME_(x) #x
-#  define QUOTEME(x) QUOTEME_(x)
-#  define LOGI(...) printf("I/" LOG_TAG " (" __FILE__ ":" QUOTEME(__LINE__) "): " __VA_ARGS__)
-#  define LOGE(...) printf("E/" LOG_TAG "(" ")" __VA_ARGS__)
-#endif
-
-JNIEXPORT void JNICALL Java_com_gpac_Osmo4_MPEGVSensor_sendData( JNIEnv* env, jobject thiz, jint ptr, jstring data);
-
-static JavaVM* javaVM = 0;
-static jclass sensCtrlClass;
-static jmethodID cid;
-static jmethodID startSensor;
-static jmethodID stopSensor;
-
-//----------------------------------------------------------------------
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-       JNIEnv* env = 0;
-       javaVM = vm;
-
-       if ( (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2) != JNI_OK )
-               return -1;
-
-       // Get the class and its methods in the main env
-
-       // Get the CameraController class
-       // This is just a local refenrece. Cannot be used in the other JNI calls.
-       sensCtrlClass = (*env)->FindClass(env, "com/gpac/Osmo4/MPEGVSensor");
-       if (sensCtrlClass == 0)
-       {
-               LOGE("[MPEG-V_IN] Class MPEGVSensor not found\n");
-               return -1;
-       }
-
-       // Get Global Reference to be able to use the class
-       sensCtrlClass = (*env)->NewGlobalRef(env, sensCtrlClass);
-       if ( sensCtrlClass == 0 )
-       {
-               LOGE("[MPEG-V_IN] Caanot create Global Reference\n");
-               return -1;
-       }
-
-       // Get the method ID for the CameraController constructor.
-       cid = (*env)->GetMethodID(env, sensCtrlClass, "<init>", "()V");
-       if (cid == 0)
-       {
-               LOGE("[MPEG-V_IN] MPEGVSensor Constructor not found\n");
-               return -1;
-       }
-
-       // Get startCamera() method from class CameraController
-       startSensor = (*env)->GetMethodID(env, sensCtrlClass, "startSensor", "(II)V");
-       if (startSensor == 0)
-       {
-               LOGE("[MPEG-V_IN] Function startSensor not found\n");
-               return -1;
-       }
-
-       stopSensor = (*env)->GetMethodID(env, sensCtrlClass, "stopSensor", "()V");
-       if (stopSensor == 0)
-       {
-               LOGE("[MPEG-V_IN] Function stopSensor not found\n");
-               return -1;
-       }
-
-       return JNI_VERSION_1_2;
-}
-
-void JNI_OnUnload(JavaVM *vm, void *reserved)
-{
-       JNIEnv* env = 0;
-       
-       if ( (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_2) != JNI_OK )
-               return;
-       
-       (*env)->DeleteGlobalRef(env, sensCtrlClass);
-}
-//----------------------------------------------------------------------
-JavaVM* GetJavaVM()
-{
-       return javaVM;
-}
-//----------------------------------------------------------------------
-
-typedef struct
-{
-       char sensor[50];
-       u16 sensorAndroidType;
-       u8 isAttached;
-
-       GF_Thread *trd;
-       u8 stop;
-
-       JNIEnv* env;
-       jclass sensCtrlClass;
-       jmethodID cid;
-       jobject sensCtrlObj;
-       jmethodID startSensor;
-       jmethodID stopSensor;
-} MPEGVSensorContext;
-
-#define MPEGVSCTX      MPEGVSensorContext *rc = (MPEGVSensorContext *)dr->udta
-
-void unloadSensorController(MPEGVSensorContext *rc)
-{
-       if ( rc->isAttached )
-       {
-               (*rc->env)->PopLocalFrame(rc->env, NULL);
-               (*GetJavaVM())->DetachCurrentThread(GetJavaVM());
-               rc->isAttached = 0;
-       }
-
-       rc->env = NULL;
-}
-
-void loadSensorControler(MPEGVSensorContext *rc)
-{
-       JNIEnv* env = NULL;
-       jint res = 0;
-
-       // Here we can be in a thread
-
-       res = (*GetJavaVM())->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2);
-       if ( res == JNI_EDETACHED )
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] The current thread is not attached to the VM, assuming native thread\n"));
-               if ( res = (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL) )
-               {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Attach current thread failed: %d\n", res));
-                       return;
-               }
-               rc->isAttached = 1;
-               (*env)->PushLocalFrame(env, 2);
-       }
-       else 
-               if ( res == JNI_EVERSION )
-               {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] The specified version is not supported\n"));
-                       return;
-               }
-       
-       rc->env = env;
-       rc->sensCtrlClass = sensCtrlClass;
-       rc->cid = cid;
-       rc->startSensor = startSensor;
-       rc->stopSensor = stopSensor;    
-
-       // Create the sensor object in the thread
-       rc->sensCtrlObj = (*rc->env)->NewObject(rc->env, rc->sensCtrlClass, rc->cid);
-       if (rc->sensCtrlObj == 0)
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Cannot create MPEGVSensor object\n"));
-               return;
-       }
-}
-
-Bool MPEGVS_RegisterDevice(struct __input_device *dr, const char *urn, GF_BitStream *dsi, void (*AddField)(struct __input_device *_this, u32 fieldType, const char *name))
-{
-       MPEGVSCTX;
-       
-       //"MPEG-V:siv:OrientationSensorType"
-
-       if ( strnicmp(urn, "MPEG-V", 6) )
-               return 0;
-
-       if ( strlen(urn) <= 6 )
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[MPEG-V] No sensor type specified\n"));
-               return 0;
-       }
-       
-       if ( strnicmp(urn+6, ":siv:", 5) )
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[MPEG-V] Not valid sensor type specified\n"));
-               return 0;
-       }
-
-       strcpy(rc->sensor, urn+11);
-
-       if ( !strcmp(rc->sensor, "OrientationSensorType") )
-       {
-               AddField(dr, GF_SG_VRML_SFVEC3F, "Orientation");
-
-               rc->sensorAndroidType = 3;
-               
-               AddField(dr, GF_SG_VRML_SFVEC3F, "pos");
-
-               return 1;
-       }
-       else
-       {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[MPEG-V_IN] Unsupported sensor type: %s\n", rc->sensor));
-               return 0;
-       }
-}
-
-u32 MPEGVS_OnData(struct __input_device * dr, const char* data)
-{
-       GF_BitStream *bs;
-       char *buf;
-       u32 buf_size;
-       float x, y, z;
-       
-       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
-
-       sscanf(data, "%f;%f;%f;", &x, &y, &z);
-
-       gf_bs_write_int(bs, 1, 1);
-       gf_bs_write_float(bs, x);
-       gf_bs_write_float(bs, y);
-       gf_bs_write_float(bs, z);
-
-       gf_bs_align(bs);
-       gf_bs_get_content(bs, &buf, &buf_size);
-       gf_bs_del(bs);
-
-       dr->DispatchFrame(dr, (u8*)buf, buf_size);
-       gf_free(buf);
-
-       return GF_OK;
-}
-
-JNIEXPORT void Java_com_gpac_Osmo4_MPEGVSensor_sendData( JNIEnv* env, jobject thiz, jint ptr, jstring data)
-{
-       jboolean isCopy;
-       const char * cData = (*env)->GetStringUTFChars(env, data, &isCopy);
-
-       MPEGVS_OnData((struct __input_device *)ptr, cData);
-
-       (*env)->ReleaseStringUTFChars(env, data, cData);
-}
-
-u32 ThreadRun(void* param)
-{
-       struct __input_device * dr = (struct __input_device *)param;
-       MPEGVSCTX;
-
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Start: %d\n", gf_th_id()));
-
-       loadSensorControler(rc);
-
-       if (!rc->env || !rc->sensCtrlObj)
-               return;
-
-       (*rc->env)->CallNonvirtualVoidMethod(rc->env, rc->sensCtrlObj, rc->sensCtrlClass, rc->startSensor, (s32)dr, rc->sensorAndroidType);
-
-       while (!rc->stop)
-               gf_sleep(10);
-       
-       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Stop: %d\n", gf_th_id()));
-
-       if (!rc->env)
-               return;
-
-       if ( rc->sensCtrlObj )
-       {
-               (*rc->env)->CallNonvirtualVoidMethod(rc->env, rc->sensCtrlObj, rc->sensCtrlClass, rc->stopSensor);
-
-               (*rc->env)->DeleteLocalRef( rc->env, rc->sensCtrlObj );
-       }
-
-       unloadSensorController(rc);
-}
-
-void MPEGVS_Start(struct __input_device * dr)
-{
-       MPEGVSCTX;
-       
-       rc->trd = gf_th_new("MPEG-V_IN");
-       gf_th_run(rc->trd, ThreadRun, dr);
-}
-
-void MPEGVS_Stop(struct __input_device * dr)
-{
-       MPEGVSCTX;
-
-       if ( rc->trd )
-       {
-               rc->stop = 1;
-               while ( gf_th_status(rc->trd) == GF_THREAD_STATUS_RUN )
-                       gf_sleep(5);
-
-               gf_th_del(rc->trd);
-               rc->trd = NULL;
-               rc->stop = 0;
-       }
-}
-
-GF_InputSensorDevice* NewMPEGVSInputSesor()
-{
-       MPEGVSensorContext* ctx = NULL;
-       GF_InputSensorDevice* driv = NULL;
-       
-       driv = (GF_InputSensorDevice *) gf_malloc(sizeof(GF_InputSensorDevice));
-       memset(driv, 0, sizeof(GF_InputSensorDevice));
-       GF_REGISTER_MODULE_INTERFACE(driv, GF_INPUT_DEVICE_INTERFACE, "MPEG-V Sensors Input Module", "gpac distribution");
-
-       driv->RegisterDevice = MPEGVS_RegisterDevice;
-       driv->Start = MPEGVS_Start;
-       driv->Stop = MPEGVS_Stop;
-
-       ctx = (MPEGVSensorContext*) gf_malloc (sizeof(MPEGVSensorContext));
-       memset(ctx, 0, sizeof(MPEGVSensorContext));
-       
-       driv->udta = (void*)ctx;
-
-       return driv;
-}
-
-void DeleteMPEGVSInputSensor(GF_InputSensorDevice* dev)
-{
-       MPEGVS_Stop(dev);
-       gf_free(dev->udta);
-       gf_free(dev);
-}
-
-/*interface query*/
-GF_EXPORT
-const u32 *QueryInterfaces() 
-{
-       static u32 si [] = {
-               GF_INPUT_DEVICE_INTERFACE,
-               0
-       };
-       return si; 
-}
-
-/*interface create*/
-GF_EXPORT
-GF_BaseInterface *LoadInterface(u32 InterfaceType)
-{
-       if (InterfaceType == GF_INPUT_DEVICE_INTERFACE) return (GF_BaseInterface *) NewMPEGVSInputSesor();
-       return NULL;
-}
-
-/*interface destroy*/
-GF_EXPORT
-void ShutdownInterface(GF_BaseInterface *ifce)
-{
-       switch (ifce->InterfaceType) {
-       case GF_INPUT_DEVICE_INTERFACE:
-               DeleteMPEGVSInputSensor((GF_InputSensorDevice *)ifce);
-               break;
-       }
-}
-
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Ivica Arsov, Jean Le Feuvre\r
+ *                     Copyright (c) Mines-Telecom 2009-\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / MPEG-V Input sensor for android\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *             \r
+ */\r
+\r
+#include <jni.h>\r
+#include <android/log.h>\r
+\r
+/*driver interfaces*/\r
+\r
+#include <gpac/list.h>\r
+#include <gpac/constants.h>\r
+\r
+#include <gpac/setup.h>\r
+\r
+#include <gpac/modules/codec.h>\r
+#include <gpac/scenegraph_vrml.h>\r
+\r
+#include <gpac/thread.h>\r
+\r
+#define LOG_TAG "MPEG-V_IN"\r
+#ifdef ANDROID\r
+#  define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)\r
+#  define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)\r
+#else\r
+#  define QUOTEME_(x) #x\r
+#  define QUOTEME(x) QUOTEME_(x)\r
+#  define LOGI(...) fprintf(stderr, "I/" LOG_TAG " (" __FILE__ ":" QUOTEME(__LINE__) "): " __VA_ARGS__)\r
+#  define LOGE(...) fprintf(stderr, "E/" LOG_TAG "(" ")" __VA_ARGS__)\r
+#endif\r
+\r
+JNIEXPORT void JNICALL Java_com_gpac_Osmo4_MPEGVSensor_sendData( JNIEnv* env, jobject thiz, jint ptr, jstring data);\r
+\r
+static JavaVM* javaVM = 0;\r
+static jclass sensCtrlClass;\r
+static jmethodID cid;\r
+static jmethodID startSensor;\r
+static jmethodID stopSensor;\r
+\r
+//----------------------------------------------------------------------\r
+jint JNI_OnLoad(JavaVM* vm, void* reserved)\r
+{\r
+       JNIEnv* env = 0;\r
+       javaVM = vm;\r
+\r
+       if ( (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2) != JNI_OK )\r
+               return -1;\r
+\r
+       // Get the class and its methods in the main env\r
+\r
+       // Get the CameraController class\r
+       // This is just a local refenrece. Cannot be used in the other JNI calls.\r
+       sensCtrlClass = (*env)->FindClass(env, "com/gpac/Osmo4/MPEGVSensor");\r
+       if (sensCtrlClass == 0)\r
+       {\r
+               LOGE("[MPEG-V_IN] Class MPEGVSensor not found\n");\r
+               return -1;\r
+       }\r
+\r
+       // Get Global Reference to be able to use the class\r
+       sensCtrlClass = (*env)->NewGlobalRef(env, sensCtrlClass);\r
+       if ( sensCtrlClass == 0 )\r
+       {\r
+               LOGE("[MPEG-V_IN] Caanot create Global Reference\n");\r
+               return -1;\r
+       }\r
+\r
+       // Get the method ID for the CameraController constructor.\r
+       cid = (*env)->GetMethodID(env, sensCtrlClass, "<init>", "()V");\r
+       if (cid == 0)\r
+       {\r
+               LOGE("[MPEG-V_IN] MPEGVSensor Constructor not found\n");\r
+               return -1;\r
+       }\r
+\r
+       // Get startCamera() method from class CameraController\r
+       startSensor = (*env)->GetMethodID(env, sensCtrlClass, "startSensor", "(II)V");\r
+       if (startSensor == 0)\r
+       {\r
+               LOGE("[MPEG-V_IN] Function startSensor not found\n");\r
+               return -1;\r
+       }\r
+\r
+       stopSensor = (*env)->GetMethodID(env, sensCtrlClass, "stopSensor", "()V");\r
+       if (stopSensor == 0)\r
+       {\r
+               LOGE("[MPEG-V_IN] Function stopSensor not found\n");\r
+               return -1;\r
+       }\r
+\r
+       return JNI_VERSION_1_2;\r
+}\r
+\r
+void JNI_OnUnload(JavaVM *vm, void *reserved)\r
+{\r
+       JNIEnv* env = 0;\r
+       \r
+       if ( (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_2) != JNI_OK )\r
+               return;\r
+       \r
+       (*env)->DeleteGlobalRef(env, sensCtrlClass);\r
+}\r
+//----------------------------------------------------------------------\r
+JavaVM* GetJavaVM()\r
+{\r
+       return javaVM;\r
+}\r
+//----------------------------------------------------------------------\r
+\r
+typedef struct\r
+{\r
+       char sensor[50];\r
+       u16 sensorAndroidType;\r
+       u8 isAttached;\r
+\r
+       GF_Thread *trd;\r
+       u8 stop;\r
+\r
+       JNIEnv* env;\r
+       jclass sensCtrlClass;\r
+       jmethodID cid;\r
+       jobject sensCtrlObj;\r
+       jmethodID startSensor;\r
+       jmethodID stopSensor;\r
+} MPEGVSensorContext;\r
+\r
+#define MPEGVSCTX      MPEGVSensorContext *rc = (MPEGVSensorContext *)dr->udta\r
+\r
+void unloadSensorController(MPEGVSensorContext *rc)\r
+{\r
+       if ( rc->isAttached )\r
+       {\r
+               (*rc->env)->PopLocalFrame(rc->env, NULL);\r
+               (*GetJavaVM())->DetachCurrentThread(GetJavaVM());\r
+               rc->isAttached = 0;\r
+       }\r
+\r
+       rc->env = NULL;\r
+}\r
+\r
+void loadSensorControler(MPEGVSensorContext *rc)\r
+{\r
+       JNIEnv* env = NULL;\r
+       jint res = 0;\r
+\r
+       // Here we can be in a thread\r
+\r
+       res = (*GetJavaVM())->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2);\r
+       if ( res == JNI_EDETACHED )\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] The current thread is not attached to the VM, assuming native thread\n"));\r
+               if ( res = (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL) )\r
+               {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Attach current thread failed: %d\n", res));\r
+                       return;\r
+               }\r
+               rc->isAttached = 1;\r
+               (*env)->PushLocalFrame(env, 2);\r
+       }\r
+       else \r
+               if ( res == JNI_EVERSION )\r
+               {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] The specified version is not supported\n"));\r
+                       return;\r
+               }\r
+       \r
+       rc->env = env;\r
+       rc->sensCtrlClass = sensCtrlClass;\r
+       rc->cid = cid;\r
+       rc->startSensor = startSensor;\r
+       rc->stopSensor = stopSensor;    \r
+\r
+       // Create the sensor object in the thread\r
+       rc->sensCtrlObj = (*rc->env)->NewObject(rc->env, rc->sensCtrlClass, rc->cid);\r
+       if (rc->sensCtrlObj == 0)\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Cannot create MPEGVSensor object\n"));\r
+               return;\r
+       }\r
+}\r
+\r
+Bool MPEGVS_RegisterDevice(struct __input_device *dr, const char *urn, GF_BitStream *dsi, void (*AddField)(struct __input_device *_this, u32 fieldType, const char *name))\r
+{\r
+       MPEGVSCTX;\r
+       \r
+       //"MPEG-V:siv:OrientationSensorType"\r
+\r
+       if ( strnicmp(urn, "MPEG-V", 6) )\r
+               return 0;\r
+\r
+       if ( strlen(urn) <= 6 )\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[MPEG-V] No sensor type specified\n"));\r
+               return 0;\r
+       }\r
+       \r
+       if ( strnicmp(urn+6, ":siv:", 5) )\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[MPEG-V] Not valid sensor type specified\n"));\r
+               return 0;\r
+       }\r
+\r
+       strcpy(rc->sensor, urn+11);\r
+\r
+       if ( !strcmp(rc->sensor, "OrientationSensorType") )\r
+       {\r
+               AddField(dr, GF_SG_VRML_SFVEC3F, "Orientation");\r
+\r
+               rc->sensorAndroidType = 3;\r
+               \r
+               AddField(dr, GF_SG_VRML_SFVEC3F, "pos");\r
+\r
+               return 1;\r
+       }\r
+       else\r
+       {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[MPEG-V_IN] Unsupported sensor type: %s\n", rc->sensor));\r
+               return 0;\r
+       }\r
+}\r
+\r
+u32 MPEGVS_OnData(struct __input_device * dr, const char* data)\r
+{\r
+       GF_BitStream *bs;\r
+       char *buf;\r
+       u32 buf_size;\r
+       float x, y, z;\r
+       \r
+       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);\r
+\r
+       sscanf(data, "%f;%f;%f;", &x, &y, &z);\r
+\r
+       gf_bs_write_int(bs, 1, 1);\r
+       gf_bs_write_float(bs, x);\r
+       gf_bs_write_float(bs, y);\r
+       gf_bs_write_float(bs, z);\r
+\r
+       gf_bs_align(bs);\r
+       gf_bs_get_content(bs, &buf, &buf_size);\r
+       gf_bs_del(bs);\r
+\r
+       dr->DispatchFrame(dr, (u8*)buf, buf_size);\r
+       gf_free(buf);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+JNIEXPORT void Java_com_gpac_Osmo4_MPEGVSensor_sendData( JNIEnv* env, jobject thiz, jint ptr, jstring data)\r
+{\r
+       jboolean isCopy;\r
+       const char * cData = (*env)->GetStringUTFChars(env, data, &isCopy);\r
+\r
+       MPEGVS_OnData((struct __input_device *)ptr, cData);\r
+\r
+       (*env)->ReleaseStringUTFChars(env, data, cData);\r
+}\r
+\r
+u32 ThreadRun(void* param)\r
+{\r
+       struct __input_device * dr = (struct __input_device *)param;\r
+       MPEGVSCTX;\r
+\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Start: %d\n", gf_th_id()));\r
+\r
+       loadSensorControler(rc);\r
+\r
+       if (!rc->env || !rc->sensCtrlObj)\r
+               return;\r
+\r
+       (*rc->env)->CallNonvirtualVoidMethod(rc->env, rc->sensCtrlObj, rc->sensCtrlClass, rc->startSensor, (s32)dr, rc->sensorAndroidType);\r
+\r
+       while (!rc->stop)\r
+               gf_sleep(10);\r
+       \r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[MPEG-V_IN] Stop: %d\n", gf_th_id()));\r
+\r
+       if (!rc->env)\r
+               return;\r
+\r
+       if ( rc->sensCtrlObj )\r
+       {\r
+               (*rc->env)->CallNonvirtualVoidMethod(rc->env, rc->sensCtrlObj, rc->sensCtrlClass, rc->stopSensor);\r
+\r
+               (*rc->env)->DeleteLocalRef( rc->env, rc->sensCtrlObj );\r
+       }\r
+\r
+       unloadSensorController(rc);\r
+}\r
+\r
+void MPEGVS_Start(struct __input_device * dr)\r
+{\r
+       MPEGVSCTX;\r
+       \r
+       rc->trd = gf_th_new("MPEG-V_IN");\r
+       gf_th_run(rc->trd, ThreadRun, dr);\r
+}\r
+\r
+void MPEGVS_Stop(struct __input_device * dr)\r
+{\r
+       MPEGVSCTX;\r
+\r
+       if ( rc->trd )\r
+       {\r
+               rc->stop = 1;\r
+               while ( gf_th_status(rc->trd) == GF_THREAD_STATUS_RUN )\r
+                       gf_sleep(5);\r
+\r
+               gf_th_del(rc->trd);\r
+               rc->trd = NULL;\r
+               rc->stop = 0;\r
+       }\r
+}\r
+\r
+GF_InputSensorDevice* NewMPEGVSInputSesor()\r
+{\r
+       MPEGVSensorContext* ctx = NULL;\r
+       GF_InputSensorDevice* driv = NULL;\r
+       \r
+       driv = (GF_InputSensorDevice *) gf_malloc(sizeof(GF_InputSensorDevice));\r
+       memset(driv, 0, sizeof(GF_InputSensorDevice));\r
+       GF_REGISTER_MODULE_INTERFACE(driv, GF_INPUT_DEVICE_INTERFACE, "MPEG-V Sensors Input Module", "gpac distribution");\r
+\r
+       driv->RegisterDevice = MPEGVS_RegisterDevice;\r
+       driv->Start = MPEGVS_Start;\r
+       driv->Stop = MPEGVS_Stop;\r
+\r
+       ctx = (MPEGVSensorContext*) gf_malloc (sizeof(MPEGVSensorContext));\r
+       memset(ctx, 0, sizeof(MPEGVSensorContext));\r
+       \r
+       driv->udta = (void*)ctx;\r
+\r
+       return driv;\r
+}\r
+\r
+void DeleteMPEGVSInputSensor(GF_InputSensorDevice* dev)\r
+{\r
+       MPEGVS_Stop(dev);\r
+       gf_free(dev->udta);\r
+       gf_free(dev);\r
+}\r
+\r
+/*interface query*/\r
+GF_EXPORT\r
+const u32 *QueryInterfaces() \r
+{\r
+       static u32 si [] = {\r
+               GF_INPUT_DEVICE_INTERFACE,\r
+               0\r
+       };\r
+       return si; \r
+}\r
+\r
+/*interface create*/\r
+GF_EXPORT\r
+GF_BaseInterface *LoadInterface(u32 InterfaceType)\r
+{\r
+       if (InterfaceType == GF_INPUT_DEVICE_INTERFACE) return (GF_BaseInterface *) NewMPEGVSInputSesor();\r
+       return NULL;\r
+}\r
+\r
+/*interface destroy*/\r
+GF_EXPORT\r
+void ShutdownInterface(GF_BaseInterface *ifce)\r
+{\r
+       switch (ifce->InterfaceType) {\r
+       case GF_INPUT_DEVICE_INTERFACE:\r
+               DeleteMPEGVSInputSensor((GF_InputSensorDevice *)ifce);\r
+               break;\r
+       }\r
+}\r
+\r
index c177145789a2525b53177e8a8401c0c61f4b5558..c47afcb4becd9771ce7c5630d69b99f862a03dc9 100644 (file)
@@ -1,12 +1,10 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Ivica Arsov, Jean Le Feuvre
+ *                     Copyright (c) Mines-Telecom 2009-
  *                                     All rights reserved
  *
- *     Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010
- *
  *  This file is part of GPAC / Wrapper
  *
  *  GPAC is free software; you can redistribute it and/or modify
index f63e9aba5ff1c713d051b6fed433d492aba26f8b..a32d45d26f4898e69a22c4a1dba3abc28a830005 100644 (file)
@@ -1,12 +1,10 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Ivica Arsov, Jean Le Feuvre
+ *                     Copyright (c) Mines-Telecom 2009-
  *                                     All rights reserved
  *
- *     Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010
- *
  *  This file is part of GPAC / Wrapper
  *
  *  GPAC is free software; you can redistribute it and/or modify
index 25765302c3fc6da0b114ac6f2abdaba673d29942..d7a7ad2ad3b2c8e3fd2bcb8dcfc415be1d421bab 100644 (file)
@@ -34,11 +34,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 6dc2605dec2f6609791ad66348641effa720b94a..7146d25c3a0e87f3a19535fa1da41c61e05f3113 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Dummy input module
@@ -42,6 +43,7 @@ typedef struct
        GF_ClientService *service;
        char *url;
        u32 oti;
+       Bool is_views_url;
        GF_List *channels;
 
        /*file downloader*/
@@ -123,6 +125,9 @@ Bool DC_CanHandleURL(GF_InputService *plug, const char *url)
                if (cgi_par) cgi_par[0] = '?';
                if (ok) return 1;
        }
+       /*views:// internal URI*/
+       if (!strnicmp(url, "views://", 8)) 
+               return 1;
 
        if (!strncmp(url, "\\\\", 2)) return 0;
 
@@ -226,6 +231,13 @@ GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const ch
        }
        read->service = serv;
 
+       if (!strnicmp(url, "views://", 8)) {
+               read->is_views_url = 1;
+               gf_term_on_connect(serv, NULL, GF_OK);
+               read->is_service_connected = 1;
+               return GF_OK;
+       }
+
        if (ext) {
                char *cgi_par = NULL;
                ext += 1;
@@ -319,6 +331,11 @@ static GF_Descriptor *DC_GetServiceDesc(GF_InputService *plug, u32 expect_type,
        iod->visual_profileAndLevel = 0xFE;
        iod->objectDescriptorID = 1;
 
+       if (read->is_views_url) {
+               iod->URLString = gf_strdup(read->url);
+               return (GF_Descriptor *)iod;
+       }
+
        esd = gf_odf_desc_esd_new(0);
        esd->slConfig->timestampResolution = 1000;
        esd->slConfig->useTimestampsFlag = 1;
index 1425f82958e9465bfa1e7fd42e17e613b45c8eb2..5676c66a6975fd0eda1ec1e9911ffa4874aa7069 100644 (file)
@@ -41,10 +41,6 @@ $(LIB): $(OBJS)
        windres "$(SRC_PATH)/modules/dx_hw/dx_hw.rc" dw_hw.o
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) dw_hw.o $(LDFLAGS_DX) -L../../bin/gcc -lgpac $(EXTRALIBS) 
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 ifeq ($(CONFIG_WIN32),yes)
index 9e39708f55ff15bcf0fe6f14600822c4bbb2ce9f..24ee473634c7d9919abfd49461e9a5f840968a54 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / 2D rendering module
index 6a21969a6c940f8de5b14cf3523d3394ace1f234..199d91df37a3e1ff752835fa73fc10a9478f3d33 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
@@ -402,7 +403,13 @@ static GF_Err DD_BlitSurface(DDContext *dd, DDSurface *src, GF_Window *src_wnd,
 
        if (src->is_yuv && dd->force_video_mem_for_yuv && dd->systems_memory) return GF_IO_ERR;
 
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Hardware blit src w=%d,h=%d to dst w=%d,h=%d - result: %08x\n", src_w, src_h, dst_w, dst_h, hr));
+#ifndef GPAC_DISABLE_LOG
+       if (hr) {
+               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DX Out] Failed blitting %s %s memory: error %08x\n", src->is_yuv ? "YUV" : "RGB", dd->systems_memory ? "systems" : "hardware", hr));
+       } else {
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] %s blit %s memory %dx%d -> %dx%d\n", src->is_yuv ? "YUV" : "RGB", dd->systems_memory ? "systems" : "hardware", src_w, src_h, dst_w, dst_h));
+       }
+#endif
        return FAILED(hr) ? GF_IO_ERR : GF_OK;
 }
 
@@ -439,7 +446,8 @@ static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 p
                        ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
 
                        ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
-                       if (dr->hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY)
+
+                       if (!dd->offscreen_yuv_to_rgb && (dr->hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY))
                                ddsd.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
 
                        ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
@@ -451,7 +459,21 @@ static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 p
                        if (FAILED(hr) ) {
                                if (!check_caps) return NULL;
 
-                               /*try withou overlay cap*/
+                               /*try without offscreen yuv->rgbcap*/
+                               if (dd->offscreen_yuv_to_rgb) {
+                                       dd->offscreen_yuv_to_rgb = 0;
+                                       if (dr->hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY) {
+                                               ddsd.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
+                                               hr = dd->pDD->lpVtbl->CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL);
+                                               if( FAILED(hr) ) {
+                                                       return NULL;
+                                               }
+                                       } else {
+                                               return NULL;
+                                       }
+                               }
+
+                               /*try without overlay cap*/
                                if (dr->hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY) {
                                        dr->hw_caps &= ~GF_VIDEO_HW_HAS_YUV_OVERLAY;
                                        ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
@@ -784,7 +806,7 @@ rem_fmt:
                gf_modules_set_option((GF_BaseInterface *)dr, "Video", "EnableOffscreenYUV", "yes");
        }
        if (opt && strcmp(opt, "yes")) dr->hw_caps &= ~GF_VIDEO_HW_HAS_YUV;
-
+       else dd->offscreen_yuv_to_rgb = 1;
 
        /*get YUV overlay key*/
        opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "OverlayColorKey");
index 3c5f02fa9dfdbb8a9990774a192d4f95cffbd9fc..a6d48c4a7ebc110393eec35049a20b6d4d7ca065 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
@@ -328,14 +329,14 @@ void DS_WriteAudio(GF_AudioOutput *dr)
 
        /*wait for end of current play buffer*/
        if (ctx->pOutput->lpVtbl->GetCurrentPosition(ctx->pOutput, &in_play, NULL) != DS_OK ) {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectSound] error getting sound buffer poitions\n"));
+               GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectSound] error getting sound buffer positions\n"));
                return;
        }
        in_play = (in_play / ctx->buffer_size);
        retry = 6;
        while (retry) {
                if (ctx->pOutput->lpVtbl->GetCurrentPosition(ctx->pOutput, &cur_play, NULL) != DS_OK ) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectSound] error getting sound buffer poitions\n"));
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectSound] error getting sound buffer positions\n"));
                        return;
                }
                cur_play = (cur_play / ctx->buffer_size);
index 12bb34af0b13b4d753c0c43b7dae3b8a9089873f..bd59d81a78568dce3546f214e3e4e2c916236dc2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
@@ -125,6 +126,7 @@ typedef struct
        Bool fullscreen;
        Bool systems_memory;
        Bool force_alpha;
+       Bool offscreen_yuv_to_rgb;
 
        u32 width, height;
        u32 fs_width, fs_height;
index 7f9b19094e4bcb74d534704cdc1289220643be78..e84cf1461bb011d112beb2f1ddd14a6d456cf342 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
@@ -542,6 +543,11 @@ static GF_Err DD_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u32
                if (!dd->fullscreen && (dd->os_hwnd==dd->fs_hwnd)) {
                        SetWindowPos(dd->os_hwnd, NULL, 0, 0, dd->store_width+dd->off_w, dd->store_height+dd->off_h, SWP_NOZORDER | SWP_NOMOVE | SWP_ASYNCWINDOWPOS);
                }
+               /*first time FS, store*/
+               if (!dd->store_width) {
+                       dd->store_width = dd->width;
+                       dd->store_height = dd->height;
+               }
                e = InitDirectDraw(dr, dd->store_width, dd->store_height);
        }
 
index 3939c4cbbe254eaad6519953181d4f121630a1f6..9f5b67868a853e91d4be64cbed0839ca37935103 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
index 4aef8dcd6bba127e9ea169162534c68ddc188757..42adc86197784ae87d8a15320ede933ee1f94b11 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / wave audio render module
index ca4b6ef89b57bf069c6ca4c6f6ca50d7a5847ba9..4171ad4a39b87259d49825c87ffcfe6ff9ece73f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / AAC reader module
index 5e748a8723233fe7d31bc4de0ec44e91283b212a..b6afacbb1626c5839fde997b4127c394a724d230 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / EPOC video output module
index bcff76633bff165851487e2cb2ff44ef84e12f1f..10dc9e0619eda53ed49ee4d0ebc0cea01c5b4746 100644 (file)
@@ -62,11 +62,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc $(LOCAL_LIB) $(LINKLIBS) $(EXTRALIBS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index db7d65ecf4822c0095715e6677aa8113526b02e7..592cee2ff47150795ee083f331027e6c1e0324fe 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / FFMPEG module
index 0f8ee5078c0a7a1d2ca258ed6403b8564d330524..77a9efef6ab3fbf55cf212311a0c89ff9729de7c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / FFMPEG module
@@ -260,6 +261,7 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url)
                /*note we forbid ffmpeg to handle files we support*/
                if (!strcmp(szExt, "mp4") || !strcmp(szExt, "mpg4") || !strcmp(szExt, "m4a") || !strcmp(szExt, "m21")
                        || !strcmp(szExt, "m4v") || !strcmp(szExt, "m4a")
+                       || !strcmp(szExt, "m4s") || !strcmp(szExt, "3gs")
                        || !strcmp(szExt, "3gp") || !strcmp(szExt, "3gpp") || !strcmp(szExt, "3gp2") || !strcmp(szExt, "3g2")
                        || !strcmp(szExt, "mp3")
                        || !strcmp(szExt, "ac3")
@@ -698,6 +700,7 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv,
                ffd->seekable = (av_seek_frame(ffd->ctx, -1, 0, AVSEEK_FLAG_BACKWARD)<0) ? 0 : 1;
                if (!ffd->seekable) {
                        av_close_input_file(ffd->ctx);
+                       ffd->ctx = NULL;
                        open_file(&ffd->ctx, szName, av_in);
                        av_find_stream_info(ffd->ctx);
                }
index 4b2bdf50d169c27a6faa7b4cf0420ac5bc45b5df..5f90198380154d1da172e645931e529f7c513757 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MP4 reader module
index 2724f143ef2d6d48ee2a6bb6d9e8800d31b273ae..4c9749814327a4e1fa7b11e02d6512d51631d5f6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / FFMPEG module
index cb4810c84aa6b61f3cd61232ba14a26a2b772a67..16cef5dae8b63db3ef63d66fa11c43bf22b713f7 100644 (file)
@@ -39,11 +39,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CXX) -w $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKLIBS)
 
-
-%.o: %.cpp
-       $(CXX) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index d7dcdd35de471aae5ef9b7add34f9fd534f28d79..b8cfee7e56bba44c58aa8bb4f58e98756eb58756 100644 (file)
@@ -38,8 +38,8 @@
 #include <gpac/thread.h>
 
 
-#ifndef FREENECT_RESOLUTION_MEDIUM
-#define FREENECT_MINIMAL
+#ifndef FREENECT_RESOLUTION_HIGH
+//#define FREENECT_MINIMAL
 #endif
 
 
index 1b5fa80fe86df6992b549cb42ec605b0f1078d7d..ff52be0ff21b89bd9ada46e590ba1afc22364b32 100644 (file)
@@ -42,10 +42,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 22f8036f39277135bb4428ae4d80341be9f9ddc6..e90f5cfa4b306edf3240835d8ab8f8a703426cb0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / FreeType font engine module
index 689976e1138f1ec93f60f50025f1f19669b18b38..4fc6531515142e6355f70bb282da09238bcf8a17 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / FreeType font engine module
index 37231fdcea548633fd588e9d4829cd889f98c26d..7230a09413eda14e70f2f2a03c3670c011a2a35e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GAPI WinCE-iPaq video render module
index 13bd73838f2db094fd300ae258cd864157ff48ae..565ccacf3b17a4a2534dab08cf98bcd3470b0144 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
index 343a74871f3d4cdf1da68ef5ac0e5a462990c9d5..f795efd7fbb57d9eca5c3a91da0c2734a6bcb818 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GDIplus rasterizer module
index 7ab52fe15a2e6183e25f68f74f53576fa6b85cc4..f20425d85330cffdff1155036af316fc8562098f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GDIplus rasterizer module
index c144cd79753346fe5b53673982c0662f55c01d2f..e2817f0caf14e8b3d43a0663a6bf512b6d0a80e4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GDIplus rasterizer module
index a481f8d23800f470de81401a16503b8c0cf81e37..7a49653d2bf0539af973198aafdca703c677fca3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GDIplus rasterizer module
index e0d4b62f104fac5216d42a7e33fea026da024291..58a81a4a3521ff64f42d104ca1ca7fb8f16b1b4e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / GDIplus rasterizer module
index c9258f8d0a3c5d41783007c4223b59563d75fd1f..73ba409ba50c3122ea0126ce3a239886fddb4fff 100644 (file)
@@ -48,11 +48,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index cca3b5b8d39556ae3cc493c9ec40d6c052d857d4..2144838c839739affeadb70b459e44d80e9821be 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2007-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -60,9 +60,9 @@ typedef struct
        u32 nb_loaded;
        GF_Terminal *term;
 
-       JSClass gpacClass;
-       JSClass gpacEvtClass;
-       JSClass anyClass;
+       GF_JSClass gpacClass;
+       GF_JSClass gpacEvtClass;
+       GF_JSClass anyClass;
 
        jsval evt_fun;
        GF_TermEventFilter evt_filter;
@@ -83,8 +83,8 @@ static GF_Terminal *gpac_get_term(JSContext *c, JSObject *obj)
        return ext ? ext->term : NULL;
 }
 
-static JSBool gpac_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( gpac_getProperty)
+
        const char *res;
        char *prop_name;
        GF_Terminal *term = gpac_get_term(c, obj);
@@ -201,8 +201,8 @@ static JSBool gpac_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
        SMJS_FREE(c, prop_name);
        return JS_TRUE;
 }
-static JSBool gpac_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( gpac_setProperty)
+
        char *prop_name, *prop_val;
        GF_Terminal *term = gpac_get_term(c, obj);
        if (!term) return JS_FALSE;
@@ -662,8 +662,8 @@ static JSBool SMJS_FUNCTION(gpac_migrate_url)
        return JS_TRUE;
 }
 
-static JSBool gpacevt_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( gpacevt_getProperty)
+
        GF_GPACJSExt *gjs = SMJS_GET_PRIVATE(c, obj);
        GF_Event *evt = gjs->evt;
        if (!evt) return 0;
@@ -834,7 +834,7 @@ static JSBool SMJS_FUNCTION(gpac_get_scene)
        if (!scene) return JS_TRUE;
 
 
-       scene_obj = JS_NewObject(c, &gjs->anyClass, 0, 0);
+       scene_obj = JS_NewObject(c, &gjs->anyClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, scene_obj, scene);
        gf_sg_get_scene_size_info(scene->graph, &w, &h);
        JS_DefineProperty(c, scene_obj, "width", INT_TO_JSVAL(w), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -910,8 +910,8 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext
        JS_SETUP_CLASS(gjs->gpacClass, "GPAC", JSCLASS_HAS_PRIVATE, gpac_getProperty, gpac_setProperty, JS_FinalizeStub);
 
        if (!gjs->gpac_obj) {
-               JS_InitClass(c, global, 0, &gjs->gpacClass, 0, 0, gpacClassProps, gpacClassFuncs, 0, 0);
-               gjs->gpac_obj = JS_DefineObject(c, global, "gpac", &gjs->gpacClass, 0, 0);
+               GF_JS_InitClass(c, global, 0, &gjs->gpacClass, 0, 0, gpacClassProps, gpacClassFuncs, 0, 0);
+               gjs->gpac_obj = JS_DefineObject(c, global, "gpac", &gjs->gpacClass._class, 0, 0);
 
                if (scene->script_action) {
                        if (scene->script_action(scene->script_action_cbck, GF_JSAPI_OP_GET_TERM, scene->RootNode, &par)) {
@@ -925,8 +925,8 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext
 
        if (!gjs->evt_obj) {
                JS_SETUP_CLASS(gjs->gpacEvtClass, "GPACEVT", JSCLASS_HAS_PRIVATE, gpacevt_getProperty, JS_PropertyStub_forSetter, JS_FinalizeStub);
-               JS_InitClass(c, global, 0, &gjs->gpacEvtClass, 0, 0, gpacEvtClassProps, gpacEvtClassFuncs, 0, 0);
-               gjs->evt_obj = JS_DefineObject(c, global, "gpacevt", &gjs->gpacEvtClass, 0, 0);
+               GF_JS_InitClass(c, global, 0, &gjs->gpacEvtClass, 0, 0, gpacEvtClassProps, gpacEvtClassFuncs, 0, 0);
+               gjs->evt_obj = JS_DefineObject(c, global, "gpacevt", &gjs->gpacEvtClass._class, 0, 0);
 
 #define DECLARE_GPAC_CONST(name) \
                JS_DefineProperty(c, global, #name, INT_TO_JSVAL(name), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -959,7 +959,7 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext
                DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_3D);
                
                JS_SETUP_CLASS(gjs->anyClass, "GPACOBJECT", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
-               JS_InitClass(c, global, 0, &gjs->anyClass, 0, 0, 0, 0, 0, 0);
+               GF_JS_InitClass(c, global, 0, &gjs->anyClass, 0, 0, 0, 0, 0, 0);
 
                gjs->evt_fun = JSVAL_NULL;
                }
index bdc9531a8f8fa0acf1d6b97d4456856493ce2e6a..244305faa8012f9f0fac03997d99ce2e71ec981c 100644 (file)
@@ -31,11 +31,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_hyb_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index f085be125b0f1d4cc005113ff7f6171594d51833..6c89a0ede2362c3ce877309db8bc595046bee1e6 100644 (file)
@@ -63,11 +63,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_img_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 6dc1e21c37c05ec47b1bd74280f301da1c6068d8..5918c8cf3f14b610f92168ce6fe204bb6696dd3b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / image format module
index 69c5ddc4bf00548ea1a80a09773913191888470b..88189dfa9047e72cc130507a11048e0a2611dc0f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / image format module
index 7ce064f56296600ac7ace4c659b7702301a94699..9abe261dd48e4810c08d54fd840f6905e1f0d0c0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / image format module
@@ -69,10 +70,12 @@ GF_ESD *IMG_GetESD(IMGLoader *read)
        if (read->img_type == IMG_BMP)
                esd->decoderConfig->objectTypeIndication = GPAC_BMP_OTI;
        else {
-               u8 OTI;
+               u8 OTI=0;
                u32 mtype, w, h;
                GF_BitStream *bs = gf_bs_from_file(read->stream, GF_BITSTREAM_READ);
+#ifndef GPAC_DISABLE_AV_PARSERS
                gf_img_parse(bs, &OTI, &mtype, &w, &h, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);
+#endif
                gf_bs_del(bs);
 
                if (!OTI) {
index 6f870caf9892be364429d1d91abfa98183b43b40..33742352251f8f94fc457e39217cbb25866fecb5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / image format module
index e3a13c9255fa4f1eb7e7d19571eead12bb4c8b28..5d46c2de66bf22d6006db3eff04c31dc1e847432 100644 (file)
@@ -1,7 +1,8 @@
 /*
 *                      GPAC - Multimedia Framework C SDK
 *
-*                      Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / image format module
index 36769135675767561abb255629364c7e723d78be..7f1279945ad361c1b6e83da34444943666f4de07 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / image format module
@@ -101,6 +102,7 @@ static GF_Err JPEG_ProcessData(GF_MediaDecoder *ifcg,
                char *outBuffer, u32 *outBufferLength,
                u8 PaddingBits, u32 mmlevel)
 {
+#ifndef GPAC_DISABLE_AV_PARSERS
        GF_Err e;
        JPEGCTX();
 
@@ -111,6 +113,9 @@ static GF_Err JPEG_ProcessData(GF_MediaDecoder *ifcg,
        }
        ctx->out_size = *outBufferLength;
        return e;
+#else
+       return GF_NOT_SUPPORTED;
+#endif //GPAC_DISABLE_AV_PARSERS
 }
 
 static const char *JPEG_GetCodecName(GF_BaseDecoder *dec)
index 4f5a1a4c7d8e7a8234c84449491fb04a1f53b6dc..55d4583065f35f51fe995f401075be560fb36380 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / image format module
@@ -115,6 +116,7 @@ static GF_Err PNG_ProcessData(GF_MediaDecoder *ifcg,
                char *outBuffer, u32 *outBufferLength,
                u8 PaddingBits, u32 mmlevel)
 {
+#ifndef GPAC_DISABLE_AV_PARSERS
        GF_Err e;
        PNGCTX();
 
@@ -137,6 +139,9 @@ static GF_Err PNG_ProcessData(GF_MediaDecoder *ifcg,
        }
        ctx->out_size = *outBufferLength;
        return e;
+#else
+       return GF_NOT_SUPPORTED;
+#endif //GPAC_DISABLE_AV_PARSERS
 }
 
 static const char *PNG_GetCodecName(GF_BaseDecoder *dec)
index d83c52dcdc0e858b8ee53b235c236a0281346d88..0b49d73453dc56c0ba49c677bf86469e188237f3 100644 (file)
@@ -33,11 +33,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ismacryp-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index db86ff80e34515ef42e23f7cc72fc48a643cf22f..8d05469dce4e116cae01f77d04419377d4a27ef9 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / LASeR decoder module
index df8f591cc4d119dff080b7a049aa55a8630d70a3..fab86c7739bc53dcd769a77a8dd8405143cf888f 100644 (file)
@@ -34,11 +34,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_isom_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) 
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 714ca8e46eb8a1ffcebc63567883edc15c8e0907..e640fc10d03b3e0d9309b61c1575244bc6c8c36f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MP4 cache module
index 2ef8bbd761b245add95169e2524d99654b5c980a..18945a171cbdfdbae58fc5b9287da9a5f5bccefc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MP4 reader module
@@ -73,8 +74,7 @@ typedef struct
        ISOMReader *owner;
        u64 duration;
 
-       Bool wait_for_segment_switch;
-
+       Bool wait_for_segment_switch, needs_codec_update;
        /*current sample*/
        GF_ISOSample *sample;
        GF_SLHeader current_slh;
index 3bc504de6f13c975e17819bda7b98b57886600ff..02405ab54dcb756c80d901831978b2204e228a53 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MP4 reader module
index e844cb2187b0e1118747cb00706707dcc7815156..24c688a1e66ba25ea3a81a2c64aa8d414b3b931c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IsoMedia reader module
index 3011102810fdf5b5c305d5980003b6f528a82acd..744a69da4ed3cdbeb3822c5e248a18672699fb59 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MP4 reader module
@@ -66,7 +67,7 @@ static void check_segment_switch(ISOMReader *read)
        }
        /*close current segment*/
        gf_isom_release_segment(read->mov, 1);
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Done playing segment - querying new one\n"));
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Done playing segment - querying new one\n"));
 
        /*update current fragment if any*/
        param.command_type = GF_NET_SERVICE_QUERY_NEXT;
@@ -74,27 +75,38 @@ static void check_segment_switch(ISOMReader *read)
                if (param.url_query.discontinuity_type==2)
                        gf_isom_reset_fragment_info(read->mov);
 
+               if (param.url_query.next_url_init_or_switch_segment) {
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Switching between files - opening new init segment %s\n", param.url_query.next_url_init_or_switch_segment));
+                       if (read->mov) gf_isom_close(read->mov);
+                       e = gf_isom_open_progressive(param.url_query.next_url_init_or_switch_segment, param.url_query.switch_start_range, param.url_query.switch_end_range, &read->mov, &read->missing_bytes);
+               }
+
                e = gf_isom_open_segment(read->mov, param.url_query.next_url, param.url_query.start_range, param.url_query.end_range);
 
 #ifndef GPAC_DISABLE_LOG
                if (e<0) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[IsoMedia] Error opening new segment %s: %s\n", param.url_query.next_url, gf_error_to_string(e) ));
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[IsoMedia] Error opening new segment %s: %s\n", param.url_query.next_url, gf_error_to_string(e) ));
                } else if (param.url_query.end_range) {
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Playing new range in %s: "LLU"-"LLU"\n", param.url_query.next_url, param.url_query.start_range, param.url_query.end_range ));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Playing new range in %s: "LLU"-"LLU"\n", param.url_query.next_url, param.url_query.start_range, param.url_query.end_range ));
                } else {
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] playing new segment %s\n", param.url_query.next_url));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] playing new segment %s\n", param.url_query.next_url));
                }
 #endif
 
                for (i=0; i<count; i++) {
                        ISOMChannel *ch = gf_list_get(read->channels, i);
                        ch->wait_for_segment_switch = 0;
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track %d - cur sample %d - new sample count %d\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track) ));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Track %d - cur sample %d - new sample count %d\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track) ));
+                       if (param.url_query.next_url_init_or_switch_segment) {
+                               ch->needs_codec_update = 1;
+                               /*we changed our moov structure, sample_num now starts from 0*/
+                               ch->sample_num = 0;
+                       }
                }
        } else {
                /*consider we are done*/
                read->frag_type = 2;
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] No more segments - done playing file\n"));
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] No more segments - done playing file\n"));
        }
        gf_mx_v(read->segment_mutex);
 }
@@ -262,17 +274,17 @@ fetch_next:
                        if (ch->owner->frag_type==1) {
                                if (!ch->wait_for_segment_switch) {
                                        ch->wait_for_segment_switch = 1;
-                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track #%d end of segment reached - waiting for sample %d - current count %d\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track) ));
+                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Track #%d end of segment reached - waiting for sample %d - current count %d\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track) ));
                                }
                                /*if sample cannot be found and file is fragmented, rewind sample*/
                                if (ch->sample_num) ch->sample_num--;
                                ch->last_state = GF_OK;
                        } else {
-                               GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track #%d end of stream reached\n", ch->track));
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Track #%d end of stream reached\n", ch->track));
                                ch->last_state = GF_EOS;
                        }
                } else {
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track #%d fail to fetch sample %d / %d: %s\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track), gf_error_to_string(gf_isom_last_error(ch->owner->mov)) ));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Track #%d fail to fetch sample %d / %d: %s\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track), gf_error_to_string(gf_isom_last_error(ch->owner->mov)) ));
                }
                if (ch->wait_for_segment_switch)
                        check_segment_switch(ch->owner);
@@ -294,7 +306,7 @@ fetch_next:
        ch->current_slh.randomAccessPointFlag = ch->sample->IsRAP;
 
        if (ch->end && (ch->end < ch->sample->DTS + ch->sample->CTS_Offset)) {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] End of Channel "LLD" (CTS "LLD")\n", ch->end, ch->sample->DTS + ch->sample->CTS_Offset));
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] End of Channel "LLD" (CTS "LLD")\n", ch->end, ch->sample->DTS + ch->sample->CTS_Offset));
                ch->last_state = GF_EOS;
        }
 
@@ -313,6 +325,62 @@ fetch_next:
                        ch->current_slh.isma_encrypted = 0;
                }
        }
+
+       /*this is ugly we need a rearchitecture of the streaming part of GPAC to handle codec changes properly - fortunately in DASH we cannot switch codec on
+       the fly (not in the same representation)!! */
+       if (ch->sample && ch->needs_codec_update) {
+               GF_AVCConfig *avccfg, *svccfg;
+               GF_AVCConfigSlot *slc;
+               GF_BitStream *bs;
+               u32 i; 
+               ch->needs_codec_update = 0;
+
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[IsoMedia] Codec configuration changed - rewriting sample\n"));
+
+               switch (gf_isom_get_media_subtype(ch->owner->mov, ch->track, 1)) {
+               case GF_ISOM_SUBTYPE_AVC_H264:
+               case GF_ISOM_SUBTYPE_AVC2_H264:
+               case GF_ISOM_SUBTYPE_SVC_H264:
+                       avccfg = gf_isom_avc_config_get(ch->owner->mov, ch->track, 1);
+                       svccfg = gf_isom_svc_config_get(ch->owner->mov, ch->track, 1);
+
+                       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+                       if (avccfg) {
+                               for (i=0; i<gf_list_count(avccfg->sequenceParameterSets); i++) {
+                                       slc = gf_list_get(avccfg->sequenceParameterSets, i);
+                                       gf_bs_write_int(bs, slc->size, avccfg->nal_unit_size*8);
+                                       gf_bs_write_data(bs, slc->data, slc->size);
+                               }
+                               for (i=0; i<gf_list_count(avccfg->pictureParameterSets); i++) {
+                                       slc = gf_list_get(avccfg->pictureParameterSets, i);
+                                       gf_bs_write_int(bs, slc->size, avccfg->nal_unit_size*8);
+                                       gf_bs_write_data(bs, slc->data, slc->size);
+                               }
+                               gf_odf_avc_cfg_del(avccfg);
+                       }
+                       if (svccfg) {
+                               for (i=0; i<gf_list_count(svccfg->sequenceParameterSets); i++) {
+                                       slc = gf_list_get(svccfg->sequenceParameterSets, i);
+                                       gf_bs_write_int(bs, slc->size, avccfg->nal_unit_size*8);
+                                       gf_bs_write_data(bs, slc->data, slc->size);
+                               }
+                               for (i=0; i<gf_list_count(svccfg->pictureParameterSets); i++) {
+                                       slc = gf_list_get(svccfg->pictureParameterSets, i);
+                                       gf_bs_write_int(bs, slc->size, avccfg->nal_unit_size*8);
+                                       gf_bs_write_data(bs, slc->data, slc->size);
+                               }
+                               gf_odf_avc_cfg_del(svccfg);
+                       }
+                       gf_bs_write_data(bs, ch->sample->data, ch->sample->dataLength);
+                       gf_free(ch->sample->data);
+                       ch->sample->data = 0;
+                       gf_bs_get_content(bs, &ch->sample->data, &ch->sample->dataLength);
+                       gf_bs_del(bs);
+                       break;
+               default:
+                       break;
+               }
+       }
 }
 
 void isor_reader_release_sample(ISOMChannel *ch)
index 0037f679d92c1ce0e17c3442035f82b83b4fb6b4..0902d646c2f99bc27389844519b13e1a992e3de5 100644 (file)
@@ -27,11 +27,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -L/usr/lib  -ljack
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 3eb5891dcd5f9efb6a539d24c944cc81c7eb6907..106aa80af69f280b611033ddb521a4bc61c9a699 100644 (file)
@@ -1,8 +1,6 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
- *                                     All rights reserved
  *                     Copyright (c) Pierre Souchay 2008
  *  History:
  *
index f457f73e11dbe8cf8003e6b6882d1e44098c032b..e695b1919a61b7250d45b8be1a574396e60ec66a 100644 (file)
@@ -35,10 +35,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 5469af54382e4da39f13c5012ddd63a3f3fb5ca5..c73cdfae9e81b759db4a4d01584646eb4a219d5b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / LASeR decoder module
index 3266c9027a87a5e7fc6937a9f532a8cbd4a7bc80..916e644fab9409fce67b42208e222ccfde5e8b8e 100644 (file)
@@ -28,10 +28,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -lplayer
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 57dda9110d70788fa9a85b063af98225219dc40f..1ab9b6737a3a2534f46c48ad461d90ba7c14033b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Dummy input module
@@ -347,9 +348,9 @@ GF_Err LIBPLAYER_CloseService(GF_InputService *plug)
        // only disconnect if 
        if (read->player_type == PLAYER_FILE) {
                player_playback_stop(read->player);
-               printf("[LibPlayerIN]player_playback_stop for instance %d\n", read->player_id);
+               fprintf(stderr, "[LibPlayerIN]player_playback_stop for instance %d\n", read->player_id);
                player_uninit(read->player);
-               printf("[LibPlayerIN]player_uninit for instance %d\n", read->player_id);
+               fprintf(stderr, "[LibPlayerIN]player_uninit for instance %d\n", read->player_id);
                read->player = NULL;
                libplayer_id--;
                
@@ -538,7 +539,7 @@ static GF_Err LIBPLAYER_Control(GF_PrivateMediaDecoder *dec, Bool mute, GF_Windo
        //! unfortunately, saving data would not be a good solution for Mosaic Mode in ESG Application since the position changes everytime user 
        //! uses the navigation button
        //~ if (read->player_id == 1 && save_data_instance1 == 1) {
-               //~ printf("in here for save data instance\n");
+               //~ fprintf(stderr, "in here for save data instance\n");
                //~ player_video_io_windows_set(read->player, &in_instance1, &out_instance1);
                //~ 
                //~ return GF_OK;
@@ -551,8 +552,8 @@ static GF_Err LIBPLAYER_Control(GF_PrivateMediaDecoder *dec, Bool mute, GF_Windo
        
 
        if((width != read->width) || (height != read->height))  {
-               printf("in here for video size changed\t");
-               printf("width %d read->width %d height %d read->height %d\n", width, read->width, height, read->height);
+               fprintf(stderr, "in here for video size changed\t");
+               fprintf(stderr, "width %d read->width %d height %d read->height %d\n", width, read->width, height, read->height);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] video size changed to width %d - height %d\n", width, height));
                if (width && height) {
                        read->width = width;
index 4b050bf9630d5c01368a72d0880d019378ed1816..08d077eba908cb66d374234748ddc938e69f7cee 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
- *                     Copyright (c) ENST 2008 - 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC 
index d77f42fb13c110598e67b0b66ba3a19622cbff78..5dbdf5e43f718f32efb3898d60255e73f4bda16e 100644 (file)
@@ -50,10 +50,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 2ccd017cfe78aff5ddfb2fa0543ed0c6945f5f0e..dff071145ef505633a34246fe8ab4498446a5564 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / codec pack module
index 6ae3255961a0ee3186d914ac588da0e78099efae..4269701496aeb2bb780dd018473a7e7936532c34 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MP3 reader module
index 22bb3853430d24e362a93628518daa161cd60d0a..af0718d377371d36c49fe1d73254c73151c1527a 100644 (file)
@@ -31,11 +31,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mpegts_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 4dcc2ac562d5316224b69d95561b8bafc70eb548..7c4bbe932585ac4041744fa3da038ee9757e457c 100644 (file)
  */
 
 #include <gpac/modules/service.h>
-#include <gpac/internal/terminal_dev.h>
-#include <gpac/thread.h>
-#include <gpac/network.h>
-#include <gpac/crypt.h>
-#include <gpac/internal/mpd.h>
-#include <gpac/internal/m3u8.h>
-#include <string.h>
-
-/*set to 1 if you want MPD to use SegmentTemplate if possible instead of SegmentList*/
-#define M3U8_TO_MPD_USE_TEMPLATE       0
-
-/*!
- * All the possible Mime-types for MPD files
- */
-static const char * MPD_MIME_TYPES[] = { "application/dash+xml", "video/vnd.3gpp.mpd", "audio/vnd.3gpp.mpd", NULL };
-
-/*!
- * All the possible Mime-types for M3U8 files
- */
-static const char * M3U8_MIME_TYPES[] = { "video/x-mpegurl", "audio/x-mpegurl", "application/x-mpegurl", "application/vnd.apple.mpegurl", NULL};
 
-typedef enum {
-       MPD_STATE_STOPPED = 0,
-       MPD_STATE_RUNNING,
-       MPD_STATE_CONNECTING,
-} MPD_STATE;
+#ifndef GPAC_DISABLE_DASH_CLIENT
 
-GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession ** sess, const char *url, gf_dm_user_io user_io,  void *usr_cbk, u64 start_range, u64 end_range, Bool persistent);
+#include <gpac/dash.h>
+#include <gpac/internal/terminal_dev.h>
 
-typedef struct
-{
-    char *cache;
-    char *url;
-       u64 start_range, end_range;
-} segment_cache_entry;
 
-/*this structure Group is the implementation of the adaptationSet element of the MPD.*/
-typedef struct __mpd_group 
+typedef struct __mpd_module 
 {
-       /*pointer to adaptation set*/
-       GF_MPD_AdaptationSet *adaptation_set;
-       /*pointer to active period*/
-       GF_MPD_Period *period;
-
-       /*active representation index in adaptation_set->representations*/
-       u32 active_rep_index;
-
-       Bool selected;
-       Bool done;
-       Bool force_switch_bandwidth, min_bandwidth_selected;
-       u32 nb_bw_check;
-       u32 active_bitrate, max_bitrate, min_bitrate;
-
-       u32 nb_segments_in_rep;
-       Double segment_duration;
-
-       /*local file playback, do not delete them*/
-       Bool local_files;
-       /*next segment to download for this group*/
-       u32 download_segment_index;
-
-       /*next file (cached) to delete at next GF_NET_SERVICE_QUERY_NEXT for this group*/
-    char * urlToDeleteNext;
-    volatile u32 max_cached_segments, nb_cached_segments;
-    segment_cache_entry *cached;
-
-    GF_DownloadSession *segment_dnload;
-    const char *segment_local_url;
-       /*usually 0-0 (no range) but can be non-zero when playing local MPD/DASH sessions*/
-       u64 local_url_start_range, local_url_end_range;
-
-    u32 nb_segments_done;
-
-    Bool segment_must_be_streamed;
-
-       /* Service really managing the segments */
-    GF_InputService *input_module;
-    char *service_mime;
-    Bool service_connected, service_descriptor_fetched;
-
-       struct __mpd_module *mpd_in;
-
-       u32 force_representation_idx_plus_one;
-
-       Bool force_segment_switch;
-
-       /*set when switching segment, indicates the current downloaded segment duration*/
-    u64 current_downloaded_segment_duration;
-} GF_MPD_Group;
-
-typedef struct __mpd_module {
     /* GPAC Service object (i.e. how this module is seen by the terminal)*/
     GF_ClientService *service;
-    /* URL to which this service is connected
-       Used to detect when audio service connection request is made on the same URL as video */
-    char *url;
+       GF_InputService *plug;
+       
+       GF_DashClient *dash;
 
        /*interface to mpd parser*/
-       GF_FileDownload getter;
-
-    u32 option_max_cached;
-    u32 auto_switch_count;
-    Bool keep_files, disable_switching;
-
-       /* MPD downloader*/
-    GF_DownloadSession *mpd_dnload;
-       /* MPD */
-    GF_MPD *mpd;
-       /* number of time the MPD has been reloaded and last update time*/
-    u32 reload_count, last_update_time;
-       /*signature of last MPD*/
-    u8 lastMPDSignature[20];
-       /*mime used by M3U8 server*/
-    char *mimeTypeForM3U8Segments;
-
-       /* active period in MPD (only one currently supported) */
-    u32 active_period_index;
-       u32 request_period_switch;
-
-       u64 start_time_in_active_period;
-
-       /*list of groups in the active period*/
-       GF_List *groups;
-       /*group 0 if present, NULL otherwise*/
-       GF_MPD_Group *group_zero_selected;
-
-    /*Main MPD Thread handling segment downloads and MPD/M3U8 update*/
-    GF_Thread *mpd_thread;
-       /*mutex for group->cache file name access and MPD update*/
-    GF_Mutex *dl_mutex;
-
-    /* 0 not started, 1 download in progress */
-    MPD_STATE mpd_is_running;
-    Bool mpd_stop_request;
-       Bool in_period_setup;
-
-    /* TODO - handle playback status for SPEED/SEEK through SIDX */
-    Double playback_speed, playback_start_range, previous_start_range;
-       Double start_range_in_segment_at_next_period;
+       GF_DASHFileIO dash_io;
+
+       Bool connection_ack_sent;
        Bool in_seek;
+    Double previous_start_range;
 } GF_MPD_In;
 
-void MPD_ResetGroups(GF_MPD_In *mpdin);
-GF_Err MPD_SetupPeriod(GF_MPD_In *mpdin);
-
-
-
-static const char *MPD_GetMimeType(GF_MPD_SubRepresentation *subrep, GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set)
+typedef struct 
 {
-       if (subrep && subrep->mime_type) return subrep->mime_type;
-       if (rep && rep->mime_type) return rep->mime_type;
-       if (set && set->mime_type) return set->mime_type;
-       return NULL;
-}
+       GF_InputService *segment_ifce;
+       Bool service_connected;
+       Bool service_descriptor_fetched;
+} GF_MPDGroup;
 
+const char * MPD_MPD_DESC = "MPEG-DASH Streaming";
+const char * MPD_MPD_EXT = "3gm mpd";
+const char * MPD_M3U8_DESC = "Apple HLS Streaming";
+const char * MPD_M3U8_EXT = "m3u8 m3u";
 
-static Bool MPD_CheckRootType(const char *local_url)
+static u32 MPD_RegisterMimeTypes(const GF_InputService *plug)
 {
-    if (local_url) {
-        char *rtype = gf_xml_get_root_type(local_url, NULL);
-        if (rtype) {
-            Bool handled = 0;
-            if (!strcmp(rtype, "MPD")) {
-                handled = 1;
-            }
-            gf_free(rtype);
-            return handled;
-        }
-    }
-    return 0;
+    u32 i, c;
+    for (i = 0 ; GF_DASH_MPD_MIME_TYPES[i]; i++)
+        gf_term_register_mime_type (plug, GF_DASH_MPD_MIME_TYPES[i], MPD_MPD_EXT, MPD_MPD_DESC);
+    c = i;
+    for (i = 0 ; GF_DASH_M3U8_MIME_TYPES[i]; i++)
+        gf_term_register_mime_type(plug, GF_DASH_M3U8_MIME_TYPES[i], MPD_M3U8_EXT, MPD_M3U8_DESC);
+    return c+i;
 }
 
-/**
- * NET IO for MPD, we don't need this anymore since mime-type can be given by session
- */
-void MPD_NetIO_Segment(void *cbk, GF_NETIO_Parameter *param)
+Bool MPD_CanHandleURL(GF_InputService *plug, const char *url)
 {
-    GF_Err e;
-       u32 download_rate;
-    GF_MPD_Group *group= (GF_MPD_Group*) cbk;
-
-    /*handle service message*/
-    gf_term_download_update_stats(group->segment_dnload);
-       if (group->done) {
-               gf_dm_sess_abort(group->segment_dnload);
-               return;
-       }       
-       
-    if ((param->msg_type == GF_NETIO_PARSE_HEADER) && !strcmp(param->name, "Content-Type")) {
-               if (!group->service_mime) {
-                       group->service_mime = gf_strdup(param->value);
-               } else if (stricmp(group->service_mime, param->value)) {
-                       GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);
-                       if (! MPD_GetMimeType(NULL, rep, group->adaptation_set) ) rep->mime_type = gf_strdup(param->value);
-                       rep->disabled = 1;
-                       GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE,
-                               ("[MPD_IN] Disabling representation since mime does not match: expected %s, but had %s for %s!\n", group->service_mime, param->value, gf_dm_sess_get_resource_name(group->segment_dnload)));
-                       group->force_switch_bandwidth = 1;
-                       gf_dm_sess_abort(group->segment_dnload);
-                       return;
-               }
-       }
-
-       e = param->error;
-       if (param->msg_type == GF_NETIO_PARSE_REPLY) {
-               if (! gf_dm_sess_can_be_cached_on_disk(group->segment_dnload)) {
-                       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE,
-                               ("[MPD_IN] Segment %s cannot be cached on disk, will use direct streaming\n", gf_dm_sess_get_resource_name(group->segment_dnload)));
-                       group->segment_must_be_streamed = 1;
-                       gf_dm_sess_abort(group->segment_dnload);
-               } else {
-                       group->segment_must_be_streamed = 0;
-               }
-       }
-       else if ((param->msg_type == GF_NETIO_DATA_EXCHANGE) || (param->msg_type == GF_NETIO_DATA_TRANSFERED)) {
-               if (!group->mpd_in->disable_switching && (gf_dm_sess_get_stats(group->segment_dnload, NULL, NULL, NULL, NULL, &download_rate, NULL) == GF_OK)) {
-                       if (download_rate) {
-                               download_rate *= 8;
-                               if (download_rate<group->min_bitrate) group->min_bitrate = download_rate;
-                               if (download_rate>group->max_bitrate) group->max_bitrate = download_rate;
-
-                               if (download_rate && (download_rate < group->active_bitrate)) {
-                                       u32 set_idx = gf_list_find(group->period->adaptation_sets, group->adaptation_set)+1;
-                                       group->nb_bw_check ++;
-                                       if (group->min_bandwidth_selected) {
-                                               fprintf(stdout, "Downloading from set #%d at rate %d kbps but media bitrate is %d kbps - no lower bitrate available ...\n", set_idx, download_rate/1024, group->active_bitrate/1024);
-                                       } else if (group->nb_bw_check>2) {
-                                               fprintf(stdout, "Downloading from set #%d at rate %d kbps but media bitrate is %d kbps - switching\n", set_idx, download_rate/1024, group->active_bitrate/1024);
-                                               group->force_switch_bandwidth = 1;
-                                               gf_dm_sess_abort(group->segment_dnload);
-                                       } else {
-                                               fprintf(stdout, "Downloading from set #%ds at rate %d kbps but media bitrate is %d kbps\n", set_idx, download_rate/1024, group->active_bitrate/1024);
-                                       }
-                               } else {
-                                       group->nb_bw_check = 0;
-                               }
-                       }
-               }
-       }
-}
-
-/*!
- * Returns true if given mime type is a MPD file
- * \param mime the mime-type to check
- * \return true if mime-type if MPD-OK
- */
-static Bool MPD_is_MPD_mime(const char * mime) {
     u32 i;
-    if (!mime)
-        return 0;
-    for (i = 0 ; MPD_MIME_TYPES[i] ; i++){
-        if ( !stricmp(mime, MPD_MIME_TYPES[i]))
+       char *sExt;
+    if (!plug || !url)
+      return 0;
+    sExt = strrchr(url, '.');
+    GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Can Handle URL request from terminal for %s\n", url));
+    for (i = 0 ; GF_DASH_MPD_MIME_TYPES[i]; i++) {
+        if (gf_term_check_extension(plug, GF_DASH_MPD_MIME_TYPES[i], MPD_MPD_EXT, MPD_MPD_DESC, sExt))
             return 1;
     }
-    return 0;
-}
-
-/*!
- * Returns true if mime type is an M3U8 mime-type
- * \param mime The mime-type to check
- * \return true if mime-type is OK for M3U8
- */
-static Bool MPD_isM3U8_mime(const char * mime) {
-    u32 i;
-    if (!mime)
-        return 0;
-    for (i = 0 ; M3U8_MIME_TYPES[i] ; i++) {
-        if ( !stricmp(mime, M3U8_MIME_TYPES[i]))
+    for (i = 0 ; GF_DASH_M3U8_MIME_TYPES[i]; i++) {
+        if (gf_term_check_extension(plug, GF_DASH_M3U8_MIME_TYPES[i], MPD_M3U8_EXT, MPD_M3U8_DESC, sExt))
             return 1;
     }
-    return 0;
-}
-
-void MPD_NetIO(void *cbk, GF_NETIO_Parameter *param)
-{
-    GF_Err e;
-    GF_MPD_In *mpdin = (GF_MPD_In*) cbk;
-
-    /*handle service message*/
-    gf_term_download_update_stats(mpdin->mpd_dnload);
-    e = param->error;
-}
-
-static GF_Err MPD_UpdatePlaylist(GF_MPD_In *mpdin)
-{
-    GF_Err e;
-    u32 group_idx, rep_idx, i, j;
-    Bool seg_found = 0;
-    GF_DOMParser *mpd_parser;
-    GF_MPD_Period *period, *new_period;
-    const char *local_url;
-    char mime[128];
-    char * purl;
-    Bool is_m3u8 = 0;
-       u32 oldUpdateTime = mpdin->mpd->minimum_update_period;
-    /*reset update time - if any error occurs, we will no longer attempt to update the MPD*/
-    mpdin->mpd->minimum_update_period = 0;
-
-    if (!mpdin->mpd_dnload) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: missing downloader\n"));
-        return GF_BAD_PARAM;
-    }
-
-    local_url = gf_dm_sess_get_cache_name(mpdin->mpd_dnload);
-    if (!local_url) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: wrong cache file %s\n", local_url));
-        return GF_IO_ERR;
-    }
-    gf_delete_file(local_url);
-    purl = gf_strdup(gf_dm_sess_get_resource_name(mpdin->mpd_dnload));
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Updating Playlist %s...\n", purl));
-       /*use non-persistent connection for MPD*/
-    e = MPD_downloadWithRetry(mpdin->service, &(mpdin->mpd_dnload), purl, MPD_NetIO, mpdin, 0, 0, 0);
-    if (e!=GF_OK) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: download problem %s for MPD file\n", gf_error_to_string(e)));
-        gf_free(purl);
-        return gf_dm_sess_last_error(mpdin->mpd_dnload);
-    } else {
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Playlist %s updated with success\n", purl));
-    }
-    strncpy(mime, gf_dm_sess_mime_type(mpdin->mpd_dnload), sizeof(mime));
-    strlwr(mime);
-
-    /*in case the session has been restarted, local_url may have been destroyed - get it back*/
-    local_url = gf_dm_sess_get_cache_name(mpdin->mpd_dnload);
-
-    /* Some servers, for instance http://tv.freebox.fr, serve m3u8 as text/plain */
-    if (MPD_isM3U8_mime(mime) || strstr(purl, ".m3u8")) {
-        gf_m3u8_to_mpd(local_url, purl, NULL, mpdin->reload_count, mpdin->mimeTypeForM3U8Segments, 0, M3U8_TO_MPD_USE_TEMPLATE, &mpdin->getter);
-    } else if (!MPD_is_MPD_mime(mime)) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] mime '%s' should be m3u8 or mpd\n", mime));
-        gf_term_on_connect(mpdin->service, NULL, GF_BAD_PARAM);
-        gf_free(purl);
-        purl = NULL;
-        return GF_BAD_PARAM;
-    }
-
-    gf_free(purl);
-    purl = NULL;
-
-    if (!MPD_CheckRootType(local_url)) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: MPD file type is not correct %s\n", local_url));
-        return GF_NON_COMPLIANT_BITSTREAM;
-    }
-    {
-        u8 signature[sizeof(mpdin->lastMPDSignature)];
-        if (gf_sha1_file( local_url, signature)) {
-            GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] : cannot SHA1 file %s\n", local_url));
-        } else {
-            if (! memcmp( signature, mpdin->lastMPDSignature, sizeof(mpdin->lastMPDSignature))) {
-                GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] MPD file did not change\n"));
-                mpdin->reload_count++;
-                mpdin->mpd->minimum_update_period = oldUpdateTime;
-            } else {
-                GF_MPD *new_mpd;
-                mpdin->reload_count = 0;
-                memccpy(mpdin->lastMPDSignature, signature, sizeof(char), sizeof(mpdin->lastMPDSignature));
-
-                /* It means we have to reparse the file ... */
-                /* parse the MPD */
-                mpd_parser = gf_xml_dom_new();
-                e = gf_xml_dom_parse(mpd_parser, local_url, NULL, NULL);
-                if (e != GF_OK) {
-                    gf_xml_dom_del(mpd_parser);
-                    GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: error in XML parsing %s\n", gf_error_to_string(e)));
-                    return GF_NON_COMPLIANT_BITSTREAM;
-                }
-                new_mpd = gf_mpd_new();
-                e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), new_mpd, purl);
-                gf_xml_dom_del(mpd_parser);
-                if (e) {
-                    GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: error in MPD creation %s\n", gf_error_to_string(e)));
-                    gf_mpd_del(new_mpd);
-                    return GF_NON_COMPLIANT_BITSTREAM;
-                }
-
-                /*TODO - check periods are the same*/
-                period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
-                new_period = gf_list_get(new_mpd->periods, mpdin->active_period_index);
-                if (!new_period) {
-                    GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: missing period\n"));
-                    gf_mpd_del(new_mpd);
-                    return GF_NON_COMPLIANT_BITSTREAM;
-                }
-
-                               if (gf_list_count(period->adaptation_sets) != gf_list_count(new_period->adaptation_sets)) {
-                    GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: missing AdaptationSet\n"));
-                    gf_mpd_del(new_mpd);
-                    return GF_NON_COMPLIANT_BITSTREAM;
-                }
-
-                               for (group_idx=0; group_idx<gf_list_count(mpdin->groups); group_idx++) {
-                                       GF_MPD_AdaptationSet *set, *new_set;
-                                       GF_MPD_Group *group = gf_list_get(mpdin->groups, group_idx);
-                                       if (!group->selected) continue;
-                                       set = group->adaptation_set;
-                                       new_set = gf_list_get(new_period->adaptation_sets, group_idx);
-
-                                       if (gf_list_count(new_set->representations) != gf_list_count(group->adaptation_set->representations)) {
-                                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: missing representation in adaptation set\n"));
-                                               gf_mpd_del(new_mpd);
-                                               return GF_NON_COMPLIANT_BITSTREAM;
-                                       }
-                                       
-                                       /*get all representations in both periods*/
-                                       for (rep_idx = 0; rep_idx <gf_list_count(group->adaptation_set->representations); rep_idx++) {
-                                               GF_List *segments, *new_segments;
-                                               GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, rep_idx);
-                                               GF_MPD_Representation *new_rep = gf_list_get(new_set->representations, rep_idx);
-
-                                               if (rep->segment_base || group->adaptation_set->segment_base || period->segment_base) {
-                                                       if (!new_rep->segment_base && !new_set->segment_base && !new_period->segment_base) {
-                                                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: representation does not use segment base as previous version\n"));
-                                                               gf_mpd_del(new_mpd);
-                                                               return GF_NON_COMPLIANT_BITSTREAM;
-                                                       }
-                                                       /*what else should we check ??*/
-
-                                                       /*OK, this rep is fine*/
-                                               }
-
-                                               else if (rep->segment_template || group->adaptation_set->segment_template || period->segment_template) {
-                                                       if (!new_rep->segment_template && !new_set->segment_template && !new_period->segment_template) {
-                                                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: representation does not use segment template as previous version\n"));
-                                                               gf_mpd_del(new_mpd);
-                                                               return GF_NON_COMPLIANT_BITSTREAM;
-                                                       }
-                                                       /*what else should we check ??*/
-
-                                                       /*OK, this rep is fine*/
-                                               }
-
-                                               else {
-                                                       /*we're using segment list*/
-                                                       assert(rep->segment_list || group->adaptation_set->segment_list || period->segment_list);
-
-                                                       if (!new_rep->segment_list && !new_set->segment_list && !new_period->segment_list) {
-                                                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: representation does not use segment list as previous version\n"));
-                                                               gf_mpd_del(new_mpd);
-                                                               return GF_NON_COMPLIANT_BITSTREAM;
-                                                       }
-                                                       /*what else should we check ??*/
-
-                                                       /*get the segment list*/
-                                                       segments = new_segments = NULL;
-                                                       if (period->segment_list && period->segment_list->segment_URLs) segments = period->segment_list->segment_URLs;
-                                                       if (set->segment_list && set->segment_list->segment_URLs) segments = set->segment_list->segment_URLs;
-                                                       if (rep->segment_list && rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;
-
-                                                       if (new_period->segment_list && new_period->segment_list->segment_URLs) new_segments = new_period->segment_list->segment_URLs;
-                                                       if (new_set->segment_list && new_set->segment_list->segment_URLs) new_segments = new_set->segment_list->segment_URLs;
-                                                       if (new_rep->segment_list && new_rep->segment_list->segment_URLs) new_segments = new_rep->segment_list->segment_URLs;
-
-
-                                                       for (i=0; i<gf_list_count(new_segments); i++) {
-                                                               GF_MPD_SegmentURL *new_seg = gf_list_get(new_segments, i);
-                                                               Bool found = 0;
-                                                               for (j=0; j<gf_list_count(segments); j++) {
-                                                                       GF_MPD_SegmentURL *seg = gf_list_get(segments, j);
-                                                                       if (seg->media && new_seg->media && !strcmp(seg->media, new_seg->media)) {
-                                                                               found=1;
-                                                                               break;
-                                                                       }
-                                                                       if (seg->media_range && new_seg->media_range && (seg->media_range->start_range==new_seg->media_range->start_range) && (seg->media_range->end_range==new_seg->media_range->end_range) ) {
-                                                                               found=1;
-                                                                               break;
-                                                                       }
-                                                               }
-                                                               /*this is a new segment, merge it: we remove from new list and push to old one, before doing a final swap
-                                                               this ensures that indexing in the segment_list is still correct after merging*/
-                                                               if (!found) {
-                                                                       gf_list_rem(new_segments, i);
-                                                                       i--;
-                                                                       gf_list_add(segments, new_seg);
-                                                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Representation #%d: Adding new segment %s\n", rep_idx+1, new_seg->media));
-                                                               }
-                                                       }
-
-                                                       /*what else should we check ?*/
-
-                                                       /*swap segment list content*/
-                                                       gf_list_swap(new_segments, segments);
-
-                                                       /*current representation is the active one in the group - update the number of segments*/
-                                                       if (group->active_rep_index==rep_idx) {
-                                                               group->nb_segments_in_rep = gf_list_count(new_segments);
-                                                       }
-                                               }
-
-                                               /*copy over a few things from former rep*/
-                                               new_rep->disabled = rep->disabled;
-                                               if (!new_rep->mime_type) {
-                                                       new_rep->mime_type = rep->mime_type;
-                                                       rep->mime_type = NULL;
-                                               }
-                                       }
-                                       /*update group/period to new period*/
-                                       j = gf_list_find(group->period->adaptation_sets, group->adaptation_set);
-                                       group->adaptation_set = gf_list_get(new_period->adaptation_sets, j);
-                                       group->period = new_period;
-                               }
-                /*swap representations - we don't need to update download_segment_index as it still points to the right entry in the merged list*/
-                if (mpdin->mpd)
-                    gf_mpd_del(mpdin->mpd);
-                mpdin->mpd = new_mpd;
-                mpdin->last_update_time = gf_sys_clock();
-            }
-        }
-    }
 
-    return GF_OK;
+       return gf_dash_check_mpd_root_type(url);
 }
 
 static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
 {
        u32 i;
-       GF_MPD_Group *group = NULL;
        GF_MPD_In *mpdin = (GF_MPD_In *) ifce->proxy_udta;
     if (!param || !ifce || !ifce->proxy_udta) return GF_BAD_PARAM;
 
+       /*gets byte range of init segment (for local validation)*/
        if (param->command_type==GF_NET_SERVICE_QUERY_INIT_RANGE) {
                param->url_query.next_url = NULL;
                param->url_query.start_range = 0;
@@ -551,23 +104,28 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
                
                mpdin->in_seek = 0;
 
-               for (i=0; i<gf_list_count(mpdin->groups); i++) {
-                       group = gf_list_get(mpdin->groups, i);
-                       if (group->selected && (group->input_module == ifce)) break;
-                       group = NULL;
-               }
-               
-               if (!group) return GF_SERVICE_ERROR;
-               param->url_query.start_range = group->local_url_start_range;
-               param->url_query.end_range = group->local_url_end_range;
-               
-               return GF_OK;
+               for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+                       GF_MPDGroup *group;
+                       if (!gf_dash_is_group_selected(mpdin->dash, i)) continue;
+                       group = gf_dash_get_group_udta(mpdin->dash, i);
+                       if (group->segment_ifce == ifce) {
+                               gf_dash_group_get_segment_init_url(mpdin->dash, i, &param->url_query.start_range, &param->url_query.end_range);
+                               return GF_OK;
+                       }
+               }               
+               return GF_SERVICE_ERROR;
        }
+
+       /*gets URL and byte range of next segment - if needed, adds butstream switching segment info*/
        if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) {
+               Bool group_done;
+               u32 nb_segments_cached;
+               u32 group_idx=0;
+               GF_MPDGroup *group=NULL;
+               const char *src_url;
                Bool discard_first_cache_entry = 1;
         u32 timer = gf_sys_clock();
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Query Next request from terminal\n"));
-        gf_mx_p(mpdin->dl_mutex);
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Service Query Next request from input service %s\n", ifce->module_name));
 
 
                param->url_query.discontinuity_type = 0;
@@ -576,31 +134,35 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
                        param->url_query.discontinuity_type = 2;
                        discard_first_cache_entry = 0;
                }
-
-               for (i=0; i<gf_list_count(mpdin->groups); i++) {
-                       group = gf_list_get(mpdin->groups, i);
-                       if (group->selected && (group->input_module == ifce)) break;
-                       group = NULL;
-               }
+               for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+                       if (!gf_dash_is_group_selected(mpdin->dash, i)) continue;
+                       group = gf_dash_get_group_udta(mpdin->dash, i);
+                       if (group->segment_ifce == ifce) {
+                               group_idx = i;
+                               break;
+                       }
+                       group=NULL;
+               }               
                
                if (!group) {
-               gf_mx_v(mpdin->dl_mutex);
                        return GF_SERVICE_ERROR;
                }
-               group->force_segment_switch = 0;
 
-        /* Wait until no file is scheduled to be downloaded */
-        while (mpdin->mpd_is_running && group->nb_cached_segments<2) {
-            gf_mx_v(mpdin->dl_mutex);
-                       if (group->done) {
-                               if (!mpdin->request_period_switch && (mpdin->active_period_index+1 < gf_list_count(mpdin->mpd->periods))) {
+               while (gf_dash_is_running(mpdin->dash) ) {
+                       group_done=0;
+                       nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done);
+                       if (nb_segments_cached>=2) 
+                               break;
+
+                       if (group_done) {
+                               if (!gf_dash_get_period_switch_status(mpdin->dash) && !gf_dash_in_last_period(mpdin->dash) ) {
                                        GF_NetworkCommand com;
                                        memset(&com, 0, sizeof(GF_NetworkCommand));
                                        com.command_type = GF_NET_BUFFER_QUERY;
-                                       while (mpdin->request_period_switch != 1) {
+                                       while (gf_dash_get_period_switch_status(mpdin->dash) != 1) {
                                                gf_term_on_command(mpdin->service, &com, GF_OK);
                                                if (!com.buffer.occupancy) {
-                                                       mpdin->request_period_switch = 1;
+                                                       gf_dash_request_period_switch(mpdin->dash);
                                                        break;
                                                }
                                                gf_sleep(20);
@@ -609,61 +171,49 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
                                return GF_EOS;
                        }
             gf_sleep(16);
-            gf_mx_p(mpdin->dl_mutex);
         }
-        if (group->nb_cached_segments<2) {
-            GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] No more file in cache, EOS\n"));
-            gf_mx_v(mpdin->dl_mutex);
+       
+               nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done);
+        if (nb_segments_cached < 2) {
+            GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] No more file in cache, EOS\n"));
             return GF_EOS;
         } else {
-            GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer)));
+            GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer)));
         }
 
                if (discard_first_cache_entry) {
-                       if (group->cached[0].cache) {
-                               if (group->urlToDeleteNext) {
-                                       if (!group->local_files && !mpdin->keep_files)
-                                               gf_dm_delete_cached_file_entry_session(group->segment_dnload, group->urlToDeleteNext);
-
-                                       gf_free( group->urlToDeleteNext);
-                                       group->urlToDeleteNext = NULL;
-                               }
-                               assert( group->cached[0].url );
-                               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] deleting cache file %s : %s\n", group->cached[0].url, group->cached[0].cache));
-                               group->urlToDeleteNext = gf_strdup( group->cached[0].url );
-                               gf_free(group->cached[0].cache);
-                               gf_free(group->cached[0].url);
-                               group->cached[0].url = NULL;
-                               group->cached[0].cache = NULL;
-                       }
-                       memmove(&group->cached[0], &group->cached[1], sizeof(segment_cache_entry)*(group->nb_cached_segments-1));
-                       memset(&(group->cached[group->nb_cached_segments-1]), 0, sizeof(segment_cache_entry));
-                       group->nb_cached_segments--;
+                       gf_dash_group_discard_segment(mpdin->dash, group_idx);
                }
 
-        param->url_query.next_url = group->cached[0].cache;
-               param->url_query.start_range = group->cached[0].start_range;
-               param->url_query.end_range = group->cached[0].end_range;
-        gf_mx_v(mpdin->dl_mutex);
+               gf_dash_group_get_next_segment_location(mpdin->dash, group_idx, &param->url_query.next_url, &param->url_query.start_range, &param->url_query.end_range, 
+                                                               &param->url_query.next_url_init_or_switch_segment, &param->url_query.switch_start_range , &param->url_query.switch_end_range,
+                                                               &src_url);
+
         {
             u32 timer2 = gf_sys_clock() - timer ;
             if (timer2 > 1000) {
-                GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] We were stuck waiting for download to end during too much time : %u ms !\n", timer2));
+                GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waiting for download to end took a long time : %u ms\n", timer2));
             }
-                       if (group->cached[0].end_range) {
-                               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Switching segment playback to \n\tURL: %s in %u ms\n\tMedia Range: "LLD"-"LLD"\n\tElements in cache: %u/%u\n", group->cached[0].url, timer2, group->cached[0].start_range, group->cached[0].end_range, group->nb_cached_segments, group->max_cached_segments));
+                       if (param->url_query.end_range) {
+                               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Switching segment playback to %s (Media Range: "LLD"-"LLD")\n", src_url, param->url_query.start_range, param->url_query.end_range));
                        } else {
-                   GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Switching segment playback to \n\tURL: %s in %u ms\n\tCache: %s\n\tElements in cache: %u/%u\n", group->cached[0].url, timer2, group->cached[0].cache, group->nb_cached_segments, group->max_cached_segments));
+                   GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Switching segment playback to %s\n", src_url));
                        }
+            GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] segment start time %g sec\n", gf_dash_group_current_segment_start_time(mpdin->dash, group_idx) ));
+
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waited %d ms - Elements in cache: %u/%u\n\tCache file name %s\n", timer2, gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done), gf_dash_group_get_max_segments_in_cache(mpdin->dash, group_idx), param->url_query.next_url ));
         }
-    } else {
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Client Query request (%d) from terminal\n", param->command_type));
+           return GF_OK;
     }
+
+
     return GF_OK;
 }
 
-static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, GF_MPD_Group *group, const char *mime, const char *init_segment_name)
+/*locates input service (demuxer) based on mime type or segment name*/
+static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, u32 group_index, const char *mime, const char *init_segment_name)
 {
+       GF_InputService *segment_ifce;
        u32 i;
     const char *sPlug;
        if (mime) {
@@ -672,10 +222,14 @@ static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, GF_MPD_Group *group, const
                if (sPlug) sPlug = strrchr(sPlug, '"');
                if (sPlug) {
                        sPlug += 2;
-                       group->input_module = (GF_InputService *) gf_modules_load_interface_by_name(mpdin->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
-                       if (group->input_module) {
-                               group->input_module->proxy_udta = mpdin;
-                               group->input_module->query_proxy = MPD_ClientQuery;
+                       segment_ifce = (GF_InputService *) gf_modules_load_interface_by_name(mpdin->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
+                       if (segment_ifce) {
+                               GF_MPDGroup *group;
+                               GF_SAFEALLOC(group, GF_MPDGroup);
+                               group->segment_ifce = segment_ifce;
+                               group->segment_ifce->proxy_udta = mpdin;
+                               group->segment_ifce->query_proxy = MPD_ClientQuery;
+                               gf_dash_set_group_udta(mpdin->dash, group_index, group);
                                return GF_OK;
                        }
                }
@@ -686,1216 +240,51 @@ static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, GF_MPD_Group *group, const
                        if (!ifce) continue;
                        
                        if (ifce->CanHandleURL && ifce->CanHandleURL(ifce, init_segment_name)) {
-                               group->input_module = ifce;
-                               group->input_module->proxy_udta = mpdin;
-                               group->input_module->query_proxy = MPD_ClientQuery;
-                               return GF_OK;
-                       }
-                       gf_modules_close_interface((GF_BaseInterface *) ifce);
-               }
-       }
-
-       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error locating plugin for segment - mime type %s - name %s\n", mime, init_segment_name));
-    return GF_CODEC_NOT_FOUND;
-}
-
-/*!
- * Download a file with possible retry if GF_IP_CONNECTION_FAILURE|GF_IP_NETWORK_FAILURE
- * (I discovered that with my WIFI connection, I had many issues with BFM-TV downloads)
- * Similar to gf_term_download_new() and gf_dm_sess_process().
- * Parameters are identical to the ones of gf_term_download_new.
- * \see gf_term_download_new()
- */
-GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession **sess, const char *url, gf_dm_user_io user_io,  void *usr_cbk, u64 start_range, u64 end_range, Bool persistent)
-{
-       Bool had_sess = 0;
-    GF_Err e;
-
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Downloading %s...\n", url));
-
-       if (! *sess) {
-               u32 flags = GF_NETIO_SESSION_NOT_THREADED;
-               if (persistent) flags |= GF_NETIO_SESSION_PERSISTENT; 
-               *sess = gf_term_download_new(service, url, flags, user_io, usr_cbk);
-               if (!(*sess)){
-                       assert(0);
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot try to download %s... OUT of memory ?\n", url));
-                       return GF_OUT_OF_MEM;
-               }
-       } else {
-               had_sess = 1;
-               e = gf_dm_sess_setup_from_url(*sess, url);
-               if (e) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot resetup session for url %s: %s\n", url, gf_error_to_string(e) ));
-                       return e;
-               }
-
-       }
-       if (end_range) {
-               e = gf_dm_sess_set_range(*sess, start_range, end_range);
-               if (e) {
-                       if (had_sess) {
-                               gf_term_download_del(*sess);
-                               *sess = NULL;
-                               return MPD_downloadWithRetry(service, sess, url, user_io, usr_cbk, start_range, end_range, persistent);
-                       }
-
-
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot setup byte-range download for %s: %s\n", url, gf_error_to_string(e) ));
-                       return e;
-               }
-       }
-    e = gf_dm_sess_process(*sess);
-    switch (e) {
-    case GF_IP_CONNECTION_FAILURE:
-    case GF_IP_NETWORK_FAILURE:
-    {
-        gf_term_download_del(*sess);
-        GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE,
-               ("[MPD_IN] failed to download, retrying once with %s...\n", url));
-        *sess = gf_term_download_new(service, url, GF_NETIO_SESSION_NOT_THREADED, user_io, usr_cbk);
-        if (!(*sess)){
-           GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot retry to download %s... OUT of memory ?\n", url));
-            return GF_OUT_OF_MEM;
-        }
-        e = gf_dm_sess_process(*sess);
-        if (e != GF_OK) {
-            GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE,
-                   ("[MPD_IN] two consecutive failures, aborting the download %s.\n", url));
-        }
-        return e;
-    }
-    case GF_OK:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] OK, Download %s complete\n", url));
-        return e;
-    default:
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] FAILED to download %s = %s...\n", url, gf_error_to_string(e)));
-        return e;
-    }
-}
-
-static void MPD_GetTimelineDuration(GF_MPD_SegmentTimeline *timeline, u32 *nb_segments, Double *seg_duration)
-{
-       u32 i, count;
-
-       *nb_segments = 0;
-       *seg_duration = 0;
-       count = gf_list_count(timeline->entries);
-       for (i=0; i<count; i++) {
-               GF_MPD_SegmentTimelineEntry *ent = gf_list_get(timeline->entries, i);
-               *nb_segments += 1 + ent->repeat_count;
-               if (*seg_duration < ent->duration) *seg_duration = ent->duration;
-       }
-}
-
-static void MPD_GetSegmentDuration(GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set, GF_MPD_Period *period, GF_MPD *mpd, u32 *nb_segments, Double *seg_duration)
-{
-       Double mediaDuration;
-       u32 timescale;
-       u64 duration;
-       GF_MPD_SegmentTimeline *timeline = NULL;
-       *nb_segments = timescale = 0;
-       duration = 0;
-       
-       /*single segment*/
-       if (rep->segment_base || set->segment_base || period->segment_base) {
-               return;
-       }
-       if (rep->segment_list || set->segment_list || period->segment_list) {
-               GF_List *segments = NULL;
-               if (period->segment_list) {
-                       if (period->segment_list->duration) duration = period->segment_list->duration;
-                       if (period->segment_list->timescale) timescale = period->segment_list->timescale;
-                       if (period->segment_list->segment_URLs) segments = period->segment_list->segment_URLs;
-                       if (period->segment_list->segment_timeline) timeline = period->segment_list->segment_timeline;
-               }
-               if (set->segment_list) {
-                       if (set->segment_list->duration) duration = set->segment_list->duration;
-                       if (set->segment_list->timescale) timescale = set->segment_list->timescale;
-                       if (set->segment_list->segment_URLs) segments = set->segment_list->segment_URLs;
-                       if (set->segment_list->segment_timeline) timeline = set->segment_list->segment_timeline;
-               }
-               if (rep->segment_list) {
-                       if (rep->segment_list->duration) duration = rep->segment_list->duration;
-                       if (rep->segment_list->timescale) timescale = rep->segment_list->timescale;
-                       if (rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;
-                       if (rep->segment_list->segment_timeline) timeline = rep->segment_list->segment_timeline;
-               }
-               if (! timescale) timescale=1;
-
-               if (timeline) {
-                       MPD_GetTimelineDuration(timeline, nb_segments, seg_duration);
-                       *seg_duration /= timescale;
-               } else {
-                       if (segments) 
-                               *nb_segments = gf_list_count(segments);
-                       *seg_duration = (Double) duration;
-                       *seg_duration /= timescale;
-               }
-               return;
-       }
-
-       if (period->segment_template) {
-               if (period->segment_template->duration) duration = period->segment_template->duration;
-               if (period->segment_template->timescale) timescale = period->segment_template->timescale;
-               if (period->segment_template->segment_timeline) timeline = period->segment_template->segment_timeline;
-       }
-       if (set->segment_template) {
-               if (set->segment_template->duration) duration = set->segment_template->duration;
-               if (set->segment_template->timescale) timescale = set->segment_template->timescale;
-               if (set->segment_template->segment_timeline) timeline = set->segment_template->segment_timeline;
-       }
-       if (rep->segment_template) {
-               if (rep->segment_template->duration) duration = rep->segment_template->duration;
-               if (rep->segment_template->timescale) timescale = rep->segment_template->timescale;
-               if (rep->segment_template->segment_timeline) timeline = rep->segment_template->segment_timeline;
-       }
-       if (!timescale) timescale=1;
-
-       if (timeline) {
-               MPD_GetTimelineDuration(timeline, nb_segments, seg_duration);
-               *seg_duration /= timescale;
-       } else {
-               *seg_duration = (Double) duration;
-               *seg_duration /= timescale;
-               mediaDuration = period->duration;
-               if (!mediaDuration) mediaDuration = mpd->media_presentation_duration;
-               if (mediaDuration && duration) {
-                       Double nb_seg = (Double) mediaDuration;
-                       /*duration is given in ms*/
-                       nb_seg /= 1000;
-                       nb_seg *= timescale;
-                       nb_seg /= duration;
-                       *nb_segments = (u32) ceil(nb_seg);
-               }
-       }
-}
-
-
-static void MPD_SetGroupRepresentation(GF_MPD_Group *group, GF_MPD_Representation *rep)
-{
-       u64 duration = 0;
-       u64 mediaDuration = 0;
-#ifndef GPAC_DISABLE_LOG
-       u32 width=0, height=0, samplerate=0;
-       GF_MPD_Fractional *framerate=NULL;
-#endif
-       u32 k, timescale = 1;
-       GF_MPD_AdaptationSet *set;
-       GF_MPD_Period *period;
-       u32 i = gf_list_find(group->adaptation_set->representations, rep);
-       assert((s32) i >= 0);
-
-       group->active_rep_index = i;
-       group->active_bitrate = rep->bandwidth;
-       group->nb_segments_in_rep = 1;
-
-       group->min_bandwidth_selected = 1;
-       for (k=0; k<gf_list_count(group->adaptation_set->representations); k++) {
-               GF_MPD_Representation *arep = gf_list_get(group->adaptation_set->representations, k);
-               if (group->active_bitrate > arep->bandwidth) {
-                       group->min_bandwidth_selected = 0;
-                       break;
-               }
-       }
-
-       set = group->adaptation_set;
-       period = group->period;
-
-#ifndef GPAC_DISABLE_LOG
-
-#define GET_REP_ATTR(_a)       _a = rep->_a; if (!_a) _a = set->_a;
-
-       GET_REP_ATTR(width);
-       GET_REP_ATTR(height);
-       GET_REP_ATTR(samplerate);
-       GET_REP_ATTR(framerate);
-
-       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPDIn] Switched to representation bandwidth %d kbps\n", rep->bandwidth/1024));
-       if (group->max_bitrate) GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tmax download bandwidth: %d kbps\n", group->max_bitrate/1024));
-       if (width&&height) {
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tWidth %d Height %d", width, height));
-               if (framerate) GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("framerate %d/%d", framerate->num, framerate->den));
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\n"));
-       } else if (samplerate) {
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tsamplerate %d\n", samplerate));
-       }
-#endif
-
-
-       MPD_GetSegmentDuration(rep, set, period, group->mpd_in->mpd, &group->nb_segments_in_rep, &group->segment_duration);
-}
-
-static void MPD_SwitchGroupRepresentation(GF_MPD_In *mpd, GF_MPD_Group *group)
-{
-       u32 i, bandwidth, min_bandwidth;
-       GF_MPD_Representation *rep_sel = NULL;
-       GF_MPD_Representation *min_rep_sel = NULL;
-       Bool min_bandwidth_selected = 0;
-       bandwidth = 0;
-       min_bandwidth = (u32) -1;
-
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPDIn] Checking representations between %d and %d kbps\n", group->min_bitrate/1024, group->max_bitrate/1024));
-
-       if (group->force_representation_idx_plus_one) {
-               rep_sel = gf_list_get(group->adaptation_set->representations, group->force_representation_idx_plus_one - 1);
-               group->force_representation_idx_plus_one = 0;
-       } 
-
-       if (!rep_sel) {
-               for (i=0; i<gf_list_count(group->adaptation_set->representations); i++) {
-                       GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, i);
-                       if (rep->disabled) continue;
-                       if ((rep->bandwidth > bandwidth) && (rep->bandwidth < group->max_bitrate )) {
-                               rep_sel = rep;
-                               bandwidth = rep->bandwidth;
-                       }
-                       if (rep->bandwidth < min_bandwidth) {
-                               min_rep_sel = rep;
-                               min_bandwidth = rep->bandwidth;
-                       }
-               }
-       }
-
-       if (!rep_sel) {
-               rep_sel = min_rep_sel;
-               min_bandwidth_selected = 1;
-       }
-       assert(rep_sel);
-       i = gf_list_find(group->adaptation_set->representations, rep_sel);
-
-       assert((s32) i >= 0);
-
-       group->force_switch_bandwidth = 0;
-       group->max_bitrate = 0;
-       group->min_bitrate = (u32) -1;
-
-       if (i != group->active_rep_index) {
-               if (min_bandwidth_selected) {
-                       GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("[MPDIn] No representation found with bandwidth below %d kbps - using representation @ %d kbps\n", group->max_bitrate/1024, rep_sel->bandwidth/1024));
-               }
-               MPD_SetGroupRepresentation(group, rep_sel);
-       }
-}
-
-
-static void MPD_ResolveDuration(GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set, GF_MPD_Period *period, u64 *out_duration, u32 *out_timescale)
-{
-       u32 timescale = 0;
-       GF_MPD_SegmentTimeline *segment_timeline;
-       GF_MPD_MultipleSegmentBase *mbase_rep, *mbase_set, *mbase_period;
-       /*single media segment - duration is not known unless indicated in period*/
-       if (rep->segment_base || set->segment_base || period->segment_base) {
-               *out_duration = period ? period->duration : 0;
-               *out_timescale = 1000;
-               return;
-       }
-       /*we have a segment template list or template*/
-       mbase_rep = rep->segment_list ? (GF_MPD_MultipleSegmentBase *) rep->segment_list : (GF_MPD_MultipleSegmentBase *) rep->segment_template;
-       mbase_set = set->segment_list ? (GF_MPD_MultipleSegmentBase *)set->segment_list : (GF_MPD_MultipleSegmentBase *)set->segment_template;
-       mbase_period = period->segment_list ? (GF_MPD_MultipleSegmentBase *)period->segment_list : (GF_MPD_MultipleSegmentBase *)period->segment_template;
-
-       segment_timeline = NULL;
-       if (mbase_period) segment_timeline =  mbase_period->segment_timeline;
-       if (mbase_set) segment_timeline =  mbase_set->segment_timeline;
-       if (mbase_rep) segment_timeline =  mbase_rep->segment_timeline;
-
-       timescale = mbase_rep ? mbase_rep->timescale : 0;
-       if (!timescale && mbase_set && mbase_set->timescale) timescale = mbase_set->timescale;
-       if (!timescale && mbase_period && mbase_period->timescale) timescale  = mbase_period->timescale;
-       if (!timescale) timescale = 1;
-       *out_timescale = timescale;
-
-       if (mbase_rep && mbase_rep->duration) *out_duration = mbase_rep->duration;
-       else if (mbase_set && mbase_set->duration) *out_duration = mbase_set->duration;
-       else if (mbase_period && mbase_period->duration) *out_duration = mbase_period->duration;
-
-}
-
-typedef enum
-{
-       GF_MPD_RESOLVE_URL_MEDIA,
-       GF_MPD_RESOLVE_URL_INIT,
-       GF_MPD_RESOLVE_URL_INDEX,
-} GF_MPDURLResolveType;
-
-
-GF_Err MPD_ResolveURL(GF_MPD *mpd, GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set, GF_MPD_Period *period, char *mpd_url, GF_MPDURLResolveType resolve_type, u32 item_index, char **out_url, u64 *out_range_start, u64 *out_range_end, u64 *segment_duration)
-{
-       GF_MPD_BaseURL *url_child;
-       GF_MPD_SegmentTimeline *timeline = NULL;
-       u32 start_number = 1;
-       u32 timescale;
-       char *url;
-       char *url_to_solve, *solved_template, *first_sep, *media_url;
-       char *init_template, *index_template;
-
-       *out_range_start = *out_range_end = 0;
-       *out_url = NULL;
-
-       /*resolve base URLs from document base (download location) to representation (media)*/
-       url = gf_strdup(mpd_url);
-       url_child = gf_list_get(mpd->base_URLs, 0);
-       if (url_child) {
-               char *t_url = gf_url_concatenate(url, url_child->URL);
-               gf_free(url);
-               url = t_url;
-       }
-
-       url_child = gf_list_get(period->base_URLs, 0);
-       if (url_child) {
-               char *t_url = gf_url_concatenate(url, url_child->URL);
-               gf_free(url);
-               url = t_url;
-       }
-
-       url_child = gf_list_get(set->base_URLs, 0);
-       if (url_child) {
-               char *t_url = gf_url_concatenate(url, url_child->URL);
-               gf_free(url);
-               url = t_url;
-       }
-
-       url_child = gf_list_get(rep->base_URLs, 0);
-       if (url_child) {
-               char *t_url = gf_url_concatenate(url, url_child->URL);
-               gf_free(url);
-               url = t_url;
-       }
-
-       MPD_ResolveDuration(rep, set, period, segment_duration, &timescale);
-       *segment_duration = (u32) ((Double) (*segment_duration) * 1000.0 / timescale);
-
-       /*single URL*/
-       if (rep->segment_base || set->segment_base || period->segment_base) {
-               GF_MPD_URL *res_url;
-               if (item_index>0) return GF_EOS;
-               switch (resolve_type) {
-               case GF_MPD_RESOLVE_URL_MEDIA:
-                       if (!url) return GF_NON_COMPLIANT_BITSTREAM;
-                       *out_url = url;
-                       return GF_OK;
-               case GF_MPD_RESOLVE_URL_INIT:
-               case GF_MPD_RESOLVE_URL_INDEX:
-                       res_url = NULL;
-                       if (resolve_type == GF_MPD_RESOLVE_URL_INDEX) {
-                               if (period->segment_base) res_url = period->segment_base->representation_index;
-                               if (set->segment_base) res_url = set->segment_base->representation_index;
-                               if (rep->segment_base) res_url = rep->segment_base->representation_index;
-                       } else {
-                               if (period->segment_base) res_url = period->segment_base->initialization_segment;
-                               if (set->segment_base) res_url = set->segment_base->initialization_segment;
-                               if (rep->segment_base) res_url = rep->segment_base->initialization_segment;
-                       }
-                       /*no initialization segment / index*/
-                       if (!res_url) {
-                               gf_free(url);
+                               GF_MPDGroup *group;
+                               GF_SAFEALLOC(group, GF_MPDGroup);
+                               group->segment_ifce = ifce;
+                               group->segment_ifce->proxy_udta = mpdin;
+                               group->segment_ifce->query_proxy = MPD_ClientQuery;
+                               gf_dash_set_group_udta(mpdin->dash, group_index, group);
                                return GF_OK;
                        }
-                       if (res_url->sourceURL) {
-                               *out_url = gf_url_concatenate(url, res_url->sourceURL);
-                               gf_free(url);
-                       } else {
-                               *out_url = url;
-                       }
-                       if (res_url->byte_range) {
-                               *out_range_start = res_url->byte_range->start_range;
-                               *out_range_end = res_url->byte_range->end_range;
-                       }
-                       return GF_OK;
-               default:
-                       break;
-               }
-               gf_free(url);
-               return GF_BAD_PARAM;
-       }
-
-       /*segmentList*/
-       if (rep->segment_list || set->segment_list || period->segment_list) {   
-               GF_MPD_URL *init_url, *index_url;
-               GF_MPD_SegmentURL *segment;
-               GF_List *segments = NULL;
-               u32 segment_count;
-
-               init_url = index_url = NULL;
-
-               /*apply inheritance of attributes, lowest level having preceedence*/
-               if (period->segment_list) {
-                       if (period->segment_list->initialization_segment) init_url = period->segment_list->initialization_segment;
-                       if (period->segment_list->representation_index) index_url = period->segment_list->representation_index;
-                       if (period->segment_list->segment_URLs) segments = period->segment_list->segment_URLs;
-                       if (period->segment_list->start_number != (u32) -1) start_number = period->segment_list->start_number;
-                       if (period->segment_list->segment_timeline) timeline = period->segment_list->segment_timeline;
-               }
-               if (set->segment_list) {
-                       if (set->segment_list->initialization_segment) init_url = set->segment_list->initialization_segment;
-                       if (set->segment_list->representation_index) index_url = set->segment_list->representation_index;
-                       if (set->segment_list->segment_URLs) segments = set->segment_list->segment_URLs;
-                       if (set->segment_list->start_number != (u32) -1) start_number = set->segment_list->start_number;
-                       if (set->segment_list->segment_timeline) timeline = set->segment_list->segment_timeline;
-               }
-               if (rep->segment_list) {
-                       if (rep->segment_list->initialization_segment) init_url = rep->segment_list->initialization_segment;
-                       if (rep->segment_list->representation_index) index_url = rep->segment_list->representation_index;
-                       if (rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;
-                       if (rep->segment_list->start_number != (u32) -1) start_number = rep->segment_list->start_number;
-                       if (rep->segment_list->segment_timeline) timeline = rep->segment_list->segment_timeline;
-               }
-
-
-               segment_count = gf_list_count(segments);
-
-               switch (resolve_type) {
-               case GF_MPD_RESOLVE_URL_INIT:
-
-                       if (init_url) {
-                               if (init_url->sourceURL) {
-                                       *out_url = gf_url_concatenate(url, init_url->sourceURL);
-                                       gf_free(url);
-                               } else {
-                                       *out_url = url;
-                               }
-                               if (init_url->byte_range) {
-                                       *out_range_start = init_url->byte_range->start_range;
-                                       *out_range_end = init_url->byte_range->end_range;
-                               }
-                       } else {
-                               gf_free(url);
-                       }
-                       return GF_OK;
-               case GF_MPD_RESOLVE_URL_MEDIA:
-                       if (!url) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Media URL is not set in segment list\n"));
-                               return GF_SERVICE_ERROR;
-                       }
-                       if (item_index >= segment_count) {
-                               gf_free(url);
-                               return GF_EOS;
-                       }
-                       *out_url = url;
-                       segment = gf_list_get(segments, item_index);
-                       if (segment->media) {
-                               *out_url = gf_url_concatenate(url, segment->media);
-                               gf_free(url);
-                       }
-                       if (segment->media_range) {
-                               *out_range_start = segment->media_range->start_range;
-                               *out_range_end = segment->media_range->end_range;
-                       }
-                       return GF_OK;
-               case GF_MPD_RESOLVE_URL_INDEX:
-                       if (item_index >= segment_count) {
-                               gf_free(url);
-                               return GF_EOS;
-                       }
-                       *out_url = url;
-                       segment = gf_list_get(segments, item_index);
-                       if (segment->index) {
-                               *out_url = gf_url_concatenate(url, segment->index);
-                               gf_free(url);
-                       }
-                       if (segment->index_range) {
-                               *out_range_start = segment->index_range->start_range;
-                               *out_range_end = segment->index_range->end_range;
-                       }
-                       return GF_OK;
-               default:
-                       break;
-               }
-               gf_free(url);
-               return GF_BAD_PARAM;
-       }
-
-       /*segmentTemplate*/
-       media_url = init_template = index_template = NULL;
-
-       /*apply inheritance of attributes, lowest level having preceedence*/
-       if (period->segment_template) {
-               if (period->segment_template->initialization) init_template = period->segment_template->initialization;
-               if (period->segment_template->index) index_template = period->segment_template->index;
-               if (period->segment_template->media) media_url = period->segment_template->media;
-               if (period->segment_template->start_number != (u32) -1) start_number = period->segment_template->start_number;
-               if (period->segment_template->segment_timeline) timeline = period->segment_template->segment_timeline;
-       }
-       if (set->segment_template) {
-               if (set->segment_template->initialization) init_template = set->segment_template->initialization;
-               if (set->segment_template->index) index_template = set->segment_template->index;
-               if (set->segment_template->media) media_url = set->segment_template->media;
-               if (set->segment_template->start_number != (u32) -1) start_number = set->segment_template->start_number;
-               if (set->segment_template->segment_timeline) timeline = set->segment_template->segment_timeline;
-       }
-       if (rep->segment_template) {
-               if (rep->segment_template->initialization) init_template = rep->segment_template->initialization;
-               if (rep->segment_template->index) index_template = rep->segment_template->index;
-               if (rep->segment_template->media) media_url = rep->segment_template->media;
-               if (rep->segment_template->start_number != (u32) -1) start_number = rep->segment_template->start_number;
-               if (rep->segment_template->segment_timeline) timeline = rep->segment_template->segment_timeline;
-       }
-       if (!media_url) {
-               GF_MPD_BaseURL *base = gf_list_get(rep->base_URLs, 0);
-               media_url = base->URL;
-       }
-       url_to_solve = NULL;
-       switch (resolve_type) {
-       case GF_MPD_RESOLVE_URL_INIT:
-               url_to_solve = init_template;
-               break;
-       case GF_MPD_RESOLVE_URL_MEDIA:
-               url_to_solve = media_url;
-               break;
-       case GF_MPD_RESOLVE_URL_INDEX:
-               url_to_solve = index_template;
-               break;
-       default:
-               gf_free(url);
-               return GF_BAD_PARAM;
-       }
-       if (!url_to_solve) {
-               gf_free(url);
-               return GF_OK;
-       }
-       /*let's solve the template*/
-       solved_template = gf_malloc(sizeof(char)*strlen(url_to_solve)*2);
-       solved_template[0] = 0;
-       strcpy(solved_template, url_to_solve);
-       first_sep = strchr(solved_template, '$');
-       if (first_sep) first_sep[0] = 0;
-
-       first_sep = strchr(url_to_solve, '$');
-       while (first_sep) {
-               char szFormat[100];
-               char *format_tag;
-               char *second_sep = strchr(first_sep+1, '$');
-               if (!second_sep) {
-                       gf_free(url);
-                       gf_free(solved_template);
-                       return GF_NON_COMPLIANT_BITSTREAM;
-               }
-               second_sep[0] = 0;
-               format_tag = strchr(first_sep+1, '%');
-               if (format_tag) format_tag[0] = 0;
-               /* identifier is $$ -> replace by $*/
-               if (!strlen(first_sep+1)) {
-                       strcat(solved_template, "$");
-               }
-               else if (!strcmp(first_sep+1, "RepresentationID")) {
-                       strcat(solved_template, rep->id);
-               }
-               else if (!strcmp(first_sep+1, "Number")) {
-                       if (format_tag) {
-                               char szPrintFormat[20];
-                               strcpy(szPrintFormat, "%");
-                               strcat(szPrintFormat, format_tag+1);
-                               strcat(szPrintFormat, "d");
-                               sprintf(szFormat, szPrintFormat, start_number + item_index);
-                       } else {
-                               sprintf(szFormat, "%d", start_number + item_index);
-                       }
-                       strcat(solved_template, szFormat);
-               }
-               else if (!strcmp(first_sep+1, "Bandwidth")) {
-                       if (format_tag) {
-                               char szPrintFormat[20];
-                               strcpy(szPrintFormat, "%");
-                               strcat(szPrintFormat, format_tag+1);
-                               strcat(szPrintFormat, "d");
-                               sprintf(szFormat, format_tag+1, rep->bandwidth);
-                       } else {
-                               sprintf(szFormat, "%d", rep->bandwidth);
-                       }
-                       strcat(solved_template, szFormat);
-               }
-               else if (!strcmp(first_sep+1, "Time")) {
-                       if (timeline) {
-                               /*uses segment timeline*/
-                               u32 k, nb_seg, cur_idx, nb_repeat;
-                               u64 time, start_time;
-                               nb_seg = gf_list_count(timeline->entries);
-                               cur_idx = 0;
-                               start_time=0;
-                               for (k=0; k<nb_seg; k++) {
-                                       GF_MPD_SegmentTimelineEntry *ent = gf_list_get(timeline->entries, k);
-                                       if (item_index>cur_idx+ent->repeat_count) {
-                                               cur_idx += 1 + ent->repeat_count;
-                                               start_time += ent->duration * (1 + ent->repeat_count);
-                                               continue;
-                                       }
-                                       *segment_duration = ent->duration;
-                                       *segment_duration = (u32) ((Double) (*segment_duration) * 1000.0 / timescale);
-                                       nb_repeat = item_index - cur_idx;
-                                       time = ent->start_time ? ent->start_time : start_time;
-                                       time += nb_repeat * ent->duration;
-                                       sprintf(szFormat, ""LLD"", time);
-                                       strcat(solved_template, szFormat);
-                                       break;
-                               }
-                       }
-               }
-               if (format_tag) format_tag[0] = '%';
-               second_sep[0] = '$';
-               /*look for next keyword - copy over remaining text if any*/
-               first_sep = strchr(second_sep+1, '$');
-               if (first_sep) first_sep[0] = 0;
-               if (strlen(second_sep+1)) 
-                       strcat(solved_template, second_sep+1);
-               if (first_sep) first_sep[0] = '$';
-       }
-       *out_url = gf_url_concatenate(url, solved_template);
-       gf_free(url);
-       gf_free(solved_template);
-       return GF_OK;
-}
-
-static GF_Err MPD_DownloadInitSegment(GF_MPD_In *mpdin, GF_MPD_Group *group)
-{
-    GF_Err e;
-    char *base_init_url;
-    GF_MPD_Representation *rep;
-       u64 start_range, end_range;
-    /* This variable is 0 if there is a initURL, the index of first segment downloaded otherwise */
-    u32 nb_segment_read = 0;
-    if (!mpdin || !group)
-        return GF_BAD_PARAM;
-    gf_mx_p(mpdin->dl_mutex);
-    
-       assert( group->adaptation_set && group->adaptation_set->representations );
-    rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);
-    if (!rep) {
-        gf_mx_v(mpdin->dl_mutex);
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Unable to find any representation, aborting.\n"));
-        return GF_IO_ERR;
-    }
-       start_range = end_range = 0;
-       
-       e = MPD_ResolveURL(mpdin->mpd, rep, group->adaptation_set, group->period, mpdin->url, GF_MPD_RESOLVE_URL_INIT, 0, &base_init_url, &start_range, &end_range, &group->current_downloaded_segment_duration);
-       if (e) {
-        gf_mx_v(mpdin->dl_mutex);
-               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Unable to resolve initialization URL: %s\n", gf_error_to_string(e) ));
-        return e;
-       }
-
-       /*no error and no init segment, go for media segment*/
-       if (!base_init_url) {
-               e = MPD_ResolveURL(mpdin->mpd, rep, group->adaptation_set, group->period, mpdin->url, GF_MPD_RESOLVE_URL_MEDIA, group->download_segment_index, &base_init_url, &start_range, &end_range, &group->current_downloaded_segment_duration);
-               if (e) {
-                       gf_mx_v(mpdin->dl_mutex);
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Unable to resolve media URL: %s\n", gf_error_to_string(e) ));
-                       return e;
-               }
-               nb_segment_read = 1;
-       }
-
-       if (!strstr(base_init_url, "://") || !strnicmp(base_init_url, "file://", 7)) {
-        assert(!group->nb_cached_segments);
-        group->cached[0].cache = gf_strdup(base_init_url);
-        group->cached[0].url = gf_strdup(base_init_url);
-        group->nb_cached_segments = 1;
-               /*do not erase local files*/
-               group->local_files = 1;
-               group->download_segment_index += nb_segment_read;
-        group->segment_local_url = group->cached[0].cache;
-               group->local_url_start_range = start_range;
-               group->local_url_end_range = end_range;
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Setup initialization segment %s \n", group->segment_local_url));
-               if (!group->input_module) {
-                       const char *mime_type = MPD_GetMimeType(NULL, rep, group->adaptation_set);
-                       e = MPD_LoadMediaService(mpdin, group, mime_type, group->segment_local_url);
-               }
-        gf_mx_v(mpdin->dl_mutex);
-        gf_free(base_init_url);
-               return GF_OK;
-       }
-
-       group->max_bitrate = 0;
-       group->min_bitrate = (u32)-1;
-       /*use persistent connection for segment downloads*/
-    e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), base_init_url, MPD_NetIO_Segment, group, start_range, end_range, 1);
-
-       if ((e==GF_OK) && group->force_switch_bandwidth && !mpdin->auto_switch_count) {
-               MPD_SwitchGroupRepresentation(mpdin, group);
-        gf_mx_v(mpdin->dl_mutex);
-               return MPD_DownloadInitSegment(mpdin, group);
-       }
-
-
-    if (e == GF_URL_ERROR && !base_init_url) { /* We have a 404 and started with segments */
-        /* It is possible that the first segment has been deleted while we made the first request...
-         * so we try with the next segment on some M3U8 servers */
-
-               gf_free(base_init_url);
-
-               e = MPD_ResolveURL(mpdin->mpd, rep, group->adaptation_set, group->period, mpdin->url, GF_MPD_RESOLVE_URL_MEDIA, group->download_segment_index + 1, &base_init_url, &start_range, &end_range, &group->current_downloaded_segment_duration);
-               if (!e) {
-            gf_mx_v(mpdin->dl_mutex);
-            return e;
-        }
-        GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("Download of first segment failed... retrying with second one : %s\n", base_init_url));
-        nb_segment_read = 2;
-               /*use persistent connection for segment downloads*/
-        e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), base_init_url, MPD_NetIO_Segment, group, 0, 0, 1);
-    } /* end of 404 */
-
-    if (e!= GF_OK && !group->segment_must_be_streamed) {
-        mpdin->mpd_stop_request = 1;
-        gf_mx_v(mpdin->dl_mutex);
-        gf_free(base_init_url);
-        return e;
-    } else {
-        char mime[128];
-               const char *mime_type;
-        u32 count = group->nb_segments_in_rep + 1;
-        if (count < group->max_cached_segments) {
-            if (count < 1) {
-                GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] 0 representations, aborting\n"));
-                gf_free(base_init_url);
-                       gf_mx_v(mpdin->dl_mutex);
-                return GF_BAD_PARAM;
-            }
-            GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Resizing to %u max_cached_segments elements instead of %u.\n", count, group->max_cached_segments));
-            /* OK, we have a problem, it may ends download */
-            group->max_cached_segments = count;
-        }
-        e = gf_dm_sess_process(group->segment_dnload);
-        /* Mime-Type check */
-               strncpy(mime, gf_dm_sess_mime_type(group->segment_dnload), sizeof(mime));
-        strlwr(mime);
-        if (mime && group->input_module == NULL) {
-            GF_Err e;
-            GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Searching an input plugin for mime type : %s...\n", mime));
-            gf_free( mpdin->mimeTypeForM3U8Segments);
-            mpdin->mimeTypeForM3U8Segments = gf_strdup( mime );
-                       if (rep->mime_type) gf_free( rep->mime_type);
-            rep->mime_type = gf_strdup( mime );
-            e = MPD_LoadMediaService(mpdin, group, mime, base_init_url);
-                       if (e != GF_OK) {
-                       gf_mx_v(mpdin->dl_mutex);
-                return e;
-                       }
-        }
-               mime_type = MPD_GetMimeType(NULL, rep, group->adaptation_set);
-        if (!mime || (stricmp(mime, mime_type))) {
-                       Bool valid = 0;
-                       char *stype1, *stype2;
-                       stype1 = strchr(mime_type, '/');
-                       stype2 = mime ? strchr(mime, '/') : NULL;
-                       if (stype1 && stype2 && !strcmp(stype1, stype2)) valid = 1;
-
-                       if (!valid && 0) {
-                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Mime '%s' is not correct for '%s', it should be '%s'\n", mime, base_init_url, mime_type));
-                               mpdin->mpd_stop_request = 0;
-                               gf_mx_v(mpdin->dl_mutex);
-                               gf_free(base_init_url);
-                               base_init_url = NULL;
-                               return GF_BAD_PARAM;
-                       }
-        }
-        if (group->segment_must_be_streamed ) {
-            group->segment_local_url = gf_dm_sess_get_resource_name(group->segment_dnload);
-            e = GF_OK;
-        } else {
-            group->segment_local_url = gf_dm_sess_get_cache_name(group->segment_dnload);
-        }
-
-        if ((e!=GF_OK) || !group->segment_local_url) {
-            GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error with initialization segment: download result:%s, cache file:%s\n", gf_error_to_string(e), group->segment_local_url));
-            mpdin->mpd_stop_request = 1;
-            gf_mx_v(mpdin->dl_mutex);
-            gf_free(base_init_url);
-            return GF_BAD_PARAM;
-        } else {
-            assert(!group->nb_cached_segments);
-            group->cached[0].cache = gf_strdup(group->segment_local_url);
-            group->cached[0].url = gf_strdup(gf_dm_sess_get_resource_name(group->segment_dnload));
-            group->nb_cached_segments = 1;
-            group->download_segment_index += nb_segment_read;
-            GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Adding initialization segment %s to cache: %s\n", group->segment_local_url, group->cached[0].url ));
-            gf_mx_v(mpdin->dl_mutex);
-            gf_free(base_init_url);
-            return GF_OK;
-        }
-    }
-}
-
-static void MPDIn_skip_disabled_rep(GF_MPD_Group *group, GF_MPD_Representation *rep)
-{
-       s32 rep_idx = gf_list_find(group->adaptation_set->representations, rep);
-       while (1) {
-               rep_idx++;
-               if (rep_idx==gf_list_count(group->adaptation_set->representations)) rep_idx = 0;
-               rep = gf_list_get(group->adaptation_set->representations, rep_idx);
-               if (!rep->disabled) break;
-       }
-       assert(rep && !rep->disabled);
-       MPD_SetGroupRepresentation(group, rep);
-       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Switching to representation %d - BW %d\n", group->active_rep_index, group->active_bitrate ));
-}
-
-
-static u32 download_segments(void *par)
-{
-    GF_Err e;
-    GF_MPD_In *mpdin = (GF_MPD_In*) par;
-    GF_MPD_Period *period;
-    GF_MPD_Representation *rep;
-    u32 i, group_count, ret = 0;
-       Bool go_on = 1;
-    char *new_base_seg_url;
-    assert(mpdin);
-    if (!mpdin->mpd){
-               GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("[MPD_IN] Incorrect state, no mpdin->mpd for URL=%s, already stopped ?\n", mpdin->url));
-      return 1;
-    }
-
-    /* Setting the download status in exclusive code */
-    gf_mx_p(mpdin->dl_mutex);
-    mpdin->mpd_is_running = MPD_STATE_CONNECTING;
-    gf_mx_v(mpdin->dl_mutex);
-
-restart_period:
-       mpdin->in_period_setup = 1;
-       e = GF_OK;
-    period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
-       group_count = gf_list_count(mpdin->groups);
-       for (i=0; i<group_count; i++) {
-           GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-               if (!group->selected) continue;
-           e = MPD_DownloadInitSegment(mpdin, group);
-               if (e) break;
-       }
-    mpdin->mpd_stop_request=0;
-
-       if (e != GF_OK) {
-        gf_term_on_connect(mpdin->service, NULL, e);
-        ret = 1;
-               goto exit;
-    }
-
-    mpdin->last_update_time = gf_sys_clock();
-
-    gf_mx_p(mpdin->dl_mutex);
-    mpdin->mpd_is_running = MPD_STATE_CONNECTING;
-    gf_mx_v(mpdin->dl_mutex);
-
-       for (i=0; i<group_count; i++) {
-               GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-               if (!group->selected) continue;
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Connecting initial service... %s\n", group->segment_local_url));
-               if (! group->input_module) {
-                       e = GF_SERVICE_ERROR;
-               gf_term_on_connect(mpdin->service, NULL, e);
-                       ret = 1;
-                       goto exit;
-               }
-               e = group->input_module->ConnectService(group->input_module, mpdin->service, group->segment_local_url);
-               if (e) {
-                       ret = 1;
-                       goto exit;
-               }
-               group->service_connected = 1;
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Connecting initial service DONE\n", group->segment_local_url));
-       }
-
-    gf_mx_p(mpdin->dl_mutex);
-       mpdin->in_period_setup = 0;
-    mpdin->mpd_is_running = MPD_STATE_RUNNING;
-    gf_mx_v(mpdin->dl_mutex);
-
-       while (go_on) {
-               const char *local_file_name = NULL;
-               const char *resource_name = NULL;
-        /*wait until next segment is needed*/
-        while (!mpdin->mpd_stop_request) {
-            u32 timer = gf_sys_clock() - mpdin->last_update_time;
-            Bool shouldParsePlaylist = mpdin->mpd->minimum_update_period && (timer > mpdin->mpd->minimum_update_period);
-
-                       if (shouldParsePlaylist) {
-                GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Next segment in cache, but it is time to update the playlist (%u ms/%u)\n", timer, mpdin->mpd->minimum_update_period));
-                e = MPD_UpdatePlaylist(mpdin);
-                               group_count = gf_list_count(mpdin->groups);
-                if (e) {
-                    GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error updating MPD %s\n", gf_error_to_string(e)));
-                }
-            } else {
-                               Bool all_groups_done = 1;
-                               Bool cache_full = 1;
-                           gf_mx_p(mpdin->dl_mutex);
-                               for (i=0; i<group_count; i++) {
-                                       GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-                                       if (!group->selected || group->done) continue;
-                                       all_groups_done = 0;
-                                       if (group->nb_cached_segments<group->max_cached_segments) {
-                                               cache_full = 0;
-                                               break;
-                                       }
-                               }
-                   gf_mx_v(mpdin->dl_mutex);
-                               if (!cache_full) break;
-
-                               if (mpdin->request_period_switch==2) all_groups_done = 1;
-
-                               if (all_groups_done && mpdin->request_period_switch) {
-                                       MPD_ResetGroups(mpdin);
-                                       if (mpdin->request_period_switch == 1) 
-                                               mpdin->active_period_index++;
-                                       
-                                       MPD_SetupPeriod(mpdin);
-                                       mpdin->request_period_switch = 0;
-
-                                       goto restart_period;
-                               }
-
-                               gf_sleep(16);
-            }
-        }
-
-        /* stop the thread if requested */
-        if (mpdin->mpd_stop_request) {
-            go_on = 0;
-            break;
-        }
-
-        /* Continue the processing (no stop request) */
-        period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
-
-               /*for each selected groups*/
-               for (i=0; i<group_count; i++) {         
-                       u64 start_range, end_range;
-                       Bool use_byterange;
-                       GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-                       if (! group->selected) continue;
-                       if (group->done) continue;
-
-
-                       if (group->nb_cached_segments>=group->max_cached_segments) {
-                               continue;
-                       }
-
-                       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);
-
-                       /* if the index of the segment to be downloaded is greater or equal to the last segment (as seen in the playlist),
-                          we need to check if a new playlist is ready */
-                       if (group->download_segment_index>=group->nb_segments_in_rep) {
-                               u32 timer = gf_sys_clock() - mpdin->last_update_time;
-                               /* update of the playlist, only if indicated */
-                               if (mpdin->mpd->minimum_update_period && timer > mpdin->mpd->minimum_update_period) {
-                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Last segment in current playlist downloaded, checking updates after %u ms\n", timer));
-                                       e = MPD_UpdatePlaylist(mpdin);
-                                       if (e) {
-                                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error updating MPD %s\n", gf_error_to_string(e)));
-                                       }
-                                       group_count = gf_list_count(mpdin->groups);
-                                       period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
-                                       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);
-                               } else {
-                                       gf_sleep(16);
-                               }
-                               /* Now that the playlist is up to date, we can check again */
-                               if (group->download_segment_index >= group->nb_segments_in_rep) {
-                                       if (mpdin->mpd->minimum_update_period) {
-                                               /* if there is a specified update period, we redo the whole process */
-                                               continue;
-                                       } else {
-                                               /* if not, we are really at the end of the playlist, we can quit */
-                                               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] End of playlist reached... downloading remaining elements..."));
-                                               group->done = 1;
-                                               break;
-                                       }
-                               }
-                       }
-                       gf_mx_p(mpdin->dl_mutex);
-
-                       /* At this stage, there are some segments left to be downloaded */
-                       e = MPD_ResolveURL(mpdin->mpd, rep, group->adaptation_set, group->period, mpdin->url, GF_MPD_RESOLVE_URL_MEDIA, group->download_segment_index, &new_base_seg_url, &start_range, &end_range, &group->current_downloaded_segment_duration);
-                       gf_mx_v(mpdin->dl_mutex);
-                       if (e) {
-                               /*do something!!*/
-                               break;
-                       }
-                       use_byterange = (start_range || end_range) ? 1 : 0;
-
-                       if (use_byterange) {
-                               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Downloading new segment: %s (range: "LLD"-"LLD")\n", new_base_seg_url, start_range, end_range));
-                       }
-
-                       /*local file*/
-                       if (!strstr(new_base_seg_url, "://") || !strnicmp(new_base_seg_url, "file://", 7)) {
-                               resource_name = local_file_name = (char *) new_base_seg_url; 
-                               e = GF_OK;
-                               /*do not erase local files*/
-                               group->local_files = 1;
-                               if (group->force_switch_bandwidth && !mpdin->auto_switch_count) {
-                                       MPD_SwitchGroupRepresentation(mpdin, group);
-                                       /*restart*/
-                                       i--;
-                                       continue;
-                               }
-
-                       } else {
-                               u32 total_size, bytes_per_sec;
-
-                               group->max_bitrate = 0;
-                               group->min_bitrate = (u32)-1;
-                               /*use persistent connection for segment downloads*/
-                               if (use_byterange) {
-                                       e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), new_base_seg_url, MPD_NetIO_Segment, group, start_range, end_range, 1);
-                               } else {
-                                       e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), new_base_seg_url, MPD_NetIO_Segment, group, 0, 0, 1);
-                               }
-
-                               if ((e==GF_OK) && group->force_switch_bandwidth) {
-                                       if (!mpdin->auto_switch_count) {
-                                               MPD_SwitchGroupRepresentation(mpdin, group);
-                                               /*restart*/
-                                               i--;
-                                               continue;
-                                       }
-                                       if (rep->disabled) {
-                                               MPDIn_skip_disabled_rep(group, rep);
-                                               /*restart*/
-                                               i--;
-                                               continue;
-                                       }
-                               }
-
-                               if (group->segment_must_be_streamed) local_file_name = gf_dm_sess_get_resource_name(group->segment_dnload);
-                               else local_file_name = gf_dm_sess_get_cache_name(group->segment_dnload);
-
-                               resource_name = gf_dm_sess_get_resource_name(group->segment_dnload);
-
-                               gf_dm_sess_get_stats(group->segment_dnload, NULL, NULL, &total_size, NULL, &bytes_per_sec, NULL);
-                               if (total_size && bytes_per_sec && group->current_downloaded_segment_duration) {
-                                       Double bitrate, time;
-                                       bitrate = 8*total_size;
-                                       bitrate *= 1000;
-                                       bitrate /= group->current_downloaded_segment_duration;
-                                       bitrate /= 1024;
-                                       time = total_size;
-                                       time /= bytes_per_sec;
-       
-                                       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Downloaded segment %d bytes in %g seconds - duration %g sec - Bandwidth (kbps): indicated %d - computed %d - download %d\n", total_size, time, group->current_downloaded_segment_duration/1000.0, rep->bandwidth/1024, (u32) bitrate, 8*bytes_per_sec/1024));
-
-                                       if (rep->bandwidth < 8*bytes_per_sec) {
-                                               u32 k;
-                                               /*find highest bandwidth that fits our bitrate*/
-                                               GF_MPD_Representation *new_rep = NULL;
-                                               for (k=0; k<gf_list_count(group->adaptation_set->representations); k++) {
-                                                       GF_MPD_Representation *arep = gf_list_get(group->adaptation_set->representations, k);
-                                                       if (8*bytes_per_sec > arep->bandwidth) {
-                                                               if (!new_rep) new_rep = arep;
-                                                               else if (arep->bandwidth > new_rep->bandwidth) {
-                                                                       new_rep = arep;
-                                                               }
-                                                       }
-                                               }
-                                               if (new_rep) {
-                                                       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Switching to new representation bitrate %d kbps\n", new_rep->bandwidth/1024));
-                                                       MPD_SetGroupRepresentation(group, new_rep);
-                                               }
-                                       }
-                               }
-                       }
-
-                       if (local_file_name && (e == GF_OK || group->segment_must_be_streamed )) {
-                               gf_mx_p(mpdin->dl_mutex);
-                               assert(group->nb_cached_segments<group->max_cached_segments);
-                               assert( local_file_name );
-                               group->cached[group->nb_cached_segments].cache = gf_strdup(local_file_name);
-                               group->cached[group->nb_cached_segments].url = gf_strdup( resource_name );
-                               group->cached[group->nb_cached_segments].start_range = 0;
-                               group->cached[group->nb_cached_segments].end_range = 0;
-                               if (group->local_files && use_byterange) {
-                                       group->cached[group->nb_cached_segments].start_range = start_range;
-                                       group->cached[group->nb_cached_segments].end_range = end_range;
-                               }
-                               if (!group->local_files) {
-                                       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Added file to cache\n\tURL: %s\n\tCache: %s\n\tElements in cache: %u/%u\n", group->cached[group->nb_cached_segments].url, group->cached[group->nb_cached_segments].cache, group->nb_cached_segments+1, group->max_cached_segments));
-                               }
-                               group->nb_cached_segments++;
-                               group->download_segment_index++;
-                               if (mpdin->auto_switch_count) {
-                                       group->nb_segments_done++;
-                                       if (group->nb_segments_done==mpdin->auto_switch_count) {
-                                               group->nb_segments_done=0;
-                                               MPDIn_skip_disabled_rep(group, rep);
-                                       }
-                               }
-                               gf_mx_v(mpdin->dl_mutex);
-                       }
-                       gf_free(new_base_seg_url);
-                       new_base_seg_url = NULL;
-                       if (e != GF_OK) {
-                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error in downloading new segment: %s %s\n", new_base_seg_url, gf_error_to_string(e)));
-                               go_on=0;
-                               break;
-                       }
-               }
-    }
-
-exit:
-    /* Signal that the download thread has ended */
-    gf_mx_p(mpdin->dl_mutex);
-    mpdin->mpd_is_running = MPD_STATE_STOPPED;
-    gf_mx_v(mpdin->dl_mutex);
-    return ret;
-}
-
-const char * MPD_MPD_DESC = "HTTP MPD Streaming";
-
-const char * MPD_MPD_EXT = "3gm mpd";
-
-const char * MPD_M3U8_DESC = "HTTP M3U8 Playlist Streaming";
-
-const char * MPD_M3U8_EXT = "m3u8 m3u";
-
-static u32 MPD_RegisterMimeTypes(const GF_InputService *plug)
-{
-    u32 i, c;
-    for (i = 0 ; MPD_MIME_TYPES[i]; i++)
-        gf_term_register_mime_type (plug, MPD_MIME_TYPES[i], MPD_MPD_EXT, MPD_MPD_DESC);
-    c = i;
-    for (i = 0 ; M3U8_MIME_TYPES[i]; i++)
-        gf_term_register_mime_type(plug, M3U8_MIME_TYPES[i], MPD_M3U8_EXT, MPD_M3U8_DESC);
-    return c+i;
-}
-
-Bool MPD_CanHandleURL(GF_InputService *plug, const char *url)
-{
-    u32 i;
-       char *sExt;
-    if (!plug || !url)
-      return 0;
-    sExt = strrchr(url, '.');
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Can Handle URL request from terminal for %s\n", url));
-    for (i = 0 ; MPD_MIME_TYPES[i]; i++) {
-        if (gf_term_check_extension(plug, MPD_MIME_TYPES[i], MPD_MPD_EXT, MPD_MPD_DESC, sExt))
-            return 1;
-    }
-    for (i = 0 ; M3U8_MIME_TYPES[i]; i++) {
-        if (gf_term_check_extension(plug, M3U8_MIME_TYPES[i], MPD_M3U8_EXT, MPD_M3U8_DESC, sExt))
-            return 1;
-    }
-    return MPD_CheckRootType(url);
+                       gf_modules_close_interface((GF_BaseInterface *) ifce);
+               }
+       }
+       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MPD_IN] Error locating plugin for segment - mime type %s - name %s\n", mime, init_segment_name));
+    return GF_CODEC_NOT_FOUND;
 }
 
 
+
 GF_InputService *MPD_GetInputServiceForChannel(GF_MPD_In *mpdin, LPNETCHANNEL channel)
 {
        GF_Channel *ch;
-       if (mpdin->group_zero_selected) return mpdin->group_zero_selected->input_module;
-       ch = (GF_Channel *) channel;
-       assert(ch && ch->odm && ch->odm->OD);
+       if (!channel) {
+               if (gf_dash_is_group_selected(mpdin->dash, 0)) {
+                       GF_MPDGroup *mudta = gf_dash_get_group_udta(mpdin->dash, 0);
+                       return mudta ? mudta->segment_ifce : NULL;
+               }
+               return NULL;
+       }
 
+       ch = (GF_Channel *) channel;
+       assert(ch->odm && ch->odm->OD);
        return (GF_InputService *) ch->odm->OD->service_ifce;
 }
 
-GF_MPD_Group *MPD_GetGroupForInputService(GF_MPD_In *mpdin, GF_InputService *ifce)
+s32 MPD_GetGroupIndexForChannel(GF_MPD_In *mpdin, LPNETCHANNEL channel)
 {
        u32 i;
-       for (i=0; i<gf_list_count(mpdin->groups); i++) {
-               GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-               if (group->input_module==ifce) return group;
+       GF_InputService *ifce = MPD_GetInputServiceForChannel(mpdin, channel);
+       if (!ifce) return -1;
+
+       for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+               GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, i);
+               if (!group) continue;
+               if (group->segment_ifce == ifce) return i;
        }
-       return NULL;
+       return -1;
 }
 
 GF_Err MPD_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream)
@@ -1903,7 +292,7 @@ GF_Err MPD_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const cha
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
        GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel);
     if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR;
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Channel Connection (%p) request from terminal for %s\n", channel, url));
+    GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Channel Connection (%p) request from terminal for %s\n", channel, url));
        return segment_ifce->ConnectChannel(segment_ifce, channel, url, upstream);
 }
 
@@ -1912,628 +301,275 @@ GF_Err MPD_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel)
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
        GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel);
     if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR;
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Disconnect channel (%p) request from terminal \n", channel));
+    GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Disconnect channel (%p) request from terminal \n", channel));
 
        return segment_ifce->DisconnectChannel(segment_ifce, channel);
 }
 
-static u32 MPD_GetPeriodIndexFromTime(GF_MPD_In *mpdin, u32 time)
+void mpdin_dash_io_delete_cache_file(GF_DASHFileIO *dashio, GF_DASHFileIOSession session, const char *cache_url)
 {
-    u32 i, count;
-    GF_MPD_Period *period;
-    count = gf_list_count(mpdin->mpd->periods);
-    for (i = 0; i<count; i++) {
-        period = gf_list_get(mpdin->mpd->periods, i);
-        if (period->start > time) {
-            break;
-        }
-    }
-    return (i-1 >= 0 ? (i-1) : 0);
+       gf_dm_delete_cached_file_entry_session((GF_DownloadSession *)session, cache_url);
 }
 
-static void MPD_DownloadStop(GF_MPD_In *mpdin)
+GF_DASHFileIOSession mpdin_dash_io_create(GF_DASHFileIO *dashio, Bool persistent, const char *url)
 {
-       u32 i;
-    assert( mpdin );
-    if (mpdin->groups) {
-               for (i=0; i<gf_list_count(mpdin->groups); i++) {
-                       GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-                       assert( group );
-                       if (group->selected && group->segment_dnload) {
-                               gf_dm_sess_abort(group->segment_dnload);
-                               group->done = 1;
-                       }
-               }
-    }
-    /* stop the download thread */
-    gf_mx_p(mpdin->dl_mutex);
-    if (mpdin->mpd_is_running != MPD_STATE_STOPPED) {
-        mpdin->mpd_stop_request = 1;
-        gf_mx_v(mpdin->dl_mutex);
-        while (1) {
-            /* waiting for the download thread to stop */
-            gf_sleep(16);
-            gf_mx_p(mpdin->dl_mutex);
-            if (mpdin->mpd_is_running != MPD_STATE_RUNNING) {
-                /* it's stopped we can continue */
-                gf_mx_v(mpdin->dl_mutex);
-                break;
-            }
-            gf_mx_v(mpdin->dl_mutex);
-        }
-    } else {
-        gf_mx_v(mpdin->dl_mutex);
-    }
-}
+       u32 flags = GF_NETIO_SESSION_NOT_THREADED;
+       GF_MPD_In *mpdin = (GF_MPD_In *)dashio->udta;
+       GF_DownloadSession *sess;
 
-Bool MPD_SeekPeriods(GF_MPD_In *mpdin)
+       if (persistent) flags |= GF_NETIO_SESSION_PERSISTENT;
+       sess = gf_term_download_new(mpdin->service, url, flags, NULL, NULL);
+       return (GF_DASHFileIOSession ) sess;
+}
+void mpdin_dash_io_del(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
 {
-       Double start_time;
-       u32 i, period_idx;
-
-       gf_mx_p(mpdin->dl_mutex);
-       
-       mpdin->start_range_in_segment_at_next_period = 0;
-       start_time = 0;
-       period_idx = 0;
-       for (i=0; i<=gf_list_count(mpdin->mpd->periods); i++) {
-               GF_MPD_Period *period = gf_list_get(mpdin->mpd->periods, i);
-               Double dur = period->duration;
-               dur /= 1000;
-               if (mpdin->playback_start_range >= start_time) {
-                       if ((i+1==gf_list_count(mpdin->mpd->periods)) || (mpdin->playback_start_range < start_time + dur) ) {
-                               period_idx = i;
-                               break;
-                       }
-               }
-               start_time += dur;
-       }
-       if (period_idx != mpdin->active_period_index) {
-               mpdin->playback_start_range -= start_time;
-               mpdin->active_period_index = period_idx;
-               mpdin->request_period_switch = 2;
-
-               /*figure out default segment duration and substract from our start range request*/
-               if (mpdin->playback_start_range) {
-                       Double duration;
-                       u32 nb_segs;
-                       GF_MPD_Period *period = gf_list_get(mpdin->mpd->periods, period_idx);
-                       GF_MPD_AdaptationSet *set = gf_list_get(period->adaptation_sets, 0);
-                       GF_MPD_Representation *rep = gf_list_get(set->representations, 0);
-
-                       MPD_GetSegmentDuration(rep, set, period, mpdin->mpd, &nb_segs, &duration);
-
-                       if (duration) {
-                               while (mpdin->playback_start_range - mpdin->start_range_in_segment_at_next_period >= duration)
-                                       mpdin->start_range_in_segment_at_next_period += duration;
-                       }
-
-               }
-       }
-       gf_mx_v(mpdin->dl_mutex);
-       
-       return mpdin->request_period_switch ? 1 : 0;
+       gf_term_download_del((GF_DownloadSession *)session);
 }
-
-void MPD_SeekGroup(GF_MPD_In *mpdin, GF_MPD_Group *group)
+void mpdin_dash_io_abort(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
 {
-       Double seg_start;
-       u32 first_downloaded, last_downloaded, segment_idx;
-
-       group->force_segment_switch = 0;
-       if (!group->segment_duration) return;
-
-       /*figure out where to seek*/
-       segment_idx = 0;
-       seg_start = 0.0;
-       while (1) {
-               if ((mpdin->playback_start_range >= seg_start) && (mpdin->playback_start_range < seg_start + group->segment_duration)) 
-                       break;
-               seg_start += group->segment_duration;
-               segment_idx++;
-       }
-       /*todo - seek to given duration*/
-       mpdin->playback_start_range -= seg_start;
-
-       first_downloaded = last_downloaded = group->download_segment_index;
-       if (group->download_segment_index +1 >= group->nb_cached_segments) {
-               first_downloaded = group->download_segment_index + 1 - group->nb_cached_segments;
-       }
-       /*we are seeking in our download range, just go on*/
-       if ((segment_idx >= first_downloaded) && (segment_idx<=last_downloaded)) return;
-
-       group->force_segment_switch = 1;
-       group->download_segment_index = segment_idx;
-
-       if (group->segment_dnload) 
-               gf_dm_sess_abort(group->segment_dnload);
-
-       if (group->urlToDeleteNext) {
-               if (!mpdin->keep_files && !group->local_files)
-                       gf_dm_delete_cached_file_entry_session(group->segment_dnload, group->urlToDeleteNext);
-    
-               gf_free(group->urlToDeleteNext);
-               group->urlToDeleteNext = NULL;
-       }
-       if (group->segment_dnload) {
-               gf_term_download_del(group->segment_dnload);
-               group->segment_dnload = NULL;
-       }
-       while (group->nb_cached_segments) {
-               group->nb_cached_segments --;
-               if (!mpdin->keep_files && !group->local_files)
-                       gf_delete_file(group->cached[group->nb_cached_segments].cache);
-
-               gf_free(group->cached[group->nb_cached_segments].cache);
-               gf_free(group->cached[group->nb_cached_segments].url);
-               memset(&group->cached[group->nb_cached_segments], 0, sizeof(segment_cache_entry));
-       }
+    gf_dm_sess_abort((GF_DownloadSession *)session);
 }
-
-void MPD_SeekGroupsDownloads(GF_MPD_In *mpdin)
+GF_Err mpdin_dash_io_setup_from_url(GF_DASHFileIO *dashio, GF_DASHFileIOSession session, const char *url)
 {
-       u32 i;
-
-       gf_mx_p(mpdin->dl_mutex);
-
-       if (mpdin->active_period_index) {
-               Double dur = 0;
-               u32 i;
-               for (i=0; i<mpdin->active_period_index; i++) {
-                       GF_MPD_Period *period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index-1);
-                       dur += period->duration/1000.0;
-               }
-               mpdin->playback_start_range -= dur;
-       }
-       for (i=0; i<gf_list_count(mpdin->groups); i++) {
-               GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-               MPD_SeekGroup(mpdin, group);
-       }
-       gf_mx_v(mpdin->dl_mutex);
+       return gf_dm_sess_setup_from_url((GF_DownloadSession *)session, url);
 }
-
-
-void MPD_ResetGroups(GF_MPD_In *mpdin)
+GF_Err mpdin_dash_io_set_range(GF_DASHFileIO *dashio, GF_DASHFileIOSession session, u64 start_range, u64 end_range)
 {
-       mpdin->service->subservice_disconnect = 1;
-       gf_term_on_disconnect(mpdin->service, NULL, GF_OK);
-
-       mpdin->service->subservice_disconnect = 2;
-       while (gf_list_count(mpdin->groups)) {
-               GF_MPD_Group *group = gf_list_last(mpdin->groups);
-               gf_list_rem_last(mpdin->groups);
-
-               if (group->urlToDeleteNext) {
-                       if (!mpdin->keep_files && !group->local_files)
-                               gf_dm_delete_cached_file_entry_session(group->segment_dnload, group->urlToDeleteNext);
-           
-                       gf_free(group->urlToDeleteNext);
-                       group->urlToDeleteNext = NULL;
-               }
-               if (group->segment_dnload) {
-                       gf_term_download_del(group->segment_dnload);
-                       group->segment_dnload = NULL;
-               }
-               while (group->nb_cached_segments) {
-                       group->nb_cached_segments --;
-                       if (!mpdin->keep_files && !group->local_files)
-                               gf_delete_file(group->cached[group->nb_cached_segments].cache);
-
-                       gf_free(group->cached[group->nb_cached_segments].cache);
-                       gf_free(group->cached[group->nb_cached_segments].url);
-               }
-               gf_free(group->cached);
-
-               if (group->input_module) {
-                       if (group->service_connected) {
-                               group->input_module->CloseService(group->input_module);
-                               group->service_connected = 0;
-                       }
-                       gf_modules_close_interface((GF_BaseInterface *) group->input_module);
-                       group->input_module = NULL;
-               }
-
-               gf_free(group);
-       }
-       gf_list_del(mpdin->groups);
-       mpdin->groups = NULL;
-       mpdin->service->subservice_disconnect = 0;
+       return gf_dm_sess_set_range((GF_DownloadSession *)session, start_range, end_range);
+}
+GF_Err mpdin_dash_io_init(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       return gf_dm_sess_process_headers((GF_DownloadSession *)session);
+}
+GF_Err mpdin_dash_io_run(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       return gf_dm_sess_process((GF_DownloadSession *)session);
+}
+const char *mpdin_dash_io_get_url(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       return gf_dm_sess_get_resource_name((GF_DownloadSession *)session);
+}
+const char *mpdin_dash_io_get_cache_name(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       return gf_dm_sess_get_cache_name((GF_DownloadSession *)session);
+}
+const char *mpdin_dash_io_get_mime(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       return gf_dm_sess_mime_type((GF_DownloadSession *)session);
+}
+u32 mpdin_dash_io_get_bytes_per_sec(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       u32 bps=0;
+       GF_DownloadSession *sess = (GF_DownloadSession *)session;
+    gf_dm_sess_get_stats((GF_DownloadSession *)session, NULL, NULL, NULL, NULL, &bps, NULL);
+       return bps;
+}
+u32 mpdin_dash_io_get_total_size(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
+{
+       u32 size=0;
+       GF_DownloadSession *sess = (GF_DownloadSession *)session;
+    gf_dm_sess_get_stats((GF_DownloadSession *)session, NULL, NULL, &size, NULL, NULL, NULL);
+       return size;
 }
 
-/* create groups (implemntation of adaptations set) */
-GF_Err MPD_SetupGroups(GF_MPD_In *mpdin)
+GF_Err mpdin_dash_io_on_dash_event(GF_DASHFileIO *dashio, GF_DASHEventType dash_evt, GF_Err error_code)
 {
        GF_Err e;
-       u32 i, j, count;
-    GF_MPD_Period *period;
-       if (!mpdin->groups) {
-               mpdin->groups = gf_list_new();
-               if (!mpdin->groups) return GF_OUT_OF_MEM;
-       }
+       u32 i;
+       GF_MPD_In *mpdin = (GF_MPD_In *)dashio->udta;
 
-       period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
-       if (!period) return GF_BAD_PARAM;
-
-       count = gf_list_count(period->adaptation_sets);
-       for (i=0; i<count; i++) {
-        Bool found = 0;
-               GF_MPD_AdaptationSet *set = gf_list_get(period->adaptation_sets, i);
-               for (j=0; j<gf_list_count(mpdin->groups); j++) {
-                       GF_MPD_Group *group = gf_list_get(mpdin->groups, j);
-                       if (group->adaptation_set==set) {
-                       found = 1;
-                               break;
-                       }
-               }
-               if (!found) {
-                       GF_MPD_Group *group;
-                       GF_SAFEALLOC(group, GF_MPD_Group);
-                       if (!group) return GF_OUT_OF_MEM;
-                       group->mpd_in = mpdin;
-                       group->adaptation_set = set;
-                       group->period = period;
-                       group->period = period;
-                       group->max_cached_segments = mpdin->option_max_cached;
-                       group->cached = gf_malloc(sizeof(segment_cache_entry)*group->max_cached_segments);
-                       memset(group->cached, 0, sizeof(segment_cache_entry)*group->max_cached_segments);
-                       if (!group->cached) {
-                               gf_free(group);
-                               return GF_OUT_OF_MEM;
-                       }
-                       e = gf_list_add(mpdin->groups, group);
-                       if (e) {
-                               gf_free(group->cached);
-                               gf_free(group);
-                               return e;
-                       }
+       if (dash_evt==GF_DASH_EVENT_PERIOD_SETUP_ERROR) {
+               if (!mpdin->connection_ack_sent) {
+               gf_term_on_connect(mpdin->service, NULL, error_code);
+                       mpdin->connection_ack_sent=1;
                }
+               return GF_OK;
        }
-       return GF_OK;
-}
 
-GF_Err MPD_SetupPeriod(GF_MPD_In *mpdin)
-{
-       GF_Err e;
-    u32 rep_i, group_i;
-
-       /*setup all groups*/
-       MPD_SetupGroups(mpdin);
-       mpdin->group_zero_selected = NULL;
-
-       for (group_i=0; group_i<gf_list_count(mpdin->groups); group_i++) {
-               GF_MPD_Representation *rep_sel;
-               u32 active_rep;
-               const char *mime_type;
-               GF_MPD_Group *group = gf_list_get(mpdin->groups, group_i);
-
-               if (group->adaptation_set->group==0) {
-                       mpdin->group_zero_selected = group;
-               } else if (mpdin->group_zero_selected) {
-                       /* if this group is not the group 0 and we have found the group 0, 
-                       we can safely ignore this group. */
-                       break;
+       if (dash_evt==GF_DASH_EVENT_SELECT_GROUPS) {
+               const char *opt;
+               for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+                       /*todo: select groups based on user criteria*/
+                       gf_dash_group_select(mpdin->dash, i, 1);
                }
+               opt = gf_modules_get_option((GF_BaseInterface *)mpdin->plug, "Systems", "Language3CC");
+               if (opt && strcmp(opt, "und"))
+                       gf_dash_groups_set_language(mpdin->dash, opt);
 
-               /* Select the appropriate representation in the given period */
-               active_rep = 0;
-               for (rep_i = 0; rep_i < gf_list_count(group->adaptation_set->representations); rep_i++) {
-                       GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, rep_i);
-                       rep_sel = gf_list_get(group->adaptation_set->representations, active_rep);
+               return GF_OK;
+       }
 
-                       if (rep_i && ( !rep->codecs || !rep_sel->codecs || strcmp(rep->codecs, rep_sel->codecs) ) ) continue;
+       /*for all selected groups, create input service and connect to init/first segment*/
+       if (dash_evt==GF_DASH_EVENT_CREATE_PLAYBACK) {
 
-                       /*by default tune to best quality and/or full bandwith*/
-                       if (rep->quality_ranking > rep_sel->quality_ranking) {
-                               active_rep = rep_i;
-                       } else if (rep->bandwidth < rep_sel->bandwidth) {
-                               active_rep = rep_i;
-                       }
+               /*select input services if possible*/
+               for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+                       const char *mime, *init_segment;
+                       
+                       if (!gf_dash_is_group_selected(mpdin->dash, i))
+                               continue;
 
+                       mime = gf_dash_group_get_segment_mime(mpdin->dash, i);
+                       init_segment = gf_dash_group_get_segment_init_url(mpdin->dash, i, NULL, NULL);
+                       e = MPD_LoadMediaService(mpdin, i, mime, init_segment);
+                       if (e != GF_OK) {
+                               gf_dash_group_select(mpdin->dash, i, 0);
+                       } else {
+                               /*connect our media service*/
+                               GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, i);
+                               e = group->segment_ifce->ConnectService(group->segment_ifce, mpdin->service, init_segment);
+                               if (e) {
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD_IN] Unable to connect input service to %s\n", init_segment));
+                                       gf_dash_group_select(mpdin->dash, i, 0);
+                               } else {
+                                       group->service_connected = 1;
+                               }
+                       }
                }
 
-               rep_sel = gf_list_get(group->adaptation_set->representations, active_rep);
-               MPD_SetGroupRepresentation(group, rep_sel);
-
-               if (mpdin->playback_start_range>=0) 
-                       MPD_SeekGroup(mpdin, group);
-
-               mime_type = MPD_GetMimeType(NULL, rep_sel, group->adaptation_set);
-
-               if (!mime_type) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: missing mime\n"));
-                       return GF_NON_COMPLIANT_BITSTREAM;
+               if (!mpdin->connection_ack_sent) {
+               gf_term_on_connect(mpdin->service, NULL, GF_OK);
+                       mpdin->connection_ack_sent=1;
                }
+               return GF_OK;
+       }
 
-               /* TODO: Generate segment names if urltemplates are used */
-               if (!rep_sel->segment_base && !rep_sel->segment_list && !rep_sel->segment_template
-                       && !group->adaptation_set->segment_base && !group->adaptation_set->segment_list && !group->adaptation_set->segment_template
-                       && !group->period->segment_base && !group->period->segment_list && !group->period->segment_template
-                       && !gf_list_count(rep_sel->base_URLs)
-               
-               ) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: missing segments\n"));
-                       return GF_NON_COMPLIANT_BITSTREAM;
-               }
+       /*for all running services, stop service*/
+       if (dash_evt==GF_DASH_EVENT_DESTROY_PLAYBACK) {
 
-               group->input_module = NULL;
-               if (strcmp(M3U8_UNKOWN_MIME_TYPE, mime_type)) {
-                       e = MPD_LoadMediaService(mpdin, group, mime_type, NULL);
-                       if (e != GF_OK) return e;
-               } else {
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Ignoring mime type %s, wait for first file...\n", mime_type));
+               mpdin->service->subservice_disconnect = 1;
+               gf_term_on_disconnect(mpdin->service, NULL, GF_OK);
+               mpdin->service->subservice_disconnect = 2;
+
+               for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+                       GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, i);
+                       if (!group) continue;
+                       if (group->segment_ifce) {
+                               if (group->service_connected) {
+                                       group->segment_ifce->CloseService(group->segment_ifce);
+                                       group->service_connected = 0;
+                               }
+                               gf_modules_close_interface((GF_BaseInterface *) group->segment_ifce);
+                       }
+                       gf_free(group);                 
+                       gf_dash_set_group_udta(mpdin->dash, i, NULL);
                }
-               group->selected = 1;
+               mpdin->service->subservice_disconnect = 0;
        }
 
-       /*and seek if needed*/
        return GF_OK;
 }
 
-static GF_Err MPD_SegmentsProcessStart(GF_MPD_In *mpdin, u32 time)
-{
-    GF_Err e = GF_BAD_PARAM;
-    GF_MPD_Period *period;
-
-       MPD_ResetGroups(mpdin);
-
-       /* Get the right period from the given time */
-    mpdin->active_period_index = MPD_GetPeriodIndexFromTime(mpdin, time);
-    period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
-       if (!period || !gf_list_count(period->adaptation_sets) ) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: not enough periods or representations in MPD\n"));
-        goto exit;
-    }
-
-       e = MPD_SetupPeriod(mpdin);
-       if (e) goto exit;
-
-       gf_th_run(mpdin->mpd_thread, download_segments, mpdin);
-    return GF_OK;
-
-exit:
-    gf_term_on_connect(mpdin->service, NULL, e);
-    return e;
-}
-
-
-static GF_Err http_ifce_get(GF_FileDownload *getter, char *url)
-{
-    GF_MPD_In *mpdin = (GF_MPD_In*) getter->udta;
-       GF_DownloadSession *sess = gf_term_download_new(mpdin->service, url, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL);
-       if (!sess) return GF_IO_ERR;
-       getter->session = sess;
-       return gf_dm_sess_process(sess);
-}
-
-static void http_ifce_clean(GF_FileDownload *getter)
-{
-    GF_MPD_In *mpdin = (GF_MPD_In*) getter->udta;
-       if (getter->session) gf_term_download_del(getter->session);
-}
-
-static const char *http_ifce_cache_name(GF_FileDownload *getter)
-{
-    GF_MPD_In *mpdin = (GF_MPD_In*) getter->udta;
-       if (getter->session) return gf_dm_sess_get_cache_name(getter->session);
-       return NULL;
-}
 
 GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
 {
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
-       char local_path[GF_MAX_PATH];
-    const char *local_url, *opt;
+    const char *opt;
     GF_Err e;
-    GF_DOMParser *mpd_parser;
-    Bool is_m3u8 = 0;
-    Bool is_local = 0;
+       u32 max_cache_duration, auto_switch_count;
+       GF_DASHInitialSelectionMode first_select_mode;
+       Bool keep_files, disable_switching;
 
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Connection request (%p) from terminal for %s\n", serv, url));
+    GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Service Connection request (%p) from terminal for %s\n", serv, url));
 
     if (!mpdin|| !serv || !url) return GF_BAD_PARAM;
 
     mpdin->service = serv;
-    memset( mpdin->lastMPDSignature, 0, sizeof(mpdin->last_update_time));
-    mpdin->reload_count = 0;
-    if (mpdin->url)
-      gf_free(mpdin->url);
-    mpdin->url = gf_strdup(url);
-    mpdin->option_max_cached = 0;
-
-       mpdin->getter.udta = mpdin;
-       mpdin->getter.new_session = http_ifce_get;
-       mpdin->getter.del_session = http_ifce_clean;
-       mpdin->getter.get_cache_name = http_ifce_cache_name;
-       mpdin->getter.session = NULL;
-
-
-       opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "MaxCachedSegments");
-    if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "MaxCachedSegments", "3");
-    if (opt) mpdin->option_max_cached = atoi(opt);
-    if (!mpdin->option_max_cached) mpdin->option_max_cached = 1;
-       /*we need one more entry for the current segment being played*/
-       mpdin->option_max_cached++;
-
-    mpdin->auto_switch_count = 0;
+
+       mpdin->dash_io.udta = mpdin;
+       mpdin->dash_io.delete_cache_file = mpdin_dash_io_delete_cache_file;
+       mpdin->dash_io.create = mpdin_dash_io_create;
+       mpdin->dash_io.del = mpdin_dash_io_del;
+       mpdin->dash_io.abort = mpdin_dash_io_abort;
+       mpdin->dash_io.setup_from_url = mpdin_dash_io_setup_from_url;
+       mpdin->dash_io.set_range = mpdin_dash_io_set_range;
+       mpdin->dash_io.init = mpdin_dash_io_init;
+       mpdin->dash_io.run = mpdin_dash_io_run;
+       mpdin->dash_io.get_url = mpdin_dash_io_get_url;
+       mpdin->dash_io.get_cache_name = mpdin_dash_io_get_cache_name;
+       mpdin->dash_io.get_mime = mpdin_dash_io_get_mime;
+       mpdin->dash_io.get_bytes_per_sec = mpdin_dash_io_get_bytes_per_sec;
+       mpdin->dash_io.get_total_size = mpdin_dash_io_get_total_size;
+       mpdin->dash_io.on_dash_event = mpdin_dash_io_on_dash_event;
+
+       max_cache_duration = 30;
+       opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "MaxCacheDuration");
+    if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "MaxCacheDuration", "30");
+    if (opt) max_cache_duration = atoi(opt);
+
+    auto_switch_count = 0;
     opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "AutoSwitchCount");
     if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "AutoSwitchCount", "0");
-    if (opt) mpdin->auto_switch_count = atoi(opt);
+    if (opt) auto_switch_count = atoi(opt);
 
+       keep_files = 0;
     opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "KeepFiles");
     if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "KeepFiles", "no");
-    if (opt && !strcmp(opt, "yes")) mpdin->keep_files = 1;
+    if (opt && !strcmp(opt, "yes")) keep_files = 1;
 
+       disable_switching = 0;
        opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "DisableSwitching");
-    if (opt && !strcmp(opt, "yes")) mpdin->disable_switching = 1;
+    if (opt && !strcmp(opt, "yes")) disable_switching = 1;
+
+       first_select_mode = 0;
+       opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "StartRepresentation");
+       if (!opt) {
+               gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "StartRepresentation", "minBandwidth");
+               opt = "minBandwidth";
+       }
+       if (opt && !strcmp(opt, "maxBandwidth")) first_select_mode = GF_DASH_SELECT_BANDWIDTH_HIGHEST;
+    else if (opt && !strcmp(opt, "minQuality")) first_select_mode = GF_DASH_SELECT_QUALITY_LOWEST;
+    else if (opt && !strcmp(opt, "maxQuality")) first_select_mode = GF_DASH_SELECT_QUALITY_HIGHEST;
+    else first_select_mode = GF_DASH_SELECT_BANDWIDTH_LOWEST;
        
-       if (mpdin->mpd_dnload) gf_term_download_del(mpdin->mpd_dnload);
-    mpdin->mpd_dnload = NULL;
        mpdin->in_seek = 0;
        mpdin->previous_start_range = -1;
 
+       mpdin->dash = gf_dash_new(&mpdin->dash_io, max_cache_duration, auto_switch_count, keep_files, disable_switching, first_select_mode);
 
-    if (!strnicmp(url, "file://", 7)) {
-        local_url = url + 7;
-               is_local = 1;
-        if (strstr(url, ".m3u8")) {
-            is_m3u8 = 1;
-        }
-    } else if (strstr(url, "://")) {
-               /*use non-persistent connection for MPD downloads*/
-        e = MPD_downloadWithRetry(mpdin->service, &(mpdin->mpd_dnload), url, MPD_NetIO, mpdin, 0, 0, 1);
-        if (e!=GF_OK) {
-            GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service: MPD downloading problem %s for %s\n", gf_error_to_string(e), url));
-            gf_term_on_connect(mpdin->service, NULL, GF_IO_ERR);
-            gf_term_download_del(mpdin->mpd_dnload);
-            mpdin->mpd_dnload = NULL;
-            return e;
-               }
-               {
-                       const char *url;
-                       char mime[128];
-                       strncpy(&(mime[0]), gf_dm_sess_mime_type(mpdin->mpd_dnload), sizeof(mime));
-                       strlwr(mime);
-                       url = gf_dm_sess_get_resource_name(mpdin->mpd_dnload);
-                       /* Some servers, for instance http://tv.freebox.fr, serve m3u8 as text/plain */
-                       if (MPD_isM3U8_mime(mime) || strstr(url, ".m3u8")) {
-                               is_m3u8 = 1;
-                       } else if (!MPD_is_MPD_mime(mime) && !strstr(url, ".mpd")) {
-                               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] mime '%s' for '%s' should be m3u8 or mpd\n", mime, url));
-                               gf_term_on_connect(mpdin->service, NULL, GF_BAD_PARAM);
-                               gf_term_download_del(mpdin->mpd_dnload);
-                               mpdin->mpd_dnload = NULL;
-                               return GF_CODEC_NOT_FOUND;
-                       }
-               }
-        local_url = gf_dm_sess_get_cache_name(mpdin->mpd_dnload);
-        if (!local_url) {
-            GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service: cache problem %s\n", local_url));
-            gf_term_on_connect(mpdin->service, NULL, GF_IO_ERR);
-            gf_term_download_del(mpdin->mpd_dnload);
-            mpdin->mpd_dnload = NULL;
-            return GF_OK;
-        }
-    } else {
-        local_url = url;
-               is_local = 1;
-        if (strstr(url, ".m3u8"))
-            is_m3u8 = 1;
-    }
-       
-       if (is_local) {
-               FILE *f = fopen(local_url, "rt");
-               if (!f) {
-               gf_term_on_connect(mpdin->service, NULL, GF_URL_ERROR);
-                       return GF_OK;
-               }
-               fclose(f);
+       if (!mpdin->dash) {
+        GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MPD_IN] Error - cannot create DASH Client for %s\n", url));
+        gf_term_on_connect(mpdin->service, NULL, GF_IO_ERR);
+               return GF_OK;
        }
 
-    if (is_m3u8) {
-               if (is_local) {
-                       char *sep;
-                       strcpy(local_path, local_url);
-                       sep = strrchr(local_path, '.');
-                       if (sep) sep[0]=0;
-                       strcat(local_path, ".mpd");
-
-               gf_m3u8_to_mpd(local_url, url, local_path, mpdin->reload_count, mpdin->mimeTypeForM3U8Segments, 0, M3U8_TO_MPD_USE_TEMPLATE, &mpdin->getter);
-                       local_url = local_path;
-               } else {
-               gf_m3u8_to_mpd(local_url, url, NULL, mpdin->reload_count, mpdin->mimeTypeForM3U8Segments, 0, M3U8_TO_MPD_USE_TEMPLATE, &mpdin->getter);
-               }
-    }
-
-    if (!MPD_CheckRootType(local_url)) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service: wrong file type %s\n", local_url));
-        gf_term_on_connect(mpdin->service, NULL, GF_BAD_PARAM);
-        gf_term_download_del(mpdin->mpd_dnload);
-        mpdin->mpd_dnload = NULL;
-        return GF_OK;
-    }
-
-    /* parse the MPD */
-    mpd_parser = gf_xml_dom_new();
-    e = gf_xml_dom_parse(mpd_parser, local_url, NULL, NULL);
-    if (e != GF_OK) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service: MPD parsing problem %s\n", gf_xml_dom_get_error(mpd_parser) ));
-        gf_xml_dom_del(mpd_parser);
-        gf_term_on_connect(mpdin->service, NULL, e);
-        gf_term_download_del(mpdin->mpd_dnload);
-        mpdin->mpd_dnload = NULL;
-        return GF_OK;
-    }
-    if (mpdin->mpd)
-        gf_mpd_del(mpdin->mpd);
-    mpdin->mpd = gf_mpd_new();
-    if (!mpdin->mpd) {
-        e = GF_OUT_OF_MEM;
-    } else {
-        e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), mpdin->mpd, url);
-    }
-    gf_xml_dom_del(mpd_parser);
-    if (e != GF_OK) {
-        GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service: MPD creation problem %s\n", gf_error_to_string(e)));
+       /*dash thread starts at the end of gf_dash_open */
+       e = gf_dash_open(mpdin->dash, url);
+       if (!mpdin->dash) {
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MPD_IN] Error - cannot initialize DASH Client for %s: %s\n", url, gf_error_to_string(e) ));
         gf_term_on_connect(mpdin->service, NULL, e);
-        gf_term_download_del(mpdin->mpd_dnload);
-        mpdin->mpd_dnload = NULL;
-        if (mpdin->mpd)
-            gf_mpd_del(mpdin->mpd);
-        mpdin->mpd = NULL;
-        return e;
-    }
-
-    e = MPD_SegmentsProcessStart(mpdin, 0);
-    return e;
+               return GF_OK;
+       }
+       return GF_OK;
 }
 
 static GF_Descriptor *MPD_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url)
 {
-    GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Description request from terminal for %s\n", sub_url));
-       if (mpdin->group_zero_selected) {
-               if (mpdin->group_zero_selected->input_module) {
-               return mpdin->group_zero_selected->input_module->GetServiceDescriptor(mpdin->group_zero_selected->input_module, expect_type, sub_url);
-               } else {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot provide service description: no segment service hanlder created\n"));
-                       return NULL;
-               }
-       } else {
-               u32 i;
-               for (i=0; i<gf_list_count(mpdin->groups); i++) {
-                       GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-                       if (!group->selected) continue;
-                       if (group->service_descriptor_fetched) continue;
-                       group->service_descriptor_fetched = 1;
-               return group->input_module->GetServiceDescriptor(group->input_module, expect_type, sub_url);
-               }
-               return NULL;
+       u32 i;
+       GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
+    GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Service Description request from terminal for %s\n", sub_url));
+       for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
+               GF_MPDGroup *mudta;
+               if (!gf_dash_is_group_selected(mpdin->dash, i))
+                       continue;
+               mudta = gf_dash_get_group_udta(mpdin->dash, i);
+               if (!mudta) continue;
+               if (mudta->service_descriptor_fetched) continue;
+               mudta->service_descriptor_fetched = 1;
+               return mudta->segment_ifce->GetServiceDescriptor(mudta->segment_ifce, expect_type, sub_url);
        }
+       return NULL;
 }
 
-void MPD_Stop(GF_MPD_In *mpdin)
-{
-    assert( mpdin );
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Stopping service %p\n", mpdin->service));
-    MPD_DownloadStop(mpdin);
-    MPD_ResetGroups(mpdin);
-
-    if (mpdin->mpd_dnload) {
-        gf_term_download_del(mpdin->mpd_dnload);
-        mpdin->mpd_dnload = NULL;
-    }
-    if (mpdin->mpd)
-        gf_mpd_del(mpdin->mpd);
-    mpdin->mpd = NULL;
-}
 
 GF_Err MPD_CloseService(GF_InputService *plug)
 {
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
     assert( mpdin );
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Close Service (%p) request from terminal\n", mpdin->service));
+    GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Close Service (%p) request from terminal\n", mpdin->service));
    
-    MPD_Stop(mpdin);
+       if (mpdin->dash)
+               gf_dash_close(mpdin->dash);
 
        gf_term_on_disconnect(mpdin->service, NULL, GF_OK);
 
@@ -2542,18 +578,19 @@ GF_Err MPD_CloseService(GF_InputService *plug)
 
 GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
 {
+       s32 idx;
     GF_Err e;
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
        GF_InputService *segment_ifce = NULL;
-       GF_MPD_Group *group = NULL;
-    if (!plug || !plug->priv || !com ) return GF_SERVICE_ERROR;
 
-       if (mpdin->group_zero_selected) segment_ifce = mpdin->group_zero_selected->input_module;
+       if (!plug || !plug->priv || !com ) return GF_SERVICE_ERROR;
+
+       segment_ifce = MPD_GetInputServiceForChannel(mpdin, com->base.on_channel);
 
        switch (com->command_type) {
     case GF_NET_SERVICE_INFO:
     {
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Info command from terminal on Service (%p)\n", mpdin->service));
+        GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Info command from terminal on Service (%p)\n", mpdin->service));
 
                e = GF_OK;
                if (segment_ifce) {
@@ -2562,18 +599,13 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
                }
 
                if (e!= GF_OK || !com->info.name || 2 > strlen(com->info.name)) {
-                       GF_MPD_ProgramInfo *info = gf_list_get(mpdin->mpd->program_infos, 0);
-                       if (info) {
-                               com->info.name = info->title;
-                               com->info.comment = info->source;
-                       }
-                       if (!com->info.name && mpdin->group_zero_selected)
-                               com->info.name = mpdin->group_zero_selected->cached[0].url;
+                       gf_dash_get_info(mpdin->dash, &com->info.name, &com->info.comment);
         }
         return GF_OK;
     }
+       /*we could get it from MPD*/
     case GF_NET_SERVICE_HAS_AUDIO:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Has Audio command from terminal on Service (%p)\n", mpdin->service));
+        GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Has Audio command from terminal on Service (%p)\n", mpdin->service));
                if (segment_ifce) {
                /* defer to the real input service */
                    return segment_ifce->ServiceCommand(segment_ifce, com);
@@ -2581,44 +613,7 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
         return GF_NOT_SUPPORTED;
 
        case GF_NET_SERVICE_QUALITY_SWITCH:
-               {
-                       u32 i;
-
-                       for (i=0; i<gf_list_count(mpdin->groups); i++) {
-                               Bool do_switch = 0;
-                               GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-                               u32 current_idx = group->active_rep_index;
-                               if (! group->selected) continue;
-
-                               if (group->force_representation_idx_plus_one) current_idx = group->force_representation_idx_plus_one - 1;
-                               if (com->switch_quality.up) {
-                                       if (current_idx + 1 < gf_list_count(group->adaptation_set->representations)) {
-                                               group->force_representation_idx_plus_one = 1 + current_idx+1;
-                                               do_switch = 1;
-                                       }
-                               } else {
-                                       if (current_idx) {
-                                               group->force_representation_idx_plus_one = 1 + current_idx - 1;
-                                               do_switch = 1;
-                                       }
-                               }
-                               if (do_switch) {
-                                       gf_mx_p(mpdin->dl_mutex);
-                                       group->force_switch_bandwidth = 1;
-                                       /*in local playback just switch at the end of the current segment*/
-                                       while (group->local_files && (group->nb_cached_segments>1)) {
-                                               group->nb_cached_segments--;
-                                               gf_free(group->cached[group->nb_cached_segments].url);
-                                               group->cached[group->nb_cached_segments].url = NULL;
-                                               group->cached[group->nb_cached_segments].start_range = 0;
-                                               group->cached[group->nb_cached_segments].end_range = 0;
-                                               assert(group->download_segment_index>1);
-                                               group->download_segment_index--;
-                                       }
-                                       gf_mx_v(mpdin->dl_mutex);
-                               }
-                       }
-               }
+               gf_dash_switch_quality(mpdin->dash, com->switch_quality.up);
         return GF_OK;
        }
        /*not supported*/
@@ -2626,205 +621,125 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
        
        segment_ifce = MPD_GetInputServiceForChannel(mpdin, com->base.on_channel);
        if (!segment_ifce) return GF_NOT_SUPPORTED;
-       group = MPD_GetGroupForInputService(mpdin, segment_ifce);
-
 
        switch (com->command_type) {
-    case GF_NET_CHAN_SET_PADDING:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Padding command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        /* for padding settings, the MPD level should not change anything */
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_SET_PULL:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Pull command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        /* defer to the real input service */
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
     case GF_NET_CHAN_INTERACTIVE:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Interactive command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
         /* we are interactive (that's the whole point of MPD) */
         return GF_OK;
 
+       /*we should get it from MPD minBufferTime*/
        case GF_NET_CHAN_BUFFER:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Buffer query command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_BUFFER_QUERY:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received buffer query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
         return segment_ifce->ServiceCommand(segment_ifce, com);
         break;
-    case GF_NET_CHAN_DURATION:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Duration query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        /* Ignore the duration given by the input service and use the one given in the MPD
-           Note: the duration of the initial segment will be 0 anyway (in MP4).*/
-        {
-            Double duration;
-                       duration = (Double)mpdin->mpd->media_presentation_duration;
-                       if (!duration) {
-                               u32 i;
-                               for (i=0; i<gf_list_count(mpdin->mpd->periods); i++) {
-                                       GF_MPD_Period *period = gf_list_get(mpdin->mpd->periods, i);
-                                       duration += (Double)period->duration;
-                               }
+
+       case GF_NET_CHAN_DURATION:
+               /* Ignore the duration given by the input service and use the one given in the MPD
+                  Note: the duration of the initial segment will be 0 anyway (in MP4).*/
+               com->duration.duration = gf_dash_get_duration(mpdin->dash);
+               return GF_OK;
+
+       case GF_NET_CHAN_PLAY:
+               /*don't seek if this command is the first PLAY request of objects declared by the subservice*/
+               if (!com->play.initial_broadcast_play) {
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Play command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
+
+                       if (!gf_dash_in_period_setup(mpdin->dash) && !com->play.dash_segment_switch && ! mpdin->in_seek) {
+                               Bool skip_seek;
+                               
+                               mpdin->in_seek = 1;
+                               
+                               /*if start range request is the same as previous one, don't process it
+                               - this happens at period switch when new objects are declared*/
+                               skip_seek = (mpdin->previous_start_range==com->play.start_range) ? 1 : 0;
+                               mpdin->previous_start_range = com->play.start_range;
+
+                               gf_dash_seek(mpdin->dash, com->play.start_range);
+                       } 
+                       /*For MPEG-2 TS or formats not using Init Seg: since objects are declared and started once the first
+                       segment is playing, we will stay in playback_start_range!=-1 until next segment (because we won't have a query_next),
+                       which will prevent seeking until then ... we force a reset of playback_start_range to allow seeking asap*/
+                       else if (mpdin->in_seek && (com->play.start_range==0)) {
+//                             mpdin->in_seek = 0;
+                       }
+                       else if (gf_dash_in_period_setup(mpdin->dash) && (com->play.start_range==0)) {
+                               com->play.start_range = gf_dash_get_playback_start_range(mpdin->dash);
                        }
-            duration /= 1000;
-            com->duration.duration = duration;
-            return GF_OK;
-        }
-        break;
-    case GF_NET_CHAN_PLAY:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Play command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
 
-               if (! mpdin->in_period_setup && !com->play.dash_segment_switch && ! mpdin->in_seek) {
-                       Bool skip_seek;
-                       
-                       mpdin->in_seek = 1;
-                       
-                       /*if start range request is the same as previous one, don't process it
-                       - this happens at period switch when new objects are declared*/
-                       skip_seek = (mpdin->previous_start_range==com->play.start_range) ? 1 : 0;
-                       mpdin->previous_start_range = com->play.start_range;
-
-               mpdin->playback_speed = com->play.speed;
-                   mpdin->playback_start_range = com->play.start_range;
-
-                       /*first check if we seek to another period*/
-                       if (! MPD_SeekPeriods(mpdin)) {
-                               /*if no, seek in group*/
-                               MPD_SeekGroupsDownloads(mpdin);
+                       idx = MPD_GetGroupIndexForChannel(mpdin, com->play.on_channel);
+                       if (idx>=0) {
+                               gf_dash_set_group_done(mpdin->dash, idx, 0);
+                               com->play.dash_segment_switch = gf_dash_group_segment_switch_forced(mpdin->dash, idx);
                        }
-               } 
-               /*For MPEG-2 TS or formats not using Init Seg: since objects are declared and started once the first
-               segment is playing, we will stay in playback_start_range!=-1 until next segment (because we won't have a query_next),
-               which will prevent seeking until then ... we force a reset of playback_start_range to allow seeking asap*/
-               else if (mpdin->in_seek && (com->play.start_range==0)) {
-//                     mpdin->in_seek = 0;
-               }
-               else if (mpdin->in_period_setup && (com->play.start_range==0)) {
-                       com->play.start_range = mpdin->playback_start_range;
-               }
 
-               group->done = 0;
-               com->play.dash_segment_switch = group->force_segment_switch;
-               /*don't forward commands, we are killing the service anyway ...*/
-               if (mpdin->request_period_switch) return GF_OK;
+                       /*don't forward commands, we are killing the service anyway ...*/
+                       if (gf_dash_get_period_switch_status(mpdin->dash) ) return GF_OK;
+               }
 
                return segment_ifce->ServiceCommand(segment_ifce, com);
 
        case GF_NET_CHAN_STOP:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Stop command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-               group->done = 1;
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-    case GF_NET_CHAN_PAUSE:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Pause command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-    case GF_NET_CHAN_RESUME:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Resume command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-       case GF_NET_CHAN_SET_SPEED:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Speed command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        /* recording the speed, to change the segment download speed */
-        mpdin->playback_speed = com->play.speed;
-        return segment_ifce->ServiceCommand(segment_ifce, com);
+       {
+               s32 idx = MPD_GetGroupIndexForChannel(mpdin, com->play.on_channel);
+               if (idx>=0) {
+                       gf_dash_set_group_done(mpdin->dash, (u32) idx, 1);
+               }
+       }
+               return segment_ifce->ServiceCommand(segment_ifce, com);
 
-       case GF_NET_CHAN_CONFIG:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Config command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        /* defer to the real input service */
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_GET_PIXEL_AR:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Pixel Aspect Ratio query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
+       /*we could get it from MPD*/
+       case GF_NET_CHAN_GET_PIXEL_AR:
         /* defer to the real input service */
         return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_GET_DSI:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Decoder Specific Info query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_MAP_TIME:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Map Time query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_RECONFIG:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Reconfig command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_DRM_CFG:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received DRM query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_CHAN_GET_ESD:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Elementary Stream Descriptor query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_BUFFER_QUERY:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Global Buffer query from terminal on Service (%p)\n", mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_GET_STATS:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Statistics query from terminal on Service (%p)\n", mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_IS_CACHABLE:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Cachable query from terminal on Service (%p)\n", mpdin->service));
-        return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
-    case GF_NET_SERVICE_MIGRATION_INFO:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Migration info query from terminal on Service (%p)\n", mpdin->service));
+
+       case GF_NET_CHAN_SET_SPEED:
         return segment_ifce->ServiceCommand(segment_ifce, com);
-        break;
+
     default:
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received unknown command (%d) on Service (%p)\n",com->command_type, mpdin->service));
-        return GF_SERVICE_ERROR;
+        return segment_ifce->ServiceCommand(segment_ifce, com);
     }
 }
 
 GF_Err MPD_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data)
 {
-    GF_Err e;
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
        GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel);
     if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR;
-
-//    gf_mx_p(mpdin->dl_mutex);
-    e = segment_ifce->ChannelGetSLP(segment_ifce, channel, out_data_ptr, out_data_size, out_sl_hdr, sl_compressed, out_reception_status, is_new_data);
-//    gf_mx_v(mpdin->dl_mutex);
-    return e;
+    return segment_ifce->ChannelGetSLP(segment_ifce, channel, out_data_ptr, out_data_size, out_sl_hdr, sl_compressed, out_reception_status, is_new_data);
 }
 
 GF_Err MPD_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel)
 {
-    GF_Err e;
     GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
        GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel);
     if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR;
-
-//    gf_mx_p(mpdin->dl_mutex);
-    e = segment_ifce->ChannelReleaseSLP(segment_ifce, channel);
-//    gf_mx_v(mpdin->dl_mutex);
-    return e;
+    return segment_ifce->ChannelReleaseSLP(segment_ifce, channel);
 }
 
 Bool MPD_CanHandleURLInService(GF_InputService *plug, const char *url)
 {
        /**
-        * May arrive when using pid:// URLs into a TS stream
-        */
+       * May arrive when using pid:// URLs into a TS stream
+       */
        GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv;
-    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Can Handle URL In Service (%p) request from terminal for %s\n", mpdin->service, url));
-    if (!plug || !plug->priv) return GF_SERVICE_ERROR;
-    if (mpdin->url && !strcmp(mpdin->url, url)) {
-        return 1;
-    } else {
-       GF_InputService *segment_ifce = NULL;
-        GF_MPD_Group *group = NULL;
-        if (mpdin->group_zero_selected)
-               segment_ifce = mpdin->group_zero_selected->input_module;
-       if (segment_ifce && segment_ifce->CanHandleURLInService){
-               return segment_ifce->CanHandleURLInService(plug, url);
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Can Handle URL In Service (%p) request from terminal for %s\n", mpdin->service, url));
+       if (!plug || !plug->priv) return GF_SERVICE_ERROR;
+       if (gf_dash_get_url(mpdin->dash) && !strcmp(gf_dash_get_url(mpdin->dash) , url)) {
+               return 1;
+       } else {
+               GF_MPDGroup *mudta;
+               GF_InputService *segment_ifce = NULL;
+               u32 i;
+               for (i=0;i<gf_dash_get_group_count(mpdin->dash); i++) {
+                       if (!gf_dash_is_group_selected(mpdin->dash, i)) continue;
+                       
+                       mudta = gf_dash_get_group_udta(mpdin->dash, i);
+                       segment_ifce = mudta->segment_ifce;
+                       if (mudta && mudta->segment_ifce && mudta->segment_ifce->CanHandleURLInService) {
+                               return mudta->segment_ifce->CanHandleURLInService(plug, url);
+                       }
+               }
+               return 0;
        }
-        return 0;
-    }
 }
 
 GF_EXPORT
@@ -2859,36 +774,25 @@ GF_BaseInterface *LoadInterface(u32 InterfaceType)
     plug->ChannelReleaseSLP = MPD_ChannelReleaseSLP;
     GF_SAFEALLOC(mpdin, GF_MPD_In);
     plug->priv = mpdin;
-    mpdin->mpd_thread = gf_th_new("MPD Segment Downloader Thread");
-    mpdin->dl_mutex = gf_mx_new("MPD Segment Downloader Mutex");
-    mpdin->mimeTypeForM3U8Segments = gf_strdup( M3U8_UNKOWN_MIME_TYPE );
+       mpdin->plug = plug;
     return (GF_BaseInterface *)plug;
 }
 
 GF_EXPORT
 void ShutdownInterface(GF_BaseInterface *bi)
 {
-    GF_InputService *ifcn = (GF_InputService*)bi;
-    if (ifcn->InterfaceType==GF_NET_CLIENT_INTERFACE) {
-        GF_MPD_In *mpdin = (GF_MPD_In*)ifcn->priv;
+       GF_MPD_In *mpdin;
+
+       if (bi->InterfaceType!=GF_NET_CLIENT_INTERFACE) return;
+
+       mpdin = (GF_MPD_In*) ((GF_InputService*)bi)->priv;
        assert( mpdin );
-        if (mpdin->mpd)
-            gf_mpd_del(mpdin->mpd);
-        mpdin->mpd = NULL;
-       if (mpdin->url)
-         gf_free(mpdin->url);
-       mpdin->url = NULL;
-       if (mpdin->mpd_thread)
-          gf_th_del(mpdin->mpd_thread);
-        mpdin->mpd_thread = NULL;
-       if (mpdin->dl_mutex)
-          gf_mx_del(mpdin->dl_mutex);
-        mpdin->dl_mutex = NULL;
-        if (mpdin->mimeTypeForM3U8Segments)
-               gf_free(mpdin->mimeTypeForM3U8Segments);
-       mpdin->mimeTypeForM3U8Segments = NULL;
-        gf_free(mpdin);
-       ifcn->priv = NULL;
-        gf_free(bi);
-    }
+
+       if (mpdin->dash)
+               gf_dash_del(mpdin->dash);
+
+       gf_free(mpdin);
+       gf_free(bi);
 }
+
+#endif //GPAC_DISABLE_DASH_CLIENT
index f9245ac12ed01c7ba537d0314d379e249b6fae38..e8ce986af6c227325af3d105819b3af5f950be42 100644 (file)
@@ -35,10 +35,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index b8b777746910dc23125d4da7dd6696176bee35af..a3e84210e39c771bfffb2eecc41ddf3a819d775d 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre, Cyril Concolato, Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / M2TS reader module
@@ -191,6 +191,9 @@ static GF_ObjectDescriptor *MP2TS_GetOD(M2TSIn *m2ts, GF_M2TS_PES *stream, char
                break;
        case GF_M2TS_AUDIO_LATM_AAC:
        case GF_M2TS_AUDIO_AAC:
+       case GPAC_OTI_AUDIO_AAC_MPEG2_MP:
+       case GPAC_OTI_AUDIO_AAC_MPEG2_LCP:
+       case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP:
                if (!dsi) {
                        /*turn on parsing to get AAC config
                                NB: we removed "no file regulation" since we may get broken files where PMT declares an AAC stream but no AAC PID is in the MUX
@@ -512,6 +515,9 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param)
        case GF_M2TS_EVT_SL_PCK:
                MP2TS_SendSLPacket(m2ts, param);
                break;
+       case GF_M2TS_EVT_EOS:
+               gf_term_on_sl_packet(m2ts->service, ((GF_M2TS_PES *)param)->user, NULL, 0, NULL, GF_EOS);
+               break;
        case GF_M2TS_EVT_AAC_CFG:
        {
                GF_M2TS_PES_PCK *pck = (GF_M2TS_PES_PCK*)param;
@@ -787,7 +793,7 @@ static GF_Err M2TS_ConnectService(GF_InputService *plug, GF_ClientService *serv,
        }
 
        opt = gf_modules_get_option((GF_BaseInterface *)m2ts->owner, "DSMCC", "Activated");
-       if (opt && !strcmp(opt, "true")) {
+       if (opt && !strcmp(opt, "yes")) {
                gf_m2ts_demux_dmscc_init(m2ts->ts);
        }
 
@@ -1155,8 +1161,8 @@ void DeleteM2TSReader(void *ifce)
                        gf_free(prog);
                }
                gf_list_del(m2ts->ts->requested_progs);
+               m2ts->ts->requested_progs = NULL;
        }
-       m2ts->ts->requested_progs = NULL;
        if( m2ts->ts->requested_pids ){
                count = gf_list_count(m2ts->ts->requested_pids);
                for (i = 0; i < count; i++) {
@@ -1164,8 +1170,8 @@ void DeleteM2TSReader(void *ifce)
                        gf_free(prog);
                }
                gf_list_del(m2ts->ts->requested_pids);
+               m2ts->ts->requested_pids = NULL;
        }
-       m2ts->ts->requested_pids = NULL;
        if (m2ts->network_buffer)
                gf_free(m2ts->network_buffer);
        m2ts->network_buffer = NULL;
index 41926816ec00d34325e0e5ead546a99e893d1d22..6ef0f04e2d1352b27758ed67af454d359ef90761 100644 (file)
@@ -34,11 +34,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_odf_dec-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index c2bd4c45ce4f559029b9a808f9510a7d18416a2b..d39bc9a05304d9da5017f67554e76268ce6f9048 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / OD decoder module
index 1e99a8b6915a1879e9115b2d6d159f06971403f0..76212f2f90e43f45e30cbef54b9ad67c02c0f4d1 100644 (file)
@@ -68,11 +68,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 522557f41e4223e5de9147521c7ed48608757ec8..a2e3409993fdb6eff9b97ca211e34003aca962ac 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / XIPH.org module
index 2b12b080b2efc98c353787c8711db02c23f881d0..82145a61421143a5e4ab996bf5784ff1cce74827 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / XIPH.org module
index c32c916e27534c85ca19b31199f90f3ec667f565..642a503c2b364e802bc843784fe1efdd131d8d98 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / XIPH.org module
index 43df4cf6282a1cc9076dcc475487b4e71d74a681..3c2e921f8c7026aa6465968ea30a5f7f84dbfa4e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / XIPH.org module
index 5200501cafb02a8a124e80ebc595ecc5d3d91c51..84861798cef4e7f6c95883434d983e875cc51bdc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / XIPH.org module
index b0b2e5bf7987fa512676c914c2271cf80eb1ecbb..8e1b2972d92199c0aac05ed094bb548c08475442 100644 (file)
@@ -34,10 +34,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 643a0a120e1de98bb10370eaa74bf18780b7de5d..49ae1d23a1ef96408b301410eac009e9de91e02b 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                                     All rights reserved
  *
- *  This file is part of GPAC / Dummy input module
+ *  This file is part of GPAC / OpenCV demo module
  *
  *  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
@@ -104,7 +104,7 @@ void detect_and_draw_objects(GF_InputSensorDevice *ifce, IplImage* image,
                              (theRealY+theRealHeight)*scale),
                      CV_RGB(0,255,0), 3, 8, 0 );
 
-       fprintf(stdout, "translation selon X : %d - translation selon Y : %d\n", (theRealX - prev_x0), (theRealY -prev_y0) );
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[OpenCV] translation selon X : %d - translation selon Y : %d\n", (theRealX - prev_x0), (theRealY -prev_y0) ));
 
        /*send data frame to GPAC*/
        {
index fa9e92383b44def417d671c66e50820ddb38f4af..42229918c41c6128bd5bb677aa6f8ee4828fd42e 100644 (file)
@@ -30,10 +30,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS)
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 041bb06362e88c7f2383b10816665955c5c747b6..0690d0e9054e45e69ccd91ce86df15949bd9748a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Telecom ParisTech 2010-
- *                             Author(s):      Jean Le Feuvre
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2010-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / OpenSVC Decoder module
index 2920b65454262e8408abb098ae2440b6e7eb75ed..8f24113252317790b3ab42cce33fcc1c4034aaf4 100644 (file)
@@ -32,10 +32,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)\r
 \r
 \r
-%.o: %.c\r
-       $(CC) $(CFLAGS) -c -o $@ $< \r
-\r
-\r
 clean: \r
        rm -f $(OBJS) ../../bin/gcc/$(LIB)\r
 \r
index f4c6f6c0054a27408f1a6eb4b75fe7871f56fa11..817da8b0b68affef5dafc13da471d5457128e7b5 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  *                     GPAC - Multimedia Framework C SDK\r
  *\r
- *                     Authors: Jean le Feuvre\r
- *                     Copyright (c) 2011-20XX ENST\r
+ *                     Authors: Jean Le Feuvre \r
+ *                     Copyright (c) Telecom ParisTech 2011-2012\r
  *                     All rights reserved\r
  *\r
  *  This file is part of GPAC / User Event Recorder sub-project\r
index 2deafcd663e2d35a5c1c79f76a40bbe9648f9268..3ed6f68b7985b7fa51889cb0620d2f37d24bd111 100644 (file)
@@ -40,11 +40,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_oss_audio-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static $(OSS_LDFLAGS)
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index ff6a5b6ff1af38b5e9253662a353239ca7aeceb6..c2430953b72ec82e025cb327f446b25f01d764bd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / linux_oss audio render module
index cdc337dc67943b1797c5f526d0eef03396ff9561..2dc9ba2bd5abaa93e728f268f16b37b52e0a3b4b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
@@ -497,7 +497,7 @@ void GPAC_FileMediaServer::ShareVirtualResource(const char *res_uri, const char
        GPAC_VirtualFile vres(the_uri, res_val, res_mime, temporary);
 
        m_VirtualFiles.Add(vres);
-       fprintf(stdout, "sharing virtual file %s as %s\n", res_uri, (const char *)the_uri);
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[UPnP] sharing virtual file %s as %s\n", res_uri, (const char *)the_uri));
 }
 
 NPT_Result 
@@ -518,7 +518,7 @@ GPAC_FileMediaServer::ServeVirtualFile(NPT_HttpResponse& response,
         return NPT_SUCCESS;
        }
 
-       fprintf(stdout, "Serving virtual file %s\n", vfile->m_Content.GetChars());
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[UPnP] Serving virtual file %s\n", vfile->m_Content.GetChars()));
 
        NPT_HttpEntity* entity = new NPT_HttpEntity();
        entity->SetContentLength(total_len);
index cdb2dfd15efc08a1515905f8eb951a6d9af7cc5c..160df3d37ca3ea75471fd83ca38388a4e649e766 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
index e91e133e6af7fd8b4efda0dad7699ad928efc96c..d029265a92936fdb96bba4e18afae9556ad521a7 100644 (file)
@@ -2,8 +2,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
index 5236f58555b73f273c37ce6ac769ebc1bdbf092b..4db8a6986d0dd14ed221009a18d10880a73b845a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
index 6feb58e884f77530d18c6ca040fc2af7ba955863..7ac22854d96c8e228ab9fe871960c662a4f9d8fe 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
index 3e8e996e10c8fa58949d23f507799fa4edfb2fbb..afb5d234efdb350cf1a68a5e8078d713d44a6d16 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
index e998ca38d1973427469de00a55dc47cc45875aaa..baa6be9bf09992e7024d9afa7dbc231519d3be8f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
@@ -525,8 +525,13 @@ void GF_UPnP::OnMediaServerAdd(PLT_DeviceDataReference& device, int added)
        LockJavascript(0);
 }
 
-static JSBool upnpdevice_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
+static SMJS_DECL_FUNC_PROP_GET(  upnpdevice_getProperty)
 {
+#ifdef USE_FFDEV_15
+       JSObject *obj = (JSObject *) __hobj;
+       jsid id = (jsid) __hid;
+#endif
+
        char *prop_name;
        GPAC_DeviceItem *dev = (GPAC_DeviceItem *)SMJS_GET_PRIVATE(c, obj);
        if (!dev) return JS_FALSE;
@@ -625,7 +630,7 @@ void GF_UPnP::OnDeviceAdd(GPAC_DeviceItem *item, int added)
 
        if (added) {
                item->js_ctx = m_pJSCtx;
-               item->obj = JS_NewObject(m_pJSCtx, &upnpGenericDeviceClass, 0, 0);
+               item->obj = JS_NewObject(m_pJSCtx, &upnpGenericDeviceClass._class, 0, 0);
                item->m_pUPnP = this;
                gf_js_add_root(m_pJSCtx, &item->obj, GF_JSGC_OBJECT);
                SMJS_SET_PRIVATE(item->js_ctx, item->obj, item);
@@ -641,8 +646,14 @@ void GF_UPnP::OnDeviceAdd(GPAC_DeviceItem *item, int added)
        LockJavascript(0);
 }
 
-static JSBool upnp_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
+static SMJS_DECL_FUNC_PROP_GET(  upnp_getProperty)
 {
+#ifdef USE_FFDEV_15
+       JSObject *obj = (JSObject *) __hobj;
+       jsid id = (jsid) __hid;
+#endif
+
+
        char *prop_name;
        GF_UPnP *upnp = (GF_UPnP *)SMJS_GET_PRIVATE(c, obj);
        if (!upnp) return JS_FALSE;
@@ -673,8 +684,12 @@ static JSBool upnp_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
        return JS_TRUE;
 }
 
-static JSBool upnp_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
+static SMJS_DECL_FUNC_PROP_SET(upnp_setProperty)
 {
+#ifdef USE_FFDEV_15
+       JSObject *obj = (JSObject *) __hobj;
+       jsid id = (jsid) __hid;
+#endif
        char *prop_name;
        GF_UPnP *upnp = (GF_UPnP *)SMJS_GET_PRIVATE(c, obj);
        if (!upnp) return JS_FALSE;
@@ -721,7 +736,7 @@ static JSBool SMJS_FUNCTION(upnp_get_device)
        if (!device) return JS_FALSE;
        if (!device->obj) {
                device->js_ctx = upnp->m_pJSCtx;
-               device->obj = JS_NewObject(upnp->m_pJSCtx, &upnp->upnpGenericDeviceClass, 0, 0);
+               device->obj = JS_NewObject(upnp->m_pJSCtx, &upnp->upnpGenericDeviceClass._class, 0, 0);
                device->m_pUPnP = upnp;
                gf_js_add_root(upnp->m_pJSCtx, &device->obj, GF_JSGC_OBJECT);
                SMJS_SET_PRIVATE(device->js_ctx, device->obj, device);
@@ -967,7 +982,7 @@ static JSBool SMJS_FUNCTION(upnp_get_renderer)
        }
        if (!mr) return JS_FALSE;
 
-       s_obj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, 0);
+       s_obj = JS_NewObject(c, &upnp->upnpDeviceClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, s_obj, upnp);
 
        JS_DefineProperty(c, s_obj, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, mr->m_device->GetFriendlyName()) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1087,7 +1102,7 @@ static JSBool SMJS_FUNCTION(upnp_server_get_file)
        server->m_BrowseResults->Get(id, mo);
        if (!mo) return JS_TRUE;
 
-       f_obj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, 0);
+       f_obj = JS_NewObject(c, &upnp->upnpDeviceClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, f_obj, mo);
 
        JS_DefineProperty(c, f_obj, "ObjectID", STRING_TO_JSVAL( JS_NewStringCopyZ(c, mo->m_ObjectID)), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1149,7 +1164,7 @@ static JSBool SMJS_FUNCTION(upnp_get_server)
                SMJS_FREE(c, uuid);
        }
        if (!ms) return JS_FALSE;
-       s_obj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, 0);
+       s_obj = JS_NewObject(c, &upnp->upnpDeviceClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, s_obj, upnp);
 
        JS_DefineProperty(c, s_obj, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ms->m_device->GetFriendlyName()) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1374,7 +1389,7 @@ static GPAC_GenericDevice *upnp_create_generic_device(GF_UPnP *upnp, JSObject*gl
        device->m_pUPnP = upnp;
        device->js_source = "";
 
-       device->obj = JS_NewObject(upnp->m_pJSCtx, &upnp->upnpDeviceClass, 0, global);
+       device->obj = JS_NewObject(upnp->m_pJSCtx, &upnp->upnpDeviceClass._class, 0, global);
        gf_js_add_root(upnp->m_pJSCtx, &device->obj, GF_JSGC_OBJECT);
 
        JS_DefineProperty(upnp->m_pJSCtx, device->obj, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(upnp->m_pJSCtx, name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1499,8 +1514,8 @@ Bool GF_UPnP::LoadJS(GF_TermExtJS *param)
        /*setup JS bindings*/
        JS_SETUP_CLASS(upnpClass, "UPNPMANAGER", JSCLASS_HAS_PRIVATE, upnp_getProperty, upnp_setProperty, JS_FinalizeStub);
 
-       JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpClass, 0, 0, upnpClassProps, upnpClassFuncs, 0, 0);
-       m_pObj = JS_DefineObject(m_pJSCtx, (JSObject*)param->global, "UPnP", &upnpClass, 0, 0);
+       GF_JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpClass, 0, 0, upnpClassProps, upnpClassFuncs, 0, 0);
+       m_pObj = JS_DefineObject(m_pJSCtx, (JSObject*)param->global, "UPnP", &upnpClass._class, 0, 0);
        SMJS_SET_PRIVATE(m_pJSCtx, m_pObj, this);
 
        JS_SETUP_CLASS(upnpDeviceClass, "UPNPAVDEVICE", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
@@ -1515,10 +1530,10 @@ Bool GF_UPnP::LoadJS(GF_TermExtJS *param)
                SMJS_FUNCTION_SPEC(0, 0, 0)
        };
        JS_SETUP_CLASS(upnpGenericDeviceClass, "UPNPDEVICE", JSCLASS_HAS_PRIVATE, upnpdevice_getProperty, JS_PropertyStub_forSetter, JS_FinalizeStub);
-       JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpGenericDeviceClass, 0, 0, upnpDeviceClassProps, upnpDeviceClassFuncs, 0, 0);
+       GF_JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpGenericDeviceClass, 0, 0, upnpDeviceClassProps, upnpDeviceClassFuncs, 0, 0);
        
        JS_SETUP_CLASS(upnpServiceClass, "UPNPSERVICEDEVICE", JSCLASS_HAS_PRIVATE, upnpservice_getProperty, JS_PropertyStub_forSetter, JS_FinalizeStub);
-       JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpServiceClass, 0, 0, 0, 0, 0, 0);
+       GF_JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpServiceClass, 0, 0, 0, 0, 0, 0);
 
        m_nbJSInstances=1;
        
@@ -1583,7 +1598,7 @@ static Bool upnp_process(GF_TermExt *termext, u32 action, void *param)
                if (!opt) {
 #ifdef GPAC_CONFIG_DARWIN
                        opt = "no";
-                       fprintf(stdout, "Disabling UPnP - to enable it, modify section [UPnP] key \"Enabled\" in /Users/yourname/.gpacrc");
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[UPnP] Disabling UPnP - to enable it, modify section [UPnP] key \"Enabled\" in /Users/yourname/.gpacrc"));
 #else
                        opt = "yes";
 #endif
index e7fceeff6224268ac9ce09eed4de44814624013c..74890ff7fac8912b6eb7e19de09813af6517d9b0 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
@@ -114,10 +114,10 @@ public:
        u32 m_nbJSInstances;
        JSContext *m_pJSCtx;
        JSObject *m_pObj;
-       JSClass upnpClass;
-       JSClass upnpDeviceClass;
-       JSClass upnpGenericDeviceClass;
-       JSClass upnpServiceClass;
+       GF_JSClass upnpClass;
+       GF_JSClass upnpDeviceClass;
+       GF_JSClass upnpGenericDeviceClass;
+       GF_JSClass upnpServiceClass;
 
        GF_List *m_Devices;
        u32 last_time, upnp_init_time;
@@ -140,7 +140,7 @@ public:
 };
 
 #ifdef GPAC_HAS_SPIDERMONKEY
-JSBool upnpservice_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp);
+SMJS_DECL_FUNC_PROP_GET( upnpservice_getProperty);
 #endif
 
 void format_time_string(char *str, Double dur);
index 962acf469213ca222fe947aa29e98a9c4a49eec5..33e077d056c104b931546c51f26c7c6a93370990 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
@@ -173,7 +173,6 @@ static JSBool SMJS_FUNCTION(upnp_service_set_listener)
        return JS_TRUE;
 }
 
-
 static JSBool SMJS_FUNCTION(upnp_service_set_action_listener)
 {
        PLT_ActionDesc *action;
@@ -247,8 +246,12 @@ static JSBool SMJS_FUNCTION(upnp_service_get_scpd)
        return JS_TRUE;
 }
 
-JSBool upnpservice_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
+SMJS_DECL_FUNC_PROP_GET( upnpservice_getProperty)
 {
+#ifdef USE_FFDEV_15
+       JSObject *obj = (JSObject *) __hobj;
+       jsid id = (jsid) __hid;
+#endif
        char *prop_name;
        GPAC_ServiceItem *service = (GPAC_ServiceItem *)SMJS_GET_PRIVATE(c, obj);
        if (!service) return JS_FALSE;
@@ -424,7 +427,7 @@ GPAC_ServiceItem *GPAC_DeviceItem::FindService(const char *type)
        
 #ifdef GPAC_HAS_SPIDERMONKEY
        serv->js_ctx = js_ctx;
-       serv->obj = JS_NewObject(serv->js_ctx, &m_pUPnP->upnpServiceClass, 0, obj);
+       serv->obj = JS_NewObject(serv->js_ctx, &m_pUPnP->upnpServiceClass._class, 0, obj);
        gf_js_add_root(serv->js_ctx, &serv->obj, GF_JSGC_OBJECT);
        SMJS_SET_PRIVATE(serv->js_ctx, serv->obj, serv);
        JS_DefineProperty(serv->js_ctx, serv->obj, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, service->GetServiceID()) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -640,7 +643,7 @@ NPT_Result GPAC_GenericController::OnActionResponse(NPT_Result res, PLT_ActionRe
 
                        GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s\n", (char *) action->GetActionDesc().GetName()));
 
-                       act_obj = JS_NewObject(serv->js_ctx, &item->m_pUPnP->upnpDeviceClass, 0, item->obj);
+                       act_obj = JS_NewObject(serv->js_ctx, &item->m_pUPnP->upnpDeviceClass._class, 0, item->obj);
                        SMJS_SET_PRIVATE(serv->js_ctx, act_obj, (void *)action.AsPointer() );
                        JS_DefineFunction(serv->js_ctx, act_obj, "GetArgumentValue", upnp_action_get_argument_value, 1, 0);
                        JS_DefineFunction(serv->js_ctx, act_obj, "GetErrorCode", upnp_action_get_error_code, 1, 0);
@@ -782,7 +785,7 @@ static JSBool SMJS_FUNCTION(upnp_service_set_state_variable)
 void GPAC_Service::SetupJS(JSContext *c, GF_UPnP *upnp, JSObject *parent)
 {
        m_pCtx = c;
-       m_pObj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, parent);
+       m_pObj = JS_NewObject(c, &upnp->upnpDeviceClass._class, 0, parent);
        gf_js_add_root(m_pCtx, &m_pObj, GF_JSGC_OBJECT);
        SMJS_SET_PRIVATE(c, m_pObj, this);
        JS_DefineFunction(c, m_pObj, "SetStateVariable", upnp_service_set_state_variable, 2, 0);
@@ -963,7 +966,7 @@ GPAC_GenericDevice::OnAction(PLT_ActionReference&          action,
 
        m_pUPnP->LockJavascript(1);
 
-       JSObject *js_action = JS_NewObject(m_pUPnP->m_pJSCtx, &m_pUPnP->upnpDeviceClass, 0, 0);
+       JSObject *js_action = JS_NewObject(m_pUPnP->m_pJSCtx, &m_pUPnP->upnpDeviceClass._class, 0, 0);
        argv[0] = OBJECT_TO_JSVAL(js_action);
        SMJS_SET_PRIVATE(m_pUPnP->m_pJSCtx, js_action, this);
        
index e49868440d371ec2ea0322e2081fafa8a2671322..70e38a975a0f7f34865cc410dcc427a9a0426cf2 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2009- Telecom ParisTech
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Platinum UPnP module 
index f5f8ddab50d4d5a09ec9192cd62f7639bef87ad9..cc49c88ffb3cab3ebf28eddbdaa354c34d552b8d 100644 (file)
@@ -18,7 +18,7 @@ LINKLIBS= -lgpac -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRendere
 LOCAL_LIB=../../bin/gcc -L../../extra_lib/lib/gcc
 
 #common objects
-OBJS=GPACFileMediaServer.o GPACMediaController.o GPACMediaRenderer.o GenericDevice.o GPACPlatinum.o
+OBJS=GPACFileMediaServer.o GPACMediaController.o GPACMediaRenderer.o GenericDevice.o GPACPlatinum.o 
 
 ifeq ($(CONFIG_JS),no)
 else
@@ -44,11 +44,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CXX) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)
 
-
-%.o: %.cpp
-       $(CXX) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index cc50a424db768d608adc156196db72cf30d9bc7a..639807d856a585ef16990768e7fd72e6fd3e0ee7 100644 (file)
@@ -27,11 +27,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -L/usr/lib -lpulse-simple
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 073fcc47b6147a39ef441918047042d45050b06d..ff09b94c6d138410c2aa42d5c25806b1948559ae 100644 (file)
@@ -1,8 +1,6 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
- *                                     All rights reserved
  *                     Copyright (c) Pierre Souchay 2008
  *
  *  History:
index ed6e0dd5c91a6074dc6e6b8c38390ff87157c77e..e518da1ff32db800aae42a7aacdfdf27c69fc0eb 100644 (file)
@@ -43,10 +43,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index ad73a88da58b446fb338f43e87eb8181a93a4ba2..875e94b1b9584081629cc9797da760f9d68a07e8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
index c514a1be6a4ed546661f0b4c980842a654b787a8..acbec25d80fa44b9f71fbf9a28ed4f7a93156709 100644 (file)
@@ -33,10 +33,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 2489fecb2189d479db5a217ada349f4bb89e1788..85c6360a363116d66c8da4eef3e64b4c2afbddd8 100644 (file)
@@ -1,6 +1,19 @@
 #include "ts_muxer.h"
 #include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
+
+#ifdef AVIO_FLAG_WRITE
+#include <libavutil/samplefmt.h>
+#define url_fopen avio_open
+#define url_fclose avio_close
+#define URL_WRONLY     AVIO_FLAG_WRITE
+#define av_write_header(__a)   avformat_write_header(__a, NULL)
+#define dump_format av_dump_format
+
+#define SAMPLE_FMT_S16 AV_SAMPLE_FMT_S16
+#endif
+
+
 #define STREAM_FRAME_RATE 25 /* 25 images/s */
 #define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
 #define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
@@ -87,8 +100,7 @@ static Bool ts_interleave_thread_run(void *param) {
                 audioKbps = audioSize * 8000 / (now-start) / 1024;
                 audioSize = videoSize = 0;
                 start = now;
-                printf("\rPTS audio="LLU" ("LLU"kbps), video="LLU" ("LLU"kbps)", audio_pts, audioKbps, video_pts, videoKbps);
-                fflush(stdout);
+                GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("\rPTS audio="LLU" ("LLU"kbps), video="LLU" ("LLU"kbps)", audio_pts, audioKbps, video_pts, videoKbps));
             }
         }
         /* write interleaved audio and video frames */
@@ -222,13 +234,17 @@ GF_AbstractTSMuxer * ts_amux_new(GF_AVRedirect * avr, u32 videoBitrateInBitsPerS
 
     }
     //av_set_pts_info(ts->audio_st, 33, 1, audioBitRateInBitsPerSec);
-    /* set the output parameters (must be done even if no
+
+#ifndef AVIO_FLAG_WRITE
+       /* set the output parameters (must be done even if no
        parameters). */
     if (av_set_parameters(ts->oc, NULL) < 0) {
         fprintf(stderr, "Invalid output format parameters\n");
         return NULL;
     }
-    dump_format(ts->oc, 0, avr->destination, 1);
+#endif
+       
+       dump_format(ts->oc, 0, avr->destination, 1);
     GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] DUMPING to %s...\n", ts->destination));
 
     if (avcodec_open(ts->video_st->codec, avr->videoCodec) < 0) {
@@ -325,7 +341,7 @@ Bool ts_encode_audio_frame(GF_AbstractTSMuxer * ts, uint8_t * data, int encoded,
     pkt->stream_index= ts->audio_st->index;
     pkt->data = data;
     pkt->size = encoded;
-    //printf("AUDIO PTS="LLU" was: "LLU" (%p)\n", pkt->pts, pts, pl);
+    //fprintf(stderr, "AUDIO PTS="LLU" was: "LLU" (%p)\n", pkt->pts, pts, pl);
     gf_mx_p(ts->audioMx);
     if (!ts->audioPackets)
         ts->audioPackets = pl;
@@ -360,7 +376,7 @@ Bool ts_encode_video_frame(GF_AbstractTSMuxer* ts, uint8_t* data, int encoded) {
     pkt->stream_index= ts->video_st->index;
     pkt->data= data;
     pkt->size= encoded;
-    //printf("VIDEO PTS="LLU" was: "LLU" (%p)\n", pkt->pts, ts->video_st->codec->coded_frame->pts, pl);
+    //fprintf(stderr, "VIDEO PTS="LLU" was: "LLU" (%p)\n", pkt->pts, ts->video_st->codec->coded_frame->pts, pl);
     gf_mx_p(ts->videoMx);
     if (!ts->videoPackets)
         ts->videoPackets = pl;
index 9a657a99ddb32fdee373d2c8b84620ce49d49d22..8db261924b8f05ffe9659df77a4ae7c16d5b5001 100644 (file)
@@ -74,18 +74,18 @@ static GF_Err void_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param)
         /*    case GF_ESI_INPUT_DATA_PULL:
                 gf_mx_p(ts->encodingMutex);
                 if (ts->frameTimeEncoded > ts->frameTimeSentOverTS) {
-                    //printf("Data PULL, avr=%p, avr->video=%p, encoded="LLU", sent over TS="LLU"\n", avr, &avr->video, avr->frameTimeEncoded, avr->frameTimeSentOverTS);
+                    //fprintf(stderr, "Data PULL, avr=%p, avr->video=%p, encoded="LLU", sent over TS="LLU"\n", avr, &avr->video, avr->frameTimeEncoded, avr->frameTimeSentOverTS);
                     ts->video->output_ctrl( ts->video, GF_ESI_OUTPUT_DATA_DISPATCH, &(ts->videoCurrentTSPacket));
                     ts->frameTimeSentOverTS = ts->frameTime;
                 } else {
-                    //printf("Data PULL IGNORED : encoded = "LLU", sent on TS="LLU"\n", avr->frameTimeEncoded, avr->frameTimeSentOverTS);
+                    //fprintf(stderr, "Data PULL IGNORED : encoded = "LLU", sent on TS="LLU"\n", avr->frameTimeEncoded, avr->frameTimeSentOverTS);
                 }
                 gf_mx_v(avr->encodingMutex);
                 break;*/
     case GF_ESI_INPUT_DATA_RELEASE:
         break;
     default:
-        printf("Asking unknown : %u\n", act_type);
+        fprintf(stderr, "Asking unknown : %u\n", act_type);
     }
     return GF_OK;
 }
@@ -100,11 +100,8 @@ Bool ts_encode_video_frame(GF_AbstractTSMuxer * ts, AVFrame * encodedFrame, uint
         ts->videoCurrentTSPacket.dts = ts->videoCurrentTSPacket.cts = gf_m2ts_get_sys_clock(ts->muxer);
         ts->videoCurrentTSPacket.data = data;
         ts->videoCurrentTSPacket.data_len = encoded;
-        //printf("\rSending frame DTS="LLU", CTS="LLU", len=%u, FPS=%u, delta=%u...", ts->videoCurrentTSPacket.dts, avr->videoCurrentTSPacket.cts, avr->videoCurrentTSPacket.data_len, fps, currentFrameTimeProcessed - lastEncodedFrameTime);
-        fflush(stdout);
         ts->videoCurrentTSPacket.flags = GF_ESI_DATA_HAS_CTS | GF_ESI_DATA_HAS_DTS;
         //if (ts_packets_sent == 0) {
-        //    printf("First Packet !\n");
         ts->videoCurrentTSPacket.flags|=GF_ESI_DATA_AU_START|GF_ESI_DATA_AU_END ;
         //}
         void_input_ctrl(ts->video, GF_ESI_INPUT_DATA_PULL, NULL);
index b89a490454b186b56da5dab137818872cc09b47d..0dd73ab0d904e966799d39060dbb70c102ede566 100644 (file)
@@ -58,8 +58,9 @@
 #include "ts_muxer.h"
 
 #define USE_GPAC_MPEG2TS
-#undef USE_GPAC_MPEG2TS
+#undef  USE_GPAC_MPEG2TS
 
+//#define MULTITHREAD_REDIRECT_AV
 #define REDIRECT_AV_AUDIO_ENABLED 1
 
 #ifdef USE_GPAC_MPEG2TS
@@ -149,10 +150,10 @@ static Bool audio_encoding_thread_run(void *param)
         goto exit;
     }
 
-    printf("******* Audio Codec Context = %d/%d, start="LLU", frame_size=%u\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start, ctx->frame_size);
+    fprintf(stderr, "******* Audio Codec Context = %d/%d, start="LLU", frame_size=%u\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start, ctx->frame_size);
     samplesReaden = ctx->frame_size * ctx->channels;
 
-    //printf("SETUP input sample size=%u, output samplesize=%u, buffsize=%u, samplesReaden=%u\n", ctx->input_sample_size, ctx->frame_size, sizeof(outbuf), samplesReaden);
+    //fprintf(stderr, "SETUP input sample size=%u, output samplesize=%u, buffsize=%u, samplesReaden=%u\n", ctx->input_sample_size, ctx->frame_size, sizeof(outbuf), samplesReaden);
     // 2 chars are needed for each short
     toRead = samplesReaden * 2;
     inBuffSize = toRead;
@@ -242,7 +243,7 @@ static Bool video_encoding_thread_run(void *param)
     if (!ctx) {
         goto exit;
     }
-    printf("******* Video Codec Context = %d/%d, start="LLU"\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start);
+    fprintf(stderr, "******* Video Codec Context = %d/%d, start="LLU"\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start);
     while (avr->is_running) {
         {
             gf_mx_p(avr->frameMutex);
@@ -257,7 +258,7 @@ static Bool video_encoding_thread_run(void *param)
             assert( currentFrameTimeProcessed != avr->frameTime);
             currentFrameTimeProcessed = avr->frameTime;
             {
-                avpicture_fill ( ( AVPicture * ) avr->RGBpicture, avr->frame, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight );
+                               avpicture_fill ( ( AVPicture * ) avr->RGBpicture, avr->frame, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight );
                 assert( avr->swsContext );
                 sws_scale ( avr->swsContext,
 #ifdef USE_AVCODEC2
@@ -278,20 +279,20 @@ static Bool video_encoding_thread_run(void *param)
                 if (avr->encode)
                 {
                     int written;
-                    //u32 sysclock = gf_sys_clock();
+                    u32 sysclock_begin = gf_sys_clock(), sysclock_end=0;
                     avr->YUVpicture->pts = currentFrameTimeProcessed;
-                    //printf("Encoding frame PTS="LLU", frameNum=%u, time=%u...", avr->YUVpicture->pts, avr->YUVpicture->coded_picture_number, currentFrameTimeProcessed);
-                    written = avcodec_encode_video ( ctx, avr->videoOutbuf, avr->videoOutbufSize, avr->YUVpicture );
-                    //ctx->coded_frame->pts = currentFrameTimeProcessed;
-                    if ( written < 0 )
-                    {
+                    written = avcodec_encode_video ( ctx, avr->videoOutbuf, avr->videoOutbufSize, avr->YUVpicture);
+                                       sysclock_end = gf_sys_clock();
+                    GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("Encoding frame PTS="LLD", frameNum=%u, time="LLU", size=%d\t in %ums\n", avr->YUVpicture->pts, avr->YUVpicture->coded_picture_number, currentFrameTimeProcessed, written, sysclock_end-sysclock_begin));
+                    ctx->coded_frame->pts = currentFrameTimeProcessed;
+
+                    if (written<0) {
                         GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while encoding video frame =%d\n", written ) );
-                    } else
-                        if ( written > 0 )
-                        {
+                                       } else {
+                        if (written>0)
                             ts_encode_video_frame(avr->ts_implementation, avr->videoOutbuf, written);
-                        }
-                    lastEncodedFrameTime = currentFrameTimeProcessed;
+                        lastEncodedFrameTime = currentFrameTimeProcessed;
+                                       }
                 }
             }
         }
@@ -335,7 +336,7 @@ static Bool start_if_needed(GF_AVRedirect *avr) {
 #endif /* AVR_DUMP_RAW_AVI */
     GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Initializing...\n"));
     if (!avr->pcmAudio)
-        avr->pcmAudio = gf_ringbuffer_new(32768);
+        avr->pcmAudio = gf_ringbuffer_new(48000*2*2); //1s of 16b stereo 48000Hz
 
     /* Setting up the video encoding ... */
     {
@@ -460,6 +461,7 @@ static void avr_on_video_frame ( void *udta, u32 time )
     GF_Err e;
     GF_VideoSurface fb;
     GF_AVRedirect *avr = ( GF_AVRedirect * ) udta;
+
     if (start_if_needed(avr))
         return;
     gf_mx_p(avr->frameMutex);
@@ -469,20 +471,25 @@ static void avr_on_video_frame ( void *udta, u32 time )
         GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error grabing frame buffer %s\n", gf_error_to_string ( e ) ) );
         return;
     }
-    /*convert frame*/
-    for ( i=0; i<fb.height; i++ )
-    {
-        char *dst = avr->frame + i * fb.width * 3;
-        char *src = fb.video_buffer + i * fb.pitch_y;
-        for ( j=0; j<fb.width; j++ )
-        {
-            dst[0] = src[2];
-            dst[1] = src[1];
-            dst[2] = src[0];
-            src+=4;
-            dst += 3;
-        }
-    }
+    /*convert colorspace for input frame*/
+       if (fb.pixel_format == GF_PIXEL_ARGB) {
+               /*ARGB -> RGB24*/
+               for (i=0; i<fb.height; i++) {
+                       char *dst = avr->frame + i * fb.width * 3;
+                       char *src = fb.video_buffer + i * fb.pitch_y;
+                       for (j=0; j<fb.width; j++) {
+                               dst[0] = src[2];
+                               dst[1] = src[1];
+                               dst[2] = src[0];
+                               src+=4;
+                               dst += 3;
+                       }
+               }
+       } else {
+               assert(fb.pixel_format == GF_PIXEL_RGB_24);
+               for (i=0; i<fb.height; i++)
+                       memcpy(avr->frame+i*fb.width*3, fb.video_buffer+i*fb.pitch_y, fb.width*3);
+       }
     avr->frameTime = time;
     gf_mx_v(avr->frameMutex);
     gf_sc_release_screen_buffer ( avr->term->compositor, &fb );
@@ -530,7 +537,7 @@ static Bool ts_thread_run(void *param)
         gf_sleep(1);
         gf_mx_p(avr->tsMutex);
     }
-    printf("avr->frameTimeEncoded="LLU"\n", avr->frameTimeEncoded);
+    fprintf(stderr, "avr->frameTimeEncoded="LLU"\n", avr->frameTimeEncoded);
 
     while (avr->is_running) {
         e = sendTSMux(avr);
@@ -610,8 +617,10 @@ static Bool avr_process ( GF_TermExt *termext, u32 action, void *param )
             GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("Failed to lock global resource 'AVRedirect:output', another GPAC instance must be running, disabling AVRedirect\n"));
             return 0;
         }
+#ifndef AVIO_FLAG_WRITE
         /* must be called before using avcodec lib */
         avcodec_init();
+#endif
 
         /* register all the codecs */
         avcodec_register_all();
@@ -680,7 +689,7 @@ static Bool avr_process ( GF_TermExt *termext, u32 action, void *param )
                     char *endPtr = NULL;
                     unsigned int x = strtoul(opt, &endPtr, 10);
                     if (endPtr == opt || x > 65536) {
-                        printf("Failed to parse : %s\n", opt);
+                        fprintf(stderr, "Failed to parse : %s\n", opt);
                         opt = NULL;
                     } else
                         avr->udp_port = (u16) x;
index ed25165d7080856ae6f464cb691ac7b9dd65350e..6009968a36dc356e4218ee9b67b970af6bc56012 100644 (file)
@@ -36,10 +36,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index e1a94a74505f05c5991d45bf0f577869483bd0c5..d11c25b57d140333d76839e5ff2f73a8a2011c9a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index 1ce20ba0796222c9b13aba54dc90a5e9e7d3d317..26af97da120fbeb13bc58a99290751b7ecfd6302 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index 2f67cf9b71a4eb4d6eb369708cd43992e39f0e6f..de08369ec6d1a21b53cd1ae855a5cb79a516acb5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index e05e3d03db4b1ba06a4b01bc6b34d40f2ce83fc9..1a90d524635f55cc29bc70648964cbc07dc47bc8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index e7bf1f07684f4848e2d9a56e5e4745a4f6cd059e..d420ae35d277b08bbcb8a5c03caa39be6502d5e6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index ec61e42cea0ed6c042f1154e9ae818747f0bbeb3..7ea4d35c0136a456da9796b8888eea3942546cde 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index 6cb2a5c94997a534e11fd2c3f965706c02814e97..29a61ce094548c0cf3ae783b00f7e6344a6c3e9e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
index b28709b2b9eece5f4f5e0437bf28538aefb98ccf..a60c433edc63a98b8e888b12a90cd7cc9b9c8c56 100644 (file)
@@ -31,10 +31,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index a4ec5c83941bbc5f81279af3f6d5c5a7c0e6c47a..c39880c3e7ee319d08008211f2d6a529136780bb 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  *                     GPAC - Multimedia Framework C SDK\r
  *\r
- *                     Copyright (c) Telecom ParisTech 2010-\r
- *                             Author(s):      Jean Le Feuvre\r
+ *                     Authors: Jean Le Feuvre \r
+ *                     Copyright (c) Telecom ParisTech 2010-2012\r
  *                                     All rights reserved\r
  *\r
  *  This file is part of GPAC / OpenSVC Decoder module\r
index a3ed68959d48d3174c3014d183b1dfc78d640901..4dc01105f80b142fdc44433d53ce3453d0d3fec0 100644 (file)
@@ -36,10 +36,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index bfbccc9ceed40ad62db38531947714d4513b40c8..3be84fb8e3b212770f296404df21e7a0f5041a6b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SAF reader module
@@ -119,7 +119,7 @@ static void SAF_Regulate(SAFIn *read)
                        if (com.buffer.occupancy) min_occ = MIN(min_occ, com.buffer.occupancy - ch->buffer_min);
                }
                if (min_occ == (u32) -1) break;
-               //fprintf(stdout, "Regulating SAF demux - sleeping for %d ms\n", min_occ);
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[SAF] Regulating SAF demux - sleeping for %d ms\n", min_occ));
                gf_sleep(min_occ);
        }
 }
index 4cbc60d369f086625e61d92dc3da3792d0f1784b..ba84dda6d9131276abebe3a4ab87a11c3bcf1219 100644 (file)
@@ -33,10 +33,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) -L../../bin/gcc -lgpac
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index df74c0ae7b78e4c981ed43d9b433964fbb7c9461..b768886f2e9b38df61c423c05cf03c3bfded5b98 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SDL audio and video module
index de25c399a4813e4d1542c9adb36eab0bb8467c62..96dc08c287dfccb935606d62b5f8bef8612d388b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DirectX audio and video render module
index 1be2a125d2d6b6dd0d28733c2398c0fcd9745c87..9b02cd3ef13aea4706df6b89d88631f2c6b36d22 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SDL audio and video module
index 4fa2e944a5aeb83ed8a90e008f504ddc8bb37087..b34a759bd4cde1595c1a5b068d68b34992231afe 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SDL audio and video module
index 14f892d8b13c06a29bae4c7848bb58a5d7c76fa0..5daa6f3d5012c0c8b87d01e51e0f4db60f2a4712 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre - Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SDL audio and video module
index b6b91dcab3a69f62e4bf59347cb0ce01389adb60..b41481d87ac91c229261fffa8dc180f1c218b4f2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SDL audio and video module
index 740dad01abf0742a9511b1c4ae97819249331df3..4476cfe2238eb340ab132f020caf77a7c1633b26 100644 (file)
@@ -40,11 +40,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_soft_raster-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 34d128f6486cc2714f3926943bb437753cd23569..8ea59f441b9b292897f0debb26c498b8b6f86100 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / software 2D rasterizer module
index 7e8f9964d62d8f8b9183c6ebcd365c793464db7e..9527d9ccc00418a201f819fa6ae9ad6c11640cae 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Rendering sub-project
index f3ab03d3e1d0309c7324347286f26c3104d58020..e593555d11c5f74692fcd4dc1ec4dd3e9b89309d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / software 2D rasterizer module
index d3951864ff6ae769c5176dfd3ad6ad27978b930b..7867fb75a82e9161a8e573d516ca378c379773f0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / software 2D rasterizer module
index 34fe84674936a0dad0a722f7e3f39709e01b11b1..9f2d404e1c1cd771dd4dc7dba951da95224cb2e8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / software 2D rasterizer module
index 70eaed3ccb9b4930871bf1f20187488c8f46c62c..b02539b3faebfad5c5c121f60ebb4e6404235e76 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / software 2D rasterizer module
index b860c8a6efde43e277878a03c4daba46b6505e6e..3fe0ad7750045e428d7fa46b28fea4377dfe0dd2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / software 2D rasterizer module
index f5cccddd761b2490bad7ca66fb61a8bff5d4e6cd..c5c8ec2178a98a38cc17147ef0161dbf3811c6fe 100644 (file)
@@ -39,11 +39,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_svg_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static -lz
 endif
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index c810e25d95d839f01f127bb0e9987c0063bb509b..6f84531ec0c15bb555830acb62d56843a8c41e35 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Loader module
index 67c30a205d933fd49944a73daab64dc1b7c79654..74c9a4e264d74e6c052ca4cf470e4319e7316827 100644 (file)
@@ -35,10 +35,6 @@ ifeq ($(STATICBUILD),yes)
 endif
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index a674431e05c0b1f5c15978789ff7a1eb70effff1..78929c1592938107402c931dd633d4fa0dc66758 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / 3GPP/MPEG4 timed text module
index d4a8c5c7009bf221418f32deedfd2e8aa7e266d5..ca3282953539050fd14bf74c5684af1742183846 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / 3GPP/MPEG4 timed text module
index 41a819956fc01d31f2f1ddc17b46027ebccdd7a8..d9317cd64a977533133b609da4eff645980ec1c0 100644 (file)
@@ -37,10 +37,6 @@ $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS)
 
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index b34dd7c667358d462d11610c05dacd0107e8eb2c..3432c5ffe37f56affd3bbc6cc2aa92e64b31039f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2007-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / User Event Recorder sub-project
index 7863caf24a9b2241cb44a75ca0703994e40d4044..287e95d8ce07c4cceece7ab5fc45977226e426ec 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK\r
  *\r
  *                     Authors: Cyril Concolato\r
- *                     Copyright (c) 2010 Telecom ParisTech\r
+ *                     Copyright (c) Telecom ParisTech 2010-2012\r
  *                     All rights reserved\r
  *\r
  *  This file is part of GPAC / Test Suite Validator Recorder sub-project\r
index bd302c6c6be9b5b84a02beb934acf44a553c259f..57338664e9640782df4ac6bdb98a62dfa5837291 100644 (file)
@@ -29,11 +29,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) 
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 3e243f1237815a07e231ed7d368a3f8de0693bc0..49edf617ecc6e9ecb3f20fbfb3cfd8d86df7a79c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / wave audio render module
index edb93f884523f9fb954d8ffa66b309ee90fdcdc1..f0543373b967ce92de112516682a63aeb7628995 100644 (file)
@@ -49,11 +49,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) $(LOCAL_LIB) $(LINKLIBS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 71f0e6991e761f6bfbd16d4808e13eff76953320..c1acc82022e45af6e40201d0631e966d93b08bde 100644 (file)
@@ -1176,7 +1176,7 @@ int makedir (newdir)
       *p = 0;
       if ((mymkdir(buffer) == -1) && (errno == ENOENT))
         {
-          printf("couldn't create directory %s\n",buffer);
+          fprintf(stderr, "couldn't create directory %s\n",buffer);
           gf_free(buffer);
           return 0;
         }
@@ -1211,7 +1211,7 @@ int do_extract_currentfile(uf)
 
     if (err!=UNZ_OK)
     {
-        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+        fprintf(stderr, "error %d with zipfile in unzGetCurrentFileInfo\n",err);
         return err;
     }
 
@@ -1219,7 +1219,7 @@ int do_extract_currentfile(uf)
     buf = (void*)gf_malloc(size_buf);
     if (buf==NULL)
     {
-        printf("Error allocating memory\n");
+        fprintf(stderr, "Error allocating memory\n");
         return UNZ_INTERNALERROR;
     }
 
@@ -1234,7 +1234,7 @@ int do_extract_currentfile(uf)
     if ((*filename_withoutpath)=='\0')
     {
 #ifndef _WIN32_WCE
-               printf("creating directory: %s\n",filename_inzip);
+               fprintf(stderr, "creating directory: %s\n",filename_inzip);
            mymkdir(filename_inzip);
 #endif
        }
@@ -1248,7 +1248,7 @@ int do_extract_currentfile(uf)
                err = unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/);
         if (err!=UNZ_OK)
         {
-            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+            fprintf(stderr, "error %d with zipfile in unzOpenCurrentFilePassword\n",err);
         }
 
         if ((skip==0) && (err==UNZ_OK))
@@ -1267,26 +1267,26 @@ int do_extract_currentfile(uf)
 
             if (fout==NULL)
             {
-                printf("error opening %s\n",write_filename);
+                fprintf(stderr, "error opening %s\n",write_filename);
             }
         }
 
         if (fout!=NULL)
         {
-            printf(" extracting: %s\n",write_filename);
+            fprintf(stderr, " extracting: %s\n",write_filename);
 
             do
             {
                 err = unzReadCurrentFile(uf,buf,size_buf);
                 if (err<0)
                 {
-                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
+                    fprintf(stderr, "error %d with zipfile in unzReadCurrentFile\n",err);
                     break;
                 }
                 if (err>0)
                     if (gf_fwrite(buf,err,1,fout)!=1)
                     {
-                        printf("error in writing extracted file\n");
+                        fprintf(stderr, "error in writing extracted file\n");
                         err=UNZ_ERRNO;
                         break;
                     }
@@ -1301,7 +1301,7 @@ int do_extract_currentfile(uf)
             err = unzCloseCurrentFile (uf);
             if (err!=UNZ_OK)
             {
-                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+                fprintf(stderr, "error %d with zipfile in unzCloseCurrentFile\n",err);
             }
         }
         else
@@ -1324,20 +1324,20 @@ int gf_unzip_archive(const char *zipfilename, const char *dirname)
     uf = unzOpen2(zipfilename, NULL);
     if (uf==NULL)
     {
-        printf("Cannot open %s\n", zipfilename);
+        fprintf(stderr, "Cannot open %s\n", zipfilename);
         return 1;
     }
 #ifndef _WIN32_WCE
        if (chdir(dirname)) 
     {
-      printf("Error changing into %s, aborting\n", dirname);
+      fprintf(stderr, "Error changing into %s, aborting\n", dirname);
       exit(-1);
     }
 #endif
 
     err = unzGetGlobalInfo (uf,&gi);
     if (err!=UNZ_OK)
-        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+        fprintf(stderr, "error %d with zipfile in unzGetGlobalInfo \n",err);
 
     for (i=0;i<gi.number_entry;i++)
     {
@@ -1349,7 +1349,7 @@ int gf_unzip_archive(const char *zipfilename, const char *dirname)
             err = unzGoToNextFile(uf);
             if (err!=UNZ_OK)
             {
-                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                fprintf(stderr, "error %d with zipfile in unzGoToNextFile\n",err);
                 break;
             }
         }
index 7a87d28881c88186e4b0b417ba15b25c9b4d6ce0..72c1c60bc8c55133a0206d8dfdab438c1f275a12 100644 (file)
@@ -20,7 +20,7 @@
 //
 //This copyright notice must be included in all copies or derivative works.
 //
-//Copyright (c) 2009.
+//Copyright (c) 2009 Telecom ParisTech.
 //
 // Alternatively, this software module may be redistributed and/or modified
 //  it under the terms of the GNU Lesser General Public License as published by
index 58d986bab7f97d36b1d7cf357f2800fcc90c5427..dc62a38c73af26ccf09b490278af64ba11ad3d17 100644 (file)
@@ -20,7 +20,7 @@
 //
 //This copyright notice must be included in all copies or derivative works.
 //
-//Copyright (c) 2009.
+//Copyright (c) 2009 Telecom ParisTech.
 //
 // Alternatively, this software module may be redistributed and/or modified
 //  it under the terms of the GNU Lesser General Public License as published by
@@ -158,7 +158,7 @@ static JSBool SMJS_FUNCTION(widget_message_handler_factory)
        for (i=0; i<count; i++) {
                GF_WidgetMessage *msg = gf_list_get(bifce->ifce->messages, i);
                if (!strcmp(msg->name, msg_name)) {
-                       JSObject *an_obj = JS_NewObject(c, &bifce->wid->widget->wm->widgetAnyClass, 0, 0);
+                       JSObject *an_obj = JS_NewObject(c, &bifce->wid->widget->wm->widgetAnyClass._class, 0, 0);
                        SMJS_SET_PRIVATE(c, an_obj, msg);
                        JS_DefineProperty(c, an_obj, "msgName", STRING_TO_JSVAL( JS_NewStringCopyZ(c, msg->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                        JS_DefineProperty(c, an_obj, "interfaceHandler", OBJECT_TO_JSVAL( obj ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -227,7 +227,7 @@ static JSBool SMJS_FUNCTION(widget_invoke_message_reply)
 static void widget_interface_js_bind(JSContext *c, GF_WidgetInterfaceInstance *ifce)
 {
        if (!ifce->obj) {
-               ifce->obj = JS_NewObject(c, &ifce->wid->widget->wm->widgetAnyClass, 0, 0);
+               ifce->obj = JS_NewObject(c, &ifce->wid->widget->wm->widgetAnyClass._class, 0, 0);
                SMJS_SET_PRIVATE(c, ifce->obj, ifce);
                gf_js_add_root(c, &ifce->obj, GF_JSGC_OBJECT);
                JS_DefineProperty(c, ifce->obj, "type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->ifce->type) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -327,8 +327,8 @@ void widget_on_interface_bind(GF_WidgetInterfaceInstance *ifce, Bool unbind)
 
 }
 
-JSBool widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *rval)
-{
+SMJS_FUNC_PROP_GET(widget_getProperty)
+
        const char *opt;
        char *prop_name;
        GF_WidgetInstance *wid = (GF_WidgetInstance *)SMJS_GET_PRIVATE(c, obj);
@@ -339,41 +339,41 @@ JSBool widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *
        if (!prop_name) return JS_FALSE;
 
        if (!strcmp(prop_name, "viewMode")) {
-               *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "floating") );
+               *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "floating") );
        }
        else if (!strcmp(prop_name, "locale")) {
                opt = gf_cfg_get_key(wid->widget->wm->term->user->config, "Systems", "Language2CC");
                if (!opt) opt = "und";
-               *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, opt) );
+               *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, opt) );
        }
        else if (!strcmp(prop_name, "identifier")) {
-               if (wid->widget->identifier) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->identifier) );
+               if (wid->widget->identifier) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->identifier) );
        }
        else if (!strcmp(prop_name, "authorName")) {
-               if (wid->widget->authorName) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorName) );
+               if (wid->widget->authorName) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorName) );
        }
        else if (!strcmp(prop_name, "authorEmail")) {
-               if (wid->widget->authorEmail) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorEmail) );
+               if (wid->widget->authorEmail) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorEmail) );
        }
        else if (!strcmp(prop_name, "authorHref")) {
-               if (wid->widget->authorHref) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorHref) );
+               if (wid->widget->authorHref) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorHref) );
        }
        else if (!strcmp(prop_name, "name")) {
-               if (wid->widget->name) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->name) );
+               if (wid->widget->name) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->name) );
        }
        else if (!strcmp(prop_name, "version")) {
-               if (wid->widget->version) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->version) );
+               if (wid->widget->version) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->version) );
        }
        else if (!strcmp(prop_name, "description")) {
-               if (wid->widget->description) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->description) );
+               if (wid->widget->description) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->description) );
        }
        else if (!strcmp(prop_name, "width")) {
                opt = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, "width");
-               *rval = INT_TO_JSVAL( (opt ? atoi(opt) : 0) );
+               *vp = INT_TO_JSVAL( (opt ? atoi(opt) : 0) );
        }
        else if (!strcmp(prop_name, "height")) {
                opt = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, "height");
-               *rval = INT_TO_JSVAL( (opt ? atoi(opt) : 0) );
+               *vp = INT_TO_JSVAL( (opt ? atoi(opt) : 0) );
        }
        else if (!strcmp(prop_name, "preferences")) {
        }
@@ -381,8 +381,11 @@ JSBool widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *
        return JS_TRUE;
 }
 
-JSBool widget_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+SMJS_FUNC_PROP_SET( widget_setProperty) 
+
+       /*avoids GCC warning*/
+       if (!obj) obj = NULL;
+       if (!id) id=0;
        return JS_TRUE;
 }
 
@@ -431,10 +434,10 @@ void widget_load(GF_WidgetManager *wm, GF_SceneGraph *scene, JSContext *c, JSObj
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
 
-               JS_InitClass(c, global, 0, &wm->widgetClass, 0, 0,widgetClassProps, widgetClassFuncs, 0, 0);
+               GF_JS_InitClass(c, global, 0, &wm->widgetClass, 0, 0,widgetClassProps, widgetClassFuncs, 0, 0);
 
                
-               wi->scene_obj = JS_DefineObject(c, global, "widget", &wm->widgetClass, 0, 0);
+               wi->scene_obj = JS_DefineObject(c, global, "widget", &wm->widgetClass._class, 0, 0);
                //JS_AliasProperty(c, global, "widget", "MPEGWidget");
                SMJS_SET_PRIVATE(c, wi->scene_obj, wi);
                /*and remember the script*/
index 058cc8b5734df35144cc3eaf1a901fd6964d8c28..9e25943288d1d7dbba2a8f27fb3c899136a67efa 100644 (file)
@@ -20,7 +20,7 @@
 //
 //This copyright notice must be included in all copies or derivative works.
 //
-//Copyright (c) 2009.
+//Copyright (c) 2009 Telecom ParisTech.
 //
 // Alternatively, this software module may be redistributed and/or modified
 //  it under the terms of the GNU Lesser General Public License as published by
@@ -1387,7 +1387,7 @@ static JSBool SMJS_FUNCTION(wm_widget_get_message_param)
        }
 
        if (par) {
-               JSObject *obj = JS_NewObject(c, &msg->ifce->content->widget->wm->widgetAnyClass, 0, 0);
+               JSObject *obj = JS_NewObject(c, &msg->ifce->content->widget->wm->widgetAnyClass._class, 0, 0);
                SMJS_SET_PRIVATE(c, obj, par);
                JS_DefineProperty(c, obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, par->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                JS_DefineProperty(c, obj, "is_input", BOOLEAN_TO_JSVAL( (par->type == GF_WM_PARAM_OUTPUT) ? JS_FALSE : JS_TRUE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1432,7 +1432,7 @@ static JSBool SMJS_FUNCTION(wm_widget_get_message)
                SMJS_FREE(c, name);
        }
        if (msg) {
-               JSObject *obj = JS_NewObject(c, &ifce->content->widget->wm->widgetAnyClass, 0, 0);
+               JSObject *obj = JS_NewObject(c, &ifce->content->widget->wm->widgetAnyClass._class, 0, 0);
                SMJS_SET_PRIVATE(c, obj, msg);
                JS_DefineProperty(c, obj, "num_params", INT_TO_JSVAL( gf_list_count(msg->params) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                JS_DefineProperty(c, obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, msg->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1503,7 +1503,7 @@ static JSBool SMJS_FUNCTION(wm_widget_get_interface)
 
        if (ifce) {
                if (!ifce->obj) {
-                       ifce->obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                       ifce->obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass._class, 0, 0);
                        SMJS_SET_PRIVATE(c, ifce->obj, ifce);
                        JS_DefineProperty(c, ifce->obj, "num_messages", INT_TO_JSVAL( gf_list_count(ifce->messages) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                        JS_DefineProperty(c, ifce->obj, "type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->type) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1638,8 +1638,8 @@ static JSBool SMJS_FUNCTION(wm_widget_get_context)
 }
 
 
-static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( wm_widget_getProperty)
+
        JSString *s;
        char *prop_name;
        const char *opt;
@@ -1693,7 +1693,7 @@ static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTE
                        if (icon) {
                                char *abs_reloc_url;
                                jsval icon_obj_val;
-                               JSObject *icon_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                               JSObject *icon_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass._class, 0, 0);
                                SMJS_SET_PRIVATE(c, icon_obj, icon);
                                JS_DefineProperty(c, icon_obj, "src", STRING_TO_JSVAL( JS_NewStringCopyZ(c, icon->src) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                                if (strlen(icon->relocated_src)) abs_reloc_url = gf_url_concatenate(wid->widget->url, icon->relocated_src);
@@ -1717,7 +1717,7 @@ static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTE
                        GF_WidgetPreference *pref = gf_list_get(wid->widget->main->preferences, i);
                        if (pref) {
                                jsval pref_obj_val;
-                               JSObject *pref_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                               JSObject *pref_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass._class, 0, 0);
                                SMJS_SET_PRIVATE(c, pref_obj, pref);
                                JS_DefineProperty(c, pref_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, pref->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                                JS_DefineProperty(c, pref_obj, "value", STRING_TO_JSVAL( JS_NewStringCopyZ(c, pref->value) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1737,7 +1737,7 @@ static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTE
                        GF_WidgetFeature *feat = gf_list_get(wid->widget->features, i);
                        if (feat) {
                                jsval feat_obj_val;
-                               JSObject *feat_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                               JSObject *feat_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass._class, 0, 0);
                                SMJS_SET_PRIVATE(c, feat_obj, feat);
                                JS_DefineProperty(c, feat_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, feat->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
                                JS_DefineProperty(c, feat_obj, "required", BOOLEAN_TO_JSVAL( (feat->required? JS_TRUE : JS_FALSE) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1748,7 +1748,7 @@ static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTE
                                        params_arr = JS_NewArrayObject(c, pcount, NULL);
                                        for (j=0; j < pcount; j++) {
                                                GF_WidgetFeatureParam *param = gf_list_get(feat->params, j);
-                                               JSObject *param_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                                               JSObject *param_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass._class, 0, 0);
                                                jsval param_obj_val;
                                                SMJS_SET_PRIVATE(c, param_obj, param);
                                                JS_DefineProperty(c, param_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -1893,8 +1893,9 @@ static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTE
        SMJS_FREE(c, prop_name);
        return JS_TRUE;
 }
-static JSBool wm_widget_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+
+static SMJS_FUNC_PROP_SET( wm_widget_setProperty)
+
        char szVal[32];
        jsdouble val;
        char *prop_name;
@@ -2105,7 +2106,7 @@ static void wm_widget_jsbind(GF_WidgetManager *wm, GF_WidgetInstance *wid)
 {
        if (wid->obj)
                return;
-       wid->obj = JS_NewObject(wm->ctx, &wm->wmWidgetClass, 0, 0);
+       wid->obj = JS_NewObject(wm->ctx, &wm->wmWidgetClass._class, 0, 0);
        SMJS_SET_PRIVATE(wm->ctx, wid->obj, wid);
        /*protect from GC*/
        gf_js_add_root(wm->ctx, &wid->obj, GF_JSGC_OBJECT);
@@ -2222,7 +2223,7 @@ static JSBool SMJS_FUNCTION(wm_load)
        url = NULL;
        if ((argc==2) && ! JSVAL_IS_NULL(argv[1]) && JSVAL_IS_OBJECT(argv[1])) {
                GF_WidgetInstance *parent_widget;
-               if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[1]), &wm->wmWidgetClass, NULL) ) return JS_FALSE;
+               if (!GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[1]), &wm->wmWidgetClass, NULL) ) return JS_FALSE;
                parent_widget = (GF_WidgetInstance *)SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[1]) );
                
                if (parent_widget->widget->url) url = gf_url_concatenate(parent_widget->widget->url, manifest);
@@ -2288,7 +2289,7 @@ static JSBool SMJS_FUNCTION(wm_unload)
        GF_WidgetManager *wm = (GF_WidgetManager *)SMJS_GET_PRIVATE(c, obj);
        if (!argc || !JSVAL_IS_OBJECT(argv[0])) return JS_TRUE;
 
-       if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &wm->wmWidgetClass, NULL) ) return JS_FALSE;
+       if (!GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &wm->wmWidgetClass, NULL) ) return JS_FALSE;
        wid = (GF_WidgetInstance *)SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0]) );
        if (!wid) return JS_TRUE;
 
@@ -2304,8 +2305,8 @@ static JSBool SMJS_FUNCTION(wm_unload)
 
 
 
-static JSBool wm_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( wm_getProperty)
+
        char *prop_name;
        GF_WidgetManager *wm = (GF_WidgetManager *)SMJS_GET_PRIVATE(c, obj);
        if (!wm) return JS_FALSE;
@@ -2325,8 +2326,10 @@ static JSBool wm_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsva
        SMJS_FREE(c, prop_name);
        return JS_TRUE;
 }
-static JSBool wm_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+
+
+static SMJS_FUNC_PROP_SET( wm_setProperty)
+
        char *prop_name;
        GF_WidgetManager *wm = (GF_WidgetManager *)SMJS_GET_PRIVATE(c, obj);
        if (!wm) return JS_FALSE;
@@ -3534,8 +3537,8 @@ static void widgetmanager_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene,
        /*setup JS bindings*/
        JS_SETUP_CLASS(wm->widmanClass, "WIDGETMANAGER", JSCLASS_HAS_PRIVATE, wm_getProperty, wm_setProperty, JS_FinalizeStub);
 
-       JS_InitClass(c, global, 0, &wm->widmanClass, 0, 0, wmClassProps, wmClassFuncs, 0, 0);
-       wm->obj = JS_DefineObject(c, global, "WidgetManager", &wm->widmanClass, 0, 0);
+       GF_JS_InitClass(c, global, 0, &wm->widmanClass, 0, 0, wmClassProps, wmClassFuncs, 0, 0);
+       wm->obj = JS_DefineObject(c, global, "WidgetManager", &wm->widmanClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, wm->obj, wm);
        gf_js_add_root(c, &wm->obj, GF_JSGC_OBJECT);
 
@@ -3563,10 +3566,10 @@ static void widgetmanager_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene,
        };
        /*setup JS bindings*/
        JS_SETUP_CLASS(wm->wmWidgetClass, "WMWIDGET", JSCLASS_HAS_PRIVATE, wm_widget_getProperty, wm_widget_setProperty, JS_FinalizeStub);
-       JS_InitClass(c, global, 0, &wm->wmWidgetClass, 0, 0, wmWidgetClassProps, wmWidgetClassFuncs, 0, 0);
+       GF_JS_InitClass(c, global, 0, &wm->wmWidgetClass, 0, 0, wmWidgetClassProps, wmWidgetClassFuncs, 0, 0);
 
        JS_SETUP_CLASS(wm->widgetAnyClass, "WIDGETANY", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
-       JS_InitClass(c, global, 0, &wm->widgetAnyClass, 0, 0, 0, 0, 0, 0);
+       GF_JS_InitClass(c, global, 0, &wm->widgetAnyClass, 0, 0, 0, 0, 0, 0);
        }
 
        JS_SETUP_CLASS(wm->widgetClass, "MPEGWidget", JSCLASS_HAS_PRIVATE, widget_getProperty, widget_setProperty, JS_FinalizeStub);
index 879cf8b5334d98f67c5ca0aff7bf43c028e674fe..b7b51950203791456be908f86604e9e586ff0bb8 100644 (file)
@@ -20,7 +20,7 @@
 //
 //This copyright notice must be included in all copies or derivative works.
 //
-//Copyright (c) 2009.
+//Copyright (c) 2009 Telecom ParisTech.
 //
 // Alternatively, this software module may be redistributed and/or modified
 //  it under the terms of the GNU Lesser General Public License as published by
@@ -76,14 +76,14 @@ typedef struct _widget_manager
 {
        JSContext *ctx;
        /*widget manager class*/
-       JSClass widmanClass;
+       GF_JSClass widmanClass;
        /*widget class used by the widget manager*/
-       JSClass wmWidgetClass;
+       GF_JSClass wmWidgetClass;
 
        /*widget class used by the widget scripts*/
-       JSClass widgetClass;
+       GF_JSClass widgetClass;
 
-       JSClass widgetAnyClass;
+       GF_JSClass widgetAnyClass;
 
        JSObject *obj;
        GF_Terminal *term;
@@ -336,8 +336,8 @@ JSBool SMJS_FUNCTION(widget_open_url);
 JSBool SMJS_FUNCTION(widget_get_attention);
 JSBool SMJS_FUNCTION(widget_show_notification);
 JSBool SMJS_FUNCTION(widget_get_interface);
-JSBool widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp);
-JSBool widget_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp);
+SMJS_DECL_FUNC_PROP_GET(widget_getProperty);
+SMJS_DECL_FUNC_PROP_SET(widget_setProperty);
 
 void widget_on_interface_bind(GF_WidgetInterfaceInstance *ifce, Bool unbind);
 
index cd00066dcb6a9ae88602bfb387933836b19a53b9..b3f8c59c5d8b027c65da88eea8f04e9cba0bcc23 100644 (file)
@@ -34,11 +34,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index b28398402a5a9550cae9b93e3b128fdcdd5fc3c6..bed16ba58b7e8e2bf7580da189be1cb3069e9c9e 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) ENST 2009-
- *                             Authors: Jean Le Feuvre
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2009-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Dummy input module
@@ -102,7 +102,6 @@ static u32 WII_Run(void *par)
        /*locate the wiimotes*/
        count = wiiuse_find(wii->wiimotes, wii->nb_wiimotes, scan_delay); 
        GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[Wii] Found %d wiimotes\n", count));
-       fprintf(stdout, "found %d wiimotes", count);
        count = wiiuse_connect(wii->wiimotes, wii->nb_wiimotes);
        if (count) {
                GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[Wii] Connected to %d connected wiimotes\n", count));
index ab00d89d23bc499f5155421b84b685ea6b89e130..5c6433ecf88184a6ece2a24fa94d9e582725275e 100644 (file)
@@ -68,12 +68,6 @@ ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.$(DYN_LIB_SUFFIX) $(OBJS) -lX11 -L../../bin/gcc -lgpac_static $(EXTRALIBS)
 endif
 
-#static-bin:
-#      $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.$(DYN_LIB_SUFFIX) $(OBJS) -lX11 -L../../bin/gcc -lgpac_static
-                                                                                               
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
 
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
index e2993525169c1fdbf9724d7a5f6f53693e35cff0..3ba42c9f2e2e59c83f896d110a50907a55b67598 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                     Authors: DINH Anh Min - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC /  X11 video output module
@@ -732,7 +732,7 @@ static GF_Err X11_SetupGLPixmap(GF_VideoOutput *vout, u32 width, u32 height)
   if (!xWin->glx_context) return GF_IO_ERR;
 
  XSync(xWin->display, False);
fprintf(stdout, "!! Activating GLContext on GLPixmap - this may crash !!\n");
GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[X11] Activating GLContext on GLPixmap - this may crash !!\n"));
  glXMakeCurrent(xWin->display, xWin->gl_offscreen, xWin->glx_context);
   }
 
index 2aa88af6ba38af117d0cb8f41ca5bbfbebfd86ef..d950695568a30e2582e51382e05f531682467fb8 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                     Authors: DINH Anh Min - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / X11 video output module
index d105a1286b1595cbf60ccfed2f48aaf8fc3a4e43..5e1d3b11a5f7d7af666db81e66f070806bbf6e3d 100644 (file)
@@ -46,11 +46,6 @@ all: $(LIB)
 $(LIB): $(OBJS)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS)
 
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
-
 clean: 
        rm -f $(OBJS) ../../bin/gcc/$(LIB)
 
index 76c44e33087ab35aaef46d2b548d5a33d1b3107c..08556475d7bd3ddaa0243e920c28ec5723c23f71 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / codec pack module
index acc86e7a9875077f981ce498c7f627cb4744c3eb..24c6dbf4b1205e0f9d034168acbaf7eff2fe88e3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / codec pack module
index 3756b24b99e4fac725b91d9d487a31e64a47264e..2186a6195d712043ce95183aada5108f4a940a50 100644 (file)
@@ -58,7 +58,8 @@ OrderedGroup {
   DEF SCRIPT Script {
    eventIn SFTime act
    field SFNode n USE TEXT
-   url ["javascript: function act(value, timestamp) {n.string[0] = 'EventIn Value: ' + value;n.string[1] = 'Script Timestamp: ' + timestamp;n.string[2] = 'Diff: ' + (timestamp-value);}"   ]
+   url ["javascript: function act(value, timestamp) {n.string[0] = 'EventIn Value: ' + value;n.string[1] = 'Script Timestamp: ' + timestamp;n.string[2] = 'Diff: ' + (timestamp-value);
+}"   ]
   }
  ]
 }
index c0f4cb20cffe81fea3ecd49c595c019095664884..318b782002ec711114a1470b3f185b336a76ea4c 100644 (file)
@@ -15,7 +15,14 @@ LDFLAGS+=-pg
 endif
 
 ## libgpac objects gathering: src/utils
-LIBGPAC_UTILS=utils/os_divers.o utils/os_net.o utils/os_module.o utils/os_thread.o utils/os_config_init.o utils/list.o utils/base_encoding.o utils/bitstream.o utils/color.o utils/configfile.o utils/cache.o utils/downloader.o utils/error.o utils/math.o utils/path2d.o utils/path2d_stroker.o utils/module.o utils/token.o utils/uni_bidi.o utils/url.o utils/utf.o utils/xml_parser.o utils/alloc.o utils/ringbuffer.o utils/unicode.o utils/sha1.o
+LIBGPAC_UTILS=utils/os_divers.o utils/list.o utils/bitstream.o utils/error.o utils/alloc.o utils/url.o utils/configfile.o 
+ifeq ($(DISABLE_CORE_TOOLS), no)
+LIBGPAC_UTILS+=utils/sha1.o  utils/base_encoding.o utils/os_net.o utils/os_thread.o utils/os_config_init.o utils/cache.o utils/downloader.o utils/xml_parser.o utils/utf.o utils/token.o 
+endif
+
+ifeq ($(DISABLE_PLAYER), no)
+LIBGPAC_UTILS+=utils/color.o utils/os_module.o utils/math.o utils/path2d.o utils/path2d_stroker.o utils/module.o utils/uni_bidi.o utils/ringbuffer.o utils/unicode.o
+endif
 
 ## libgpac objects gathering: src/ietf
 LIBGPAC_IETF=
@@ -30,13 +37,32 @@ LIBGPAC_BIFS=bifs/arith_decoder.o bifs/bifs_codec.o bifs/bifs_node_tables.o bifs
 endif
 
 ## libgpac objects gathering: src/isomedia
-LIBGPAC_ISOM=isomedia/avc_ext.o isomedia/box_code_3gpp.o isomedia/box_code_apple.o isomedia/box_code_base.o isomedia/box_code_isma.o isomedia/box_code_meta.o isomedia/box_dump.o isomedia/box_funcs.o isomedia/data_map.o isomedia/isma_sample.o isomedia/isom_intern.o isomedia/isom_read.o isomedia/isom_store.o isomedia/isom_write.o isomedia/media.o isomedia/media_odf.o isomedia/meta.o isomedia/movie_fragments.o isomedia/sample_descs.o isomedia/stbl_read.o isomedia/stbl_write.o isomedia/track.o isomedia/tx3g.o 
+LIBGPAC_ISOM=isomedia/avc_ext.o isomedia/box_code_3gpp.o isomedia/box_code_adobe.o isomedia/box_code_apple.o isomedia/box_code_base.o isomedia/box_code_drm.o isomedia/box_code_meta.o isomedia/box_dump.o isomedia/box_funcs.o isomedia/data_map.o isomedia/drm_sample.o isomedia/isom_intern.o isomedia/isom_read.o isomedia/isom_store.o isomedia/isom_write.o isomedia/media.o isomedia/media_odf.o isomedia/meta.o isomedia/movie_fragments.o isomedia/sample_descs.o isomedia/stbl_read.o isomedia/stbl_write.o isomedia/track.o isomedia/tx3g.o isomedia/generic_subtitle.o 
 ifeq ($(DISABLE_ISOFF_HINT), no)
 LIBGPAC_ISOM+=isomedia/hint_track.o isomedia/hinting.o
 endif
 
 ## libgpac objects gathering: src/odf
-LIBGPAC_ODF=odf/desc_private.o odf/descriptors.o odf/ipmpx_code.o odf/ipmpx_dump.o odf/ipmpx_parse.o odf/oci_codec.o odf/odf_code.o odf/odf_codec.o odf/odf_command.o odf/odf_dump.o odf/odf_parse.o odf/qos.o odf/slc.o 
+LIBGPAC_ODF=odf/desc_private.o odf/descriptors.o odf/odf_code.o odf/odf_codec.o odf/odf_command.o odf/qos.o odf/slc.o 
+ifeq ($(MINIMAL_OD), no)
+LIBGPAC_ODF+=odf/ipmpx_code.o odf/oci_codec.o 
+
+ifeq ($(DISABLE_OD_DUMP), no)
+LIBGPAC_ODF+=odf/ipmpx_dump.o
+endif
+
+ifeq ($(DISABLE_OD_PARSE), no)
+LIBGPAC_ODF+=odf/ipmpx_parse.o
+endif
+
+endif
+
+ifeq ($(DISABLE_OD_DUMP), no)
+LIBGPAC_ODF+=odf/odf_dump.o
+endif
+ifeq ($(DISABLE_OD_PARSE), no)
+LIBGPAC_ODF+=odf/odf_parse.o
+endif
 
 ## libgpac objects gathering: src/scenegraph
 LIBGPAC_SCENE=scenegraph/base_scenegraph.o scenegraph/mpeg4_animators.o scenegraph/commands.o scenegraph/mpeg4_nodes.o scenegraph/mpeg4_valuator.o scenegraph/vrml_interpolators.o scenegraph/vrml_proto.o scenegraph/vrml_route.o scenegraph/vrml_script.o scenegraph/vrml_smjs.o scenegraph/vrml_tools.o scenegraph/x3d_nodes.o scenegraph/svg_attributes.o scenegraph/svg_types.o scenegraph/svg_smjs.o scenegraph/smil_anim.o scenegraph/smil_timing.o scenegraph/svg_properties.o scenegraph/dom_events.o  scenegraph/dom_smjs.o scenegraph/xbl_process.o scenegraph/xml_ns.o
@@ -48,7 +74,28 @@ LIBGPAC_MCRYPT+=mcrypt/cbc.o mcrypt/cfb.o mcrypt/ctr.o mcrypt/des.o mcrypt/ecb.o
 endif
 
 ## libgpac objects gathering: src/media tools
-LIBGPAC_MEDIATOOLS=media_tools/av_parsers.o media_tools/img.o media_tools/isom_tools.o media_tools/media_export.o media_tools/media_import.o media_tools/mpegts.o media_tools/m2ts_mux.o media_tools/m3u8.o media_tools/mpd.o
+LIBGPAC_MEDIATOOLS=media_tools/isom_tools.o media_tools/dash_segmenter.o media_tools/av_parsers.o
+ifeq ($(DISABLE_AV_PARSERS), no)
+LIBGPAC_MEDIATOOLS+=media_tools/img.o
+endif
+ifeq ($(DISABLE_MEDIA_IMPORT), no)
+LIBGPAC_MEDIATOOLS+=media_tools/media_import.o
+endif
+ifeq ($(DISABLE_M2TS), no)
+LIBGPAC_MEDIATOOLS+=media_tools/mpegts.o
+endif
+ifeq ($(DISABLE_MPD), no)
+LIBGPAC_MEDIATOOLS+=media_tools/m3u8.o media_tools/mpd.o
+endif
+ifeq ($(DISABLE_DASH_CLIENT), no)
+LIBGPAC_MEDIATOOLS+=media_tools/dash_client.o
+endif
+ifeq ($(DISABLE_MEDIA_EXPORT), no)
+LIBGPAC_MEDIATOOLS+=media_tools/media_export.o
+endif
+ifeq ($(DISABLE_M2TS_MUX), no)
+LIBGPAC_MEDIATOOLS+=media_tools/m2ts_mux.o
+endif
 ifeq ($(DISABLE_STREAMING), no)
 LIBGPAC_MEDIATOOLS+=media_tools/filestreamer.o
 endif
@@ -69,6 +116,10 @@ LIBGPAC_MEDIATOOLS+=media_tools/ismacryp.o
 endif
 ifeq ($(DISABLE_ISOFF_HINT), no)
 LIBGPAC_MEDIATOOLS+=media_tools/isom_hinter.o
+else
+ifeq ($(DISABLE_STREAMING), no)
+LIBGPAC_MEDIATOOLS+=media_tools/isom_hinter.o
+endif
 endif
 ifeq ($(DISABLE_SAF), no)
 LIBGPAC_MEDIATOOLS+=media_tools/saf.o
@@ -84,10 +135,10 @@ endif
 ## libgpac objects gathering: src/scene_manager
 LIBGPAC_SCENEMANAGER=
 ifeq ($(DISABLE_SMGR), no)
-LIBGPAC_SCENEMANAGER+=scene_manager/scene_manager.o
+LIBGPAC_SCENEMANAGER+=scene_manager/scene_manager.o scene_manager/text_to_bifs.o
 endif
 ifeq ($(DISABLE_LOADER_BT), no)
-LIBGPAC_SCENEMANAGER+=scene_manager/loader_bt.o scene_manager/text_to_bifs.o
+LIBGPAC_SCENEMANAGER+=scene_manager/loader_bt.o
 endif
 ifeq ($(DISABLE_LOADER_XMT), no)
 LIBGPAC_SCENEMANAGER+=scene_manager/loader_xmt.o
@@ -102,7 +153,7 @@ ifeq ($(DISABLE_SVG), no)
 LIBGPAC_SCENEMANAGER+=scene_manager/loader_svg.o 
 endif
 ifeq ($(DISABLE_LOADER_SWF), no)
-LIBGPAC_SCENEMANAGER+=scene_manager/swf_parse.o scene_manager/swf_bifs.o 
+LIBGPAC_SCENEMANAGER+=scene_manager/swf_parse.o scene_manager/swf_bifs.o scene_manager/swf_svg.o 
 endif
 ifeq ($(DISABLE_SCENE_DUMP), no)
 LIBGPAC_SCENEMANAGER+=scene_manager/scene_dump.o
@@ -147,6 +198,8 @@ LINKLIBS=
 SCENEGRAPH_CFLAGS=
 MEDIATOOLS_CFLAGS=
 
+ifeq ($(DISABLE_CORE_TOOLS), no)
+
 #1 - zlib support
 ifeq ($(CONFIG_ZLIB), local)
 CFLAGS+= -I"$(LOCAL_INC_PATH)/zlib"
@@ -169,6 +222,8 @@ endif
 LINKLIBS+=$(JS_LIBS)
 endif
 
+endif
+
 #4 - JPEG support
 ifeq ($(CONFIG_JPEG), no)
 else
@@ -279,18 +334,16 @@ mediatools: $(LIBGPAC_MEDIATOOLS)
 compositor: CFLAGS+=$(COMPOSITOR_CFLAGS)
 compositor: $(LIBGPAC_COMPOSITOR)
 
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $< 
-
 
 $(LIB): $(LIBGPAC_UTILS) $(LIBGPAC_IETF) $(LIBGPAC_BIFS) $(LIBGPAC_ODF) $(LIBGPAC_LASER) $(LIBGPAC_ISOM) $(LIBGPAC_SCENEMANAGER) $(LIBGPAC_TERMINAL) compositor scenegraph mediatools mcrypt $(OBJS)
+       @echo "Linking libgpac"
 ifeq ($(CONFIG_DARWIN),yes)
-       libtool -s -o ../bin/gcc/libgpac_static.a $(OBJS)
-       ranlib ../bin/gcc/libgpac_static.a
+       $(LIBTOOL) -s -o ../bin/gcc/libgpac_static.a $(OBJS)
+       $(RANLIB) ../bin/gcc/libgpac_static.a
        $(CC) $(SHFLAGS) $(LD_SONAME) $(LDFLAGS) -o ../bin/gcc/$@ $(OBJS) $(EXTRALIBS) 
 else
-       ar cr ../bin/gcc/libgpac_static.a $(OBJS)
-       ranlib ../bin/gcc/libgpac_static.a
+       $(AR) cr ../bin/gcc/libgpac_static.a $(OBJS)
+       $(RANLIB) ../bin/gcc/libgpac_static.a
        $(CC) $(SHFLAGS) $(LD_SONAME) $(LDFLAGS) -o ../bin/gcc/$@ $(OBJS) $(EXTRALIBS)
 ifeq (,$(findstring yes, $(CONFIG_WIN32)))
        mv ../bin/gcc/$@ ../bin/gcc/$@.$(VERSION_SONAME)
index b838bb4efb94635e619fd0347dca275b509cf5c0..331d5dcf13b751c1f8f9763b2147c5f06f196a42 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index c5268663f46545f230a1b66f452116a2b2b713d2..bfff6e93fa3a3b04a9a16929a1fd8420753c03ac 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index a024495c9550b3fd5ca83f2e83039b376ce675e0..987ffdeb29894d02abbe103586095b3865715f7a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 21d8f19f00aa464257abea5caaebe266158b19a8..bfcd1b65975ba69e3f53cc174b268d63c4387e12 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 71ba7420639e7d1d7ef111d3acda09f5b0920a32..7f8687546bdb02dcf66150b0bf566c3b4fb2ab6f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 2016cf6ebba42383a8251299221446d452252157..2a1db48a17e7dd0ea99c763e28654d9338d2642e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index b39422ea164016870e6ad7093afe8fbca14e3539..6e2aaf6d716c9425a3f7868dee521f499d343c72 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
@@ -923,10 +924,14 @@ GF_Node *gf_bifs_dec_node(GF_BifsDecoder * codec, GF_BitStream *bs, u32 NDT_Tag)
                break;
        }
 
+       /*proto is initialized upon the first traversal to have the same behavior as wth BT/XMT loading*/
+#if 0
        /*if new node is a proto and we're in the top scene, load proto code*/
        if (proto && (codec->scenegraph == codec->current_graph)) {
                codec->LastError = gf_sg_proto_load_code(new_node);
        }
+#endif
+
        return new_node;
 }
 
index 56e4f920a292c66adb57caa19cdb8b46e7a1c7bd..4b90bdf1afb374a4d5744619e0d640f80b1dcb46 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index ae4f9de61b88dcd4dcdbee8519b0d7557788f023..3d57eb90b09c23f799b4d7f62c081aa4beafcd3a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 0e32773fac7a446b596728507fab491b2feedc26..8d0c4262e18dbdebc8c524d642ef1a59d6aa158b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index b7dd1bcc7e3065d0a0a12bb83087f7a7cf1ba232..6d45add52fff7bcb92b54468abce1819bcabfe95 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index ece1182ad8fab98c00600af0877b638364a54e60..d1e873ad7df60d3c06c82ffd6ebf7adcba83bc50 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index b305c887479acfb8a03ba5855af8453858f56da9..d60fa97fbc4cfa92153e50370ed70e5f4f3ef282 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 3f5be2474cf1327d0b3383ee80825c4a936b62f9..11362ded577564e441b7d06f57a8a372037b2713 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index 77c09fe99780be77904d23705db7fa8c24f81dfa..75738c11f625921ffbe3bde485c437ffab113eed 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index c2b5a367c56bdade847c6f40e1d75c942ba2ab33..ec337735d7c58ee90ba7377716b322ccfa6515bc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / BIFS codec sub-project
index c02b2323144585311405059fefc1e916d0029359..475d40394b8f7c8ac9340ae209ea3edfc7a9a061 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
 
 #include <gpac/internal/compositor_dev.h>
 
-//#define ENABLE_EARLY_FRAME_DETECTION
-
-/*diff time in ms to consider an audio frame too early and insert silence*/
-#define MIN_RESYNC_TIME                500
+#define ENABLE_EARLY_FRAME_DETECTION
 
 /*diff time in ms to consider an audio frame too late and drop it - we should try to dynamically figure this out
 since the drift may be high on TS for example, where PTS-PCR>500ms is quite common*/
@@ -55,7 +53,7 @@ static char *gf_audio_input_fetch_frame(void *callback, u32 *size, u32 audio_del
 {
        char *frame;
        u32 obj_time, ts;
-       s32 drift, resync_delay;
+       s32 drift;
        Fixed speed;
        GF_AudioInput *ai = (GF_AudioInput *) callback;
        /*even if the stream is signaled as finished we must check it, because it may have been restarted by a mediaControl*/
@@ -74,7 +72,6 @@ static char *gf_audio_input_fetch_frame(void *callback, u32 *size, u32 audio_del
        ai->need_release = 1;
 
        speed = gf_mo_get_current_speed(ai->stream);
-       resync_delay = FIX2INT(speed*ai->is_open);
 
        gf_mo_get_object_time(ai->stream, &obj_time);
        obj_time += audio_delay_ms;
@@ -83,8 +80,8 @@ static char *gf_audio_input_fetch_frame(void *callback, u32 *size, u32 audio_del
 
 #ifdef ENABLE_EARLY_FRAME_DETECTION
        /*too early (silence insertions), skip*/
-       if (drift + (s32) (audio_delay_ms + resync_delay) < 0) {
-               GF_LOG(GF_LOG_INFO, GF_LOG_AUDIO, ("[Audio Input] audio too early %d (CTS %d)\n", drift + audio_delay_ms + resync_delay, ts));
+       if (drift < 0) {
+               GF_LOG(GF_LOG_INFO, GF_LOG_AUDIO, ("[Audio Input] audio too early of %d (CTS %d at OTB %d with audio delay %d ms)\n", drift + audio_delay_ms, ts, obj_time, audio_delay_ms));
                ai->need_release = 0;
                gf_mo_release_data(ai->stream, 0, 0);
                return NULL;
@@ -92,7 +89,7 @@ static char *gf_audio_input_fetch_frame(void *callback, u32 *size, u32 audio_del
 #endif
        /*adjust drift*/
        if (audio_delay_ms) {
-               resync_delay = FIX2INT(speed * MAX_RESYNC_TIME);
+               s32 resync_delay = FIX2INT(speed * MAX_RESYNC_TIME);
                /*CU is way too late, discard and fetch a new one - this usually happen when media speed is more than 1*/
                if (drift>resync_delay) {
                        GF_LOG(GF_LOG_INFO, GF_LOG_AUDIO, ("[Audio Input] Audio data too late obj time %d - CTS %d - drift %d ms - resync forced\n", obj_time - audio_delay_ms, ts, drift));
@@ -112,8 +109,6 @@ static void gf_audio_input_release_frame(void *callback, u32 nb_bytes)
        if (!ai->stream) return;
        gf_mo_release_data(ai->stream, nb_bytes, 1);
        ai->need_release = 0;
-       /*as soon as we have released a frame for this audio stream, update resync tolerance*/
-       ai->is_open = MIN_RESYNC_TIME;
 }
 
 static Fixed gf_audio_input_get_speed(void *callback)
index 2f1e82b095f47cfbdf72c3de22f067d1f4c4aa1e..42010d5199e209369a3ffb9f20480cea4b67ca59 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -604,7 +605,7 @@ single_source_mix:
                buffer_size -= size;
                ptr += size;
                single_source->src->ReleaseFrame(single_source->src->callback, size);
-               delay = 0;
+               delay += size * 8000 / am->bits_per_sample / am->sample_rate / am->nb_channels;
        }
 
        /*not completely filled*/
@@ -690,7 +691,7 @@ do_mix:
                for (i=0; i<count; i++) {
                        in = (MixerInput *)gf_list_get(am->sources, i);
                        if (in->out_samples_to_write>in->out_samples_written) {
-                               gf_mixer_fetch_input(am, in, in->out_samples_written ? 0 : delay);
+                               gf_mixer_fetch_input(am, in, delay + 8000 * i / am->bits_per_sample / am->sample_rate / am->nb_channels);
                                if (in->out_samples_to_write>in->out_samples_written) nb_to_fill++;
                        }
                }
index 6fdb997a445ddf7f6ecd34b8748f3ac1078345fe..df3d1490f82d4fbc46bc5ce1dd10f4e8cc7e48e5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -487,7 +488,7 @@ void gf_sc_ar_del(GF_AudioRenderer *ar)
        if (ar->audio_out) {
                /*kill audio thread*/
                if (!ar->audio_out->SelfThreaded) {
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] stoping audio thread\n"));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] stopping audio thread\n"));
                        ar->audio_th_state = 2;
                        while (ar->audio_th_state != 3) {
                                gf_sleep(33);
@@ -653,7 +654,7 @@ void gf_sc_reload_audio_filters(GF_Compositor *compositor)
        gf_mixer_lock(ar->mixer, 0);
 }
 
-
+GF_EXPORT
 GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al)
 {
        GF_AudioMixer *mixer;
@@ -675,6 +676,7 @@ GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al)
        return GF_OK;
 }
 
+GF_EXPORT
 GF_Err gf_sc_remove_audio_listener(GF_Compositor *compositor, GF_AudioListener *al)
 {
        if (!compositor || !al) return GF_BAD_PARAM;
index 5bdf4312accc625f8c51055a0cf6cf17527a72b4..e36d21fa650726976a4ef8962a18bed84741da36 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index d92ea3e09e3843a3f8ea65643f139a2164bdb799..1a7bb23981715c7127d0e04e9e480a4f8ab4704f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -184,7 +185,7 @@ void camera_set_2d(GF_Camera *cam)
 #endif
 }
 
-void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coords, Fixed horizontal_shift, Fixed nominal_view_distance, Fixed view_distance_offset, u32 camera_layout)
+void camera_update_stereo(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coords, Fixed horizontal_shift, Fixed nominal_view_distance, Fixed view_distance_offset, u32 camera_layout)
 {
        Fixed vlen, h, w, ar;
        SFVec3f corner, center;
@@ -201,7 +202,7 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor
                        Fixed left, right, top, bottom, shift, wd2, ndfl, viewing_distance;
                        SFVec3f eye, pos, tar, disp;
 
-                       viewing_distance = (nominal_view_distance + view_distance_offset);
+                       viewing_distance = nominal_view_distance;
 
                        wd2 = cam->z_near * gf_tan(cam->fieldOfView/2);
                        ndfl = gf_divfix(cam->z_near, viewing_distance);
@@ -230,7 +231,6 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor
 
                        gf_vec_diff(center, cam->world_bbox.center, cam->position);
                        vlen = gf_vec_len(center);
-                       vlen += view_distance_offset * (vlen/nominal_view_distance);
                        shift = horizontal_shift * vlen / viewing_distance;
 
                        pos = gf_vec_scale(disp, shift);
@@ -315,13 +315,12 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor
 
        if (camera_layout == GF_3D_CAMERA_CIRCULAR) {
                GF_Matrix mx;
-               Fixed viewing_distance = nominal_view_distance + view_distance_offset;
+               Fixed viewing_distance = nominal_view_distance;
                SFVec3f pos, target;
                Fixed angle;
 
                gf_vec_diff(center, cam->world_bbox.center, cam->position);
                vlen = gf_vec_len(center);
-               vlen += view_distance_offset * (vlen/nominal_view_distance);
 
                gf_vec_diff(pos, cam->target, cam->position);
                gf_vec_norm(&pos);
@@ -345,7 +344,7 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor
                gf_vec_diff(center, cam->world_bbox.center, cam->position);
                vlen = gf_vec_len(center);
                vlen += view_distance_offset * (vlen/nominal_view_distance);
-
+       
                gf_vec_diff(eye, cam->target, cam->position);
                gf_vec_norm(&eye);
                tar = gf_vec_scale(eye, vlen);
@@ -370,6 +369,10 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor
        cam->flags &= ~CAM_IS_DIRTY;
 }
 
+void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coords)
+{
+       camera_update_stereo(cam, user_transform, center_coords, 0, 0, 0, GF_3D_CAMERA_STRAIGHT);
+}
 void camera_set_vectors(GF_Camera *cam, SFVec3f pos, SFRotation ori, Fixed fov)
 {
        Fixed sin_a, cos_a, icos_a, tmp;
index 71b46457e8a55641e9c33400beb04714e1078687..04891c8cae82a782df7ea09b2c1df219b235d28a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -1267,6 +1268,11 @@ void gf_sc_reload_config(GF_Compositor *compositor)
        else if (!strcmp(sOpt, "OffAxis")) compositor->visual->camera_layout = GF_3D_CAMERA_OFFAXIS;
        else compositor->visual->camera_layout = GF_3D_CAMERA_STRAIGHT;
 
+       compositor->interoccular_distance = FLT2FIX(6.3f);
+       sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "EyeSeparation");
+       if (sOpt) compositor->interoccular_distance = FLT2FIX( atof(sOpt)) ;
+       else gf_cfg_set_key(compositor->user->config, "Compositor", "EyeSeparation", "6.3");
+
        sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ReverseViews");
        if (sOpt && !strcmp(sOpt, "yes")) compositor->visual->reverse_views = 1;
 
@@ -1290,6 +1296,16 @@ void gf_sc_reload_config(GF_Compositor *compositor)
                sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ViewDistance");
                compositor->video_out->view_distance = FLT2FIX( sOpt ? (Float) atof(sOpt) : 50.0f ); 
        }
+
+#ifndef GPAC_DISABLE_3D
+       sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "FocusDistance");
+       compositor->focus_distance = 0;
+       if (sOpt) 
+               compositor->focus_distance = FLT2FIX( atof(sOpt) ); 
+       else
+               gf_cfg_set_key(compositor->user->config, "Compositor", "FocusDistance", "0");
+#endif
+
 #endif
 
 
@@ -2052,7 +2068,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor)
                                        if (gf_sys_get_rti(500, &sys_rti, GF_RTI_ALL_PROCESSES_TIMES)) {
                                                evt.type = GF_EVENT_CPU;
                                                evt.cpu_percentage = sys_rti.total_cpu_usage;
-                                               //printf("%d\n",sys_rti.total_cpu_usage);
+                                               //fprintf(stderr, "%d\n",sys_rti.total_cpu_usage);
                                                gf_dom_event_fire(root, NULL, &evt);
                                        } 
                                } else if (l->event.type == GF_EVENT_BATTERY) { //&& l->observer.target == (SVG_SA_Element *)node) {
@@ -2192,7 +2208,8 @@ void gf_sc_simulation_tick(GF_Compositor *compositor)
                flush_time = gf_sys_clock();
 #endif
 
-               if(compositor->user->init_flags & GF_TERM_INIT_HIDE) compositor->skip_flush = 1;
+               if(compositor->user->init_flags & GF_TERM_INIT_HIDE)
+                       compositor->skip_flush = 1;
 
                if (compositor->skip_flush!=1) {
                        rc.x = rc.y = 0; 
@@ -2959,6 +2976,7 @@ void gf_sc_check_focus_upon_destroy(GF_Node *n)
        if (compositor->hit_text==n) compositor->hit_text = NULL;
 }
 
+GF_EXPORT
 GF_Err gf_sc_add_video_listener(GF_Compositor *sc, GF_VideoListener *vl)
 {
        if (!sc|| !vl || !vl->on_video_frame || !vl->on_video_reconfig) return GF_BAD_PARAM;
@@ -2970,6 +2988,7 @@ GF_Err gf_sc_add_video_listener(GF_Compositor *sc, GF_VideoListener *vl)
        return GF_OK;
 }
 
+GF_EXPORT
 GF_Err gf_sc_remove_video_listener(GF_Compositor *sc, GF_VideoListener *vl)
 {
        if (!sc|| !vl) return GF_BAD_PARAM;
index 22636281af554d13a9ee657fd4824a31287aac3e..9b273243f9ed43acf6d6e198c3a06ce05fe01d6c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index d1c8f277f0b3e8f8cf0a0ceadeace1b4cc20b011..8a8aa571d484898f63663affda33436436c656aa 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index d1ab3966df8af3ed59bc48d52ef851de578cfd11..be9fc65929f3969955f3474e2221ee7eb1dc6636 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index cfb13404df8dcf6f0ad9fd9cea6421f87a4de09c..94103aac41d29e597f8f316c44687966c0968e77 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -820,7 +821,7 @@ void drawable_finalize_sort_ex(DrawableContext *ctx, GF_TraverseState *tr_state,
        } else {
                gf_path_get_bounds(ctx->drawable->path, &store_orig_bounds);
        }
-    //if (store_orig_bounds) printf("store_orig_bounds: %d\n", (int) store_orig_bounds.width );
+    //if (store_orig_bounds) fprintf(stderr, "store_orig_bounds: %d\n", (int) store_orig_bounds.width );
        ctx->bi->unclip = store_orig_bounds;
        gf_mx2d_apply_rect(&tr_state->transform, &ctx->bi->unclip);
 
index c24ed76806aa07389eb836749af212dea0c5992e..937a272359b8908c97b243d39bfde465f777d37f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 482c2dc8bbf3d5fd0d4ac57d12f9785348dc9d89..2ba4548d53927686116280226cd93ca39c417be1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -165,7 +166,9 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type)
        u32 prev_pos, pos=0;
        s32 caret_pos;
        Bool append;
+#ifndef GPAC_DISABLE_SVG
        Bool delete_cr = 0;
+#endif
 
        caret_pos = -1;
 
@@ -177,7 +180,9 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type)
                break;
        /*load prev text chunk*/
        case 4:
+#ifndef GPAC_DISABLE_SVG
                delete_cr = 1;
+#endif
        case 1:
                if (compositor->dom_text_pos ==0) return 0;
                pos = compositor->dom_text_pos - 1;
@@ -335,11 +340,11 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type)
                                }
 /*                             if (1) {
                                        GF_ChildNodeItem *child = ((GF_ParentNode *) compositor->focus_node)->children;
-                                       fprintf(stdout, "Dumping text tree:\n");
+                                       fprintf(stderr, "Dumping text tree:\n");
                                        while (child) {
                                                switch (gf_node_get_tag(child->node)) {
-                                               case TAG_SVG_tbreak: fprintf(stdout, "\ttbreak\n"); break;
-                                               case TAG_DOMText: fprintf(stdout, "\ttext: %s\n", ((GF_DOMText *)child->node)->textContent); break;
+                                               case TAG_SVG_tbreak: fprintf(stderr, "\ttbreak\n"); break;
+                                               case TAG_DOMText: fprintf(stderr, "\ttext: %s\n", ((GF_DOMText *)child->node)->textContent); break;
                                                }
                                                child = child->next;
                                        }
@@ -613,19 +618,16 @@ static Bool hit_node_editable(GF_Compositor *compositor, Bool check_focus_node)
        return 1;
 }
 
+#ifndef GPAC_DISABLE_SVG
 static GF_Node *get_parent_focus(GF_Node *node, GF_List *hit_use_stack, u32 cur_idx)
 {
        GF_Node *parent;
-#ifndef GPAC_DISABLE_SVG
        GF_FieldInfo info;
-#endif
        if (!node) return NULL;
 
-#ifndef GPAC_DISABLE_SVG
        if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_focusable, 0, 0, &info)==GF_OK) {
                if ( *(SVG_Focusable*)info.far_ptr == SVG_FOCUSABLE_TRUE) return node;
        }
-#endif
        parent = gf_node_get_parent(node, 0);
        if (cur_idx) {
                GF_Node *n = gf_list_get(hit_use_stack, cur_idx-1);
@@ -637,6 +639,8 @@ static GF_Node *get_parent_focus(GF_Node *node, GF_List *hit_use_stack, u32 cur_
        }
        return get_parent_focus(parent, hit_use_stack, cur_idx);
 }
+#endif
+
 
 static Bool exec_event_dom(GF_Compositor *compositor, GF_Event *event)
 {
@@ -1195,17 +1199,14 @@ u32 gf_sc_svg_focus_navigate(GF_Compositor *compositor, u32 key_code)
 }
 
 /*focus management*/
+#ifndef GPAC_DISABLE_SVG
 static Bool is_focus_target(GF_Node *elt)
 {
-#ifndef GPAC_DISABLE_SVG
        u32 i, count;
-#endif
        u32 tag = gf_node_get_tag(elt);
        switch (tag) {
-#ifndef GPAC_DISABLE_SVG
        case TAG_SVG_a:
                return 1;
-#endif
 
 #ifndef GPAC_DISABLE_VRML
        case TAG_MPEG4_Anchor:
@@ -1221,7 +1222,6 @@ static Bool is_focus_target(GF_Node *elt)
        }
        if (tag<=GF_NODE_FIRST_DOM_NODE_TAG) return 0;
 
-#ifndef GPAC_DISABLE_SVG
        count = gf_dom_listener_count(elt);
        for (i=0; i<count; i++) {
                GF_FieldInfo info;
@@ -1239,9 +1239,9 @@ static Bool is_focus_target(GF_Node *elt)
                        }
                }
        }
-#endif /*GPAC_DISABLE_SVG*/
        return 0;
 }
+#endif /*GPAC_DISABLE_SVG*/
 
 #define CALL_SET_FOCUS(__child)        {       \
        gf_list_add(compositor->focus_ancestors, elt);  \
@@ -1255,7 +1255,7 @@ static Bool is_focus_target(GF_Node *elt)
        return NULL;    \
        }       \
 
-
+#ifndef GPAC_DISABLE_SVG
 static void rebuild_focus_ancestor(GF_Compositor *compositor, GF_Node *elt)
 {
        gf_list_reset(compositor->focus_ancestors);
@@ -1266,6 +1266,7 @@ static void rebuild_focus_ancestor(GF_Compositor *compositor, GF_Node *elt)
                elt = par;
        }
 }
+#endif // GPAC_DISABLE_SVG
 
 static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_focus, Bool prev_focus)
 {
@@ -1754,15 +1755,20 @@ GF_EXPORT
 u32 gf_sc_focus_switch_ring(GF_Compositor *compositor, Bool move_prev, GF_Node *focus, u32 force_focus)
 {
        Bool current_focus = 1;
+#ifndef GPAC_DISABLE_SVG
        Bool prev_uses_dom_events;
+       GF_Node *prev_use;
+#endif
        u32 ret = 0;
        GF_List *cloned_use = NULL;
-       GF_Node *n, *prev, *prev_use;
+       GF_Node *n, *prev;
 
+       compositor->focus_text_type = 0;
        prev = compositor->focus_node;
+#ifndef GPAC_DISABLE_SVG
        prev_use = compositor->focus_used;
-       compositor->focus_text_type = 0;
        prev_uses_dom_events = compositor->focus_uses_dom_events;
+#endif
        compositor->focus_uses_dom_events = 0;
 
        if (!compositor->focus_node) {
index 26c12e6b368c978153315f85e68acd55ceeff6b7..11f1018e202207ced3887cb6a6d8200932cabfaa 100644 (file)
@@ -2,8 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *                     
  *                     Authors: Jean Le Feuvre 
- *
- *                     Copyright (c) ENST 2007-200X
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Rendering sub-project
@@ -1177,7 +1176,9 @@ static void gf_font_spans_select(GF_TextSpan *span, GF_TraverseState *tr_state,
        for (i=0; i<span->nb_glyphs; i++) {
                GF_Rect g_rc;
                Bool end_of_line = 0;
-               Fixed advance = sx * span->glyphs[i]->horiz_advance;
+               Fixed advance;
+               if (!span->glyphs[i]) continue;
+               advance = sx * span->glyphs[i]->horiz_advance;
                if (span->dx) dx = span->dx[i];
                if (span->dy) dy = span->dy[i];
                if (dx + advance/2 < rc->x) {
index 177e3858f483124e6d10bf6a172aee8e9f59fc58..62e6f417ba3655f151fdd716be4968ff2061e8cc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -78,7 +79,7 @@
 #endif
 
 
-#define GL_CHECK_ERR  {s32 res = glGetError(); if (res) fprintf(stdout, "GL Error %d file %s line %d\n", res, __FILE__, __LINE__); }
+#define GL_CHECK_ERR  {s32 res = glGetError(); if (res) GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, "GL Error %d file %s line %d\n", res, __FILE__, __LINE__)); }
 
 /*macros for GL proto and fun declaration*/
 #ifdef _WIN32_WCE
index 695cae41f36d1baaa8b456625eb2e6fd2daac973..2eff1dc47d95b877b59478e96a77613c9e475cf7 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -904,7 +905,7 @@ static void TraverseUntransform(GF_Node *node, void *rs, Bool is_destroy)
                tr_state->camera->is_3D=0;
                tr_state->camera->flags |= CAM_NO_LOOKAT;
                tr_state->camera->end_zoom = FIX_ONE;
-               camera_update(tr_state->camera, NULL, 1, 0, 0, 0, GF_3D_CAMERA_STRAIGHT);
+               camera_update(tr_state->camera, NULL, 1);
 
 
                if (tr_state->traversing_mode == TRAVERSE_SORT) {
@@ -1043,7 +1044,7 @@ void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node)
                if (compositor->proto_modules) {
                        j = 0;
                        while ( (ifce = (GF_HardcodedProto *)gf_list_enum(compositor->proto_modules, &j) )) {
-                               if ( ifce->can_load_proto(url) && ifce->init(compositor, node) ) {
+                               if ( ifce->can_load_proto(url) && ifce->init(compositor, node, url) ) {
                                        return;
                                }
                        }
@@ -1052,4 +1053,19 @@ void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node)
 
 }
 
+Bool gf_sc_uri_is_hardcoded_proto(GF_Compositor *compositor, const char *uri)
+{
+       /*check proto modules*/
+       if (compositor && compositor->proto_modules ) {
+               u32 j = 0;
+               GF_HardcodedProto *ifce;
+               while ( (ifce = (GF_HardcodedProto *)gf_list_enum(compositor->proto_modules, &j) )) {
+                       if ( ifce->can_load_proto(uri)) {
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
 #endif /*GPAC_DISABLE_VRML*/
index a8e764ec5b7559534ed15b34a6bd00b4fc03b4aa..0c9e8fc09cf9738addd449409706f364cac205bf 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 89146088d8e42fb198d892e8ecd46c4bf755c9a1..f9bd6b78a475b2c1727429b13a20d31a8b31cd5d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 248ecb15d1a5588224dda38c93610405f019b007..007211baf53972fe38bfc4dbd874055ebb098a2b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index bb6f3ea1b7c0beb393f4b0d78c6125f6358fc142..569553bc688ba97237b9d4ef075d7b67fb76eb20 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 26108999abb217d85834090b1975fae788c08ae9..a19c41181abc3d1fdbee7c7bc10c143fd7f80468 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index c83e93315b9d21f70a8ecd0aa0b903ce33e6769f..98c361c978501cf2132b19a9032dec5e3eb48297 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index b5de7c43659c83f878b9ba7a160457870fa48606..8b0c44cf7566fe9908f7b6af27c7332adb44402e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 214330cf1210b052cfacdfdb0189f6fcf4848ec5..bb483119c5df1efaa7b851c03fdc4e2c5ba9a333 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -173,13 +174,13 @@ static void DrawBackground2D_3D(M_Background2D *bck, Background2DStack *st, GF_T
 
        visual_3d_set_background_state(tr_state->visual, 1);
 
+       visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_MODELVIEW);
        visual_3d_matrix_push(tr_state->visual);
 
 /*     visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_TEXTURE);
        gf_sc_texture_get_transform(&st->txh, NULL, &mx, 0);
        visual_3d_matrix_load(tr_state->visual, mx.m);
 */     
-       visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_MODELVIEW);
 
        /*little opt: if we clear the main visual clear it entirely */
        if (! tr_state->is_layer) {
index c2eee0723ca459e8f4224cc5059999ae249346e2..f39fce101c6a6bef8a6caa9ab939429ecb6329ed 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 0f8b92a678c7a0e536f9d5040093a0c9a33614a7..e7c5b19d39b9696b312681143db587f3f9d23f47 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 4c2b8cfa65d25fb1ee6fbba1b870174003fa3c97..887773661bf76a0e742e9a18fc2828e68afe8edc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 501d21f0252ecf35b5ffdf8c8fd4736b583002bf..6e993a551036d4f3987f31d74ba535f1962aca68 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index a2689ac8465507cf96a636f5616f79f4cf14db91..90ee5aca5592b4cfa68a4ec70ba081a0fabfb639 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index b79e8e847c9f1ebdb444df2c4c352c6ce61de52e..7970308d8049675fb8d8d3f5fd3332feb4e80d2a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 26ba0a300fea39a0750cba0fe5769d4a1b4af0f7..df4014a2504fc1fc9bbfd0dd615f018e77724a9f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 27374de7d788802080406af15b99fe8b0765e095..ba2b2baed9ff0e440440088c924f4639f13c9511 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 88119bde0a88aef8336e77943149dc6cbe99e1a0..42866830fc653b629ac407567102708164d90191 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 0032e00c4aba8e736a01841456143d3e608f4736..dc424056e3a8ed7addb6fbe3fb575a9f66cb4abe 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 6baf398eadc3ed81403dc5c3be5a803cffd40c20..f1a70e066b07a0717c2b2a1cfa1faec9e94614bf 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 68a5b149ae1459764fe97bd24b7bda2f98f0de49..9088433225fe0a5debb783d8c067c5e829776d3e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index d140cd580925fb174d22654fc6eaea181768884a..b610edf89f3afb051a3ae54734681220d47228b4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -97,6 +98,8 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy)
        GF_Node *back;
        Bool prev_layer;
        GF_Matrix2D backup;
+       GF_IRect prev_clip;
+       GF_Rect rc;
        SFVec2f prev_vp;
 
 #ifndef GPAC_DISABLE_3D
@@ -176,9 +179,6 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy)
                                gf_node_traverse(back, tr_state);
                        }
 
-                       /*sort all children without transform, and use current transform when flushing contexts*/
-                       gf_mx_init(tr_state->model_matrix);
-
                        /*apply viewport*/
                        if (viewport) {
                                tr_state->traversing_mode = TRAVERSE_BINDABLE;
@@ -216,9 +216,6 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy)
                } else 
 #endif
                {
-                       GF_IRect prev_clip;
-                       GF_Rect rc;
-
                        gf_mx2d_copy(backup, tr_state->transform);
 
                        prev_clip = tr_state->visual->top_clipper;
index 23e0041e4eaf0a309d7f91ef1abdd5baccf14777..89323dfe5e19c6bf45e8bb526efa9219ecc38596 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 7cb9f22fc5f2e6ef443b704782ec2af5f4b83186..78dba7e9faa0f6452397203ac8ae0b493160fd7d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 14f907c4271eba9b4882f4a69409560d57d95209..c86a1ab5f5ed8aeb29f901e63e96d2f18943464d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index dd1b85630b8164e428fa2657315147cd5615de2e..a8f5420b6529c059fc3575cbdd6eb99383c2821d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 59e626433b11770827bfa727e2cddeb4a5ccddf2..dbda11a825ae752beabdf6e29ad6c062e9c5df5b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 576b8c2c777feee27b520c58c8b3643de4c3f24f..19df81f47c8fcbf8ddcb0cadb4cc658fa6c74147 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index d211f85b9d97062160fef6a1dc7fe28c7165936f..467eb10d20f99a5063d7541e277478137ca2d4ee 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 3ae06d00df11ccd88030d812779033a236a21f9f..5b4f95d5b145326841b6d1dfa05adfcf1d7d5c2a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -279,6 +280,7 @@ static void imagetexture_update(GF_TextureHandler *txh)
 
                /*decode cacheTexture data */
                if ((ct->data || ct->image.buffer) && !txh->data) {
+#ifndef GPAC_DISABLE_AV_PARSERS
                        u32 out_size;
                        GF_Err e;
 
@@ -323,6 +325,7 @@ static void imagetexture_update(GF_TextureHandler *txh)
                                        break;
                                }
                        }
+#endif // GPAC_DISABLE_AV_PARSERS
 
                        /*cacheURL is specified, store the image*/
                        if (ct->cacheURL.buffer) {
index 683d6161a2264d8fbbad8c1252eb688454045615..4cc31a4e01516639f38a76cde3d1a1ab97039793 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 673087d30e5ea8ea847fad86b5aabb8b32530e57..18495f816fcf3af3bff24bb3f637c062e41fe7c7 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 7490bc013f55857b535298780dc7ecc5b9cc318f..6986025a7041113b31b982118f042e71c5657dfc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -209,6 +210,7 @@ Bool gf_sc_fit_world_to_screen(GF_Compositor *compositor)
                return 0;
        }
        memset(&tr_state, 0, sizeof(GF_TraverseState));
+       gf_mx_init(tr_state.model_matrix);
        tr_state.traversing_mode = TRAVERSE_GET_BOUNDS;
        tr_state.visual = compositor->visual;
        gf_node_traverse(top, &tr_state);
@@ -255,29 +257,37 @@ Bool gf_sc_fit_world_to_screen(GF_Compositor *compositor)
        return 1;
 }
 
+//#define SCALE_NAV
+
 static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event *ev)
 {
        Fixed x, y, trans_scale;
        Fixed dx, dy, key_trans, key_pan, key_exam;
        s32 key_inv;
        u32 keys;
+#ifdef SCALE_NAV
        Bool is_pixel_metrics;
+#endif
        GF_Camera *cam;
        Fixed zoom = compositor->zoom;
 
        cam = NULL;
-       if (compositor->active_layer) {
 #ifndef GPAC_DISABLE_VRML
+       if (compositor->active_layer) {
                cam = compositor_layer3d_get_camera(compositor->active_layer);
-               is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(compositor->active_layer));
+#ifdef SCALE_NAV
+       is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(compositor->active_layer));
 #endif
        } 
+#endif
 
        if (!cam) {
                cam = &compositor->visual->camera;
                assert(compositor);
                assert(compositor->scene);
+#ifdef SCALE_NAV
                is_pixel_metrics = compositor->traverse_state->pixel_metrics;
+#endif
        }
 
        keys = compositor->key_states;
@@ -292,11 +302,14 @@ static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event
        dx = (x - compositor->grab_x); 
        dy = (compositor->grab_y - y);
 
-/*     trans_scale = is_pixel_metrics ? cam->width/2 : INT2FIX(10);
+#ifdef SCALE_NAV
+       trans_scale = is_pixel_metrics ? cam->width/2 : INT2FIX(10);
        key_trans = is_pixel_metrics ? INT2FIX(10) : cam->avatar_size.x;
-*/
+#else
        trans_scale = cam->width/20;
        key_trans = cam->avatar_size.x/2;
+#endif
+
        if (cam->world_bbox.is_set && (key_trans*5 > cam->world_bbox.radius)) {
                key_trans = cam->world_bbox.radius / 100;
        }
@@ -450,9 +463,9 @@ static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event
                                compositor->visual->camera.start_zoom = compositor->zoom;
                                compositor->zoom = FIX_ONE;
                                compositor->interoccular_offset = 0;
-                               compositor->view_distance_offset = 0;
+                               compositor->focus_distance = 0;
                                compositor->interoccular_offset = 0;
-                               compositor->view_distance_offset = 0;
+                               compositor->focus_distance = 0;
                                compositor_3d_reset_camera(compositor);
                        }
                        break;
@@ -467,9 +480,10 @@ static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event
                case GF_KEY_RIGHT:
                        if (keys & GF_KEY_MOD_ALT) {
                                if ( (keys & GF_KEY_MOD_SHIFT) && (compositor->visual->nb_views > 1) ) {
-                                       compositor->view_distance_offset += key_inv * (is_pixel_metrics ? INT2FIX(1) : FLT2FIX(0.1));
+                                       /*+ or - 10 cm*/
+                                       compositor->focus_distance += INT2FIX(key_inv);
                                        cam->flags |= CAM_IS_DIRTY;
-                                       fprintf(stdout, "AutoStereo view distance %f\n", FIX2FLT(compositor->view_distance_offset + compositor->video_out->view_distance)/100);
+                                       fprintf(stderr, "AutoStereo view distance %f - focus %f\n", FIX2FLT(compositor->video_out->view_distance)/100, FIX2FLT(compositor->focus_distance)/100);
                                        gf_sc_invalidate(compositor, NULL);
                                        return 1;
                                }
@@ -504,7 +518,7 @@ static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event
                        if (keys & GF_KEY_MOD_ALT) {
                                if ( (keys & GF_KEY_MOD_SHIFT) && (compositor->visual->nb_views > 1) ) {
                                        compositor->interoccular_offset += FLT2FIX(0.5) * key_inv;
-                                       fprintf(stdout, "AutoStereo interoccular distance %f\n", FIX2FLT(compositor->interoccular_offset)+6.8);
+                                       fprintf(stderr, "AutoStereo interoccular distance %f\n", FIX2FLT(compositor->interoccular_distance + compositor->interoccular_offset));
                                        cam->flags |= CAM_IS_DIRTY;
                                        gf_sc_invalidate(compositor, NULL);
                                        return 1;
index 6968d6918e920ccd6fd02f5eab4f7f0be27fbc00..94934a42c3aac2efaea6c63691f346e59739dca4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 22bf6bbc8d9da53d55e985a3b4cf3b689b1c0eeb..749abc9f6aae58b7bc29875ec587f378aad1b45e 100644 (file)
@@ -1,9 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Yi-Zhen Zhang, Jean Le Feuvre
- *
- *                     Copyright (c) ENST 2005-200X
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -335,6 +334,7 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr
        gf_mx2d_copy(backup, tr_state->transform);
        gf_mx2d_init(tr_state->transform);
 #else
+       gf_mx2d_copy(backup, tr_state->transform);
        if (auto_fit_vp) {
                if ((tr_state->vp_size.x != cache->orig_vp.x) || (tr_state->vp_size.y != cache->orig_vp.y)) {
                        GF_Matrix2D m;
index da6d7137e51c0c6d9701c1be40a769f2d1ed34d2..85cbc40aa84ef8fb671e217f8b0a18142e3d3025 100644 (file)
@@ -1,9 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Yi-Zhen Zhang, Jean Le Feuvre
- *
- *                     Copyright (c) ENST 2005-200X
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2006-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index c45be6dd7d7d3a1c4ba945b17290464794b375bf..151783690ebdfdaf1d2d91ffe685219a2c4dd740 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index b6070d883c693f51d1b45e93929ba00630feefd4..1a319e713b9756e4e6275a4d6b8536cd6815f549 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2010-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 45fff2c8a4d7abb115a0335b50fefaf681ddbb81..6458058fa2c45c622172dbbac68304adde4a7301 100644 (file)
@@ -2,8 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Jean Le Feuvre 
- *
- *                     Copyright (c) ENST 2007-200X
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 0d309b03a123d4f499d4ea39ac4b5dc59ec54877..6921f3288da60846d84f3c1808309a1a4789af42 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index bf457d67b9ef5078549a8b5f70ab23e8cff5b012..0620a81a563662819e6590ceeb9d2b40fd0e9715 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -332,7 +332,10 @@ static void svg_traverse_svg(GF_Node *node, void *rs, Bool is_destroy)
        gf_mx2d_copy(vb_bck, tr_state->vb_transform);
 
 #ifndef GPAC_DISABLE_3D
-       if (tr_state->visual->type_3d) gf_mx_copy(bck_mx, tr_state->model_matrix);
+       //commented to get rid of GCC warning
+        //if (tr_state->visual->type_3d)
+         gf_mx_copy(bck_mx, tr_state->model_matrix);
+        
 #endif
        
        invalidate_flag = tr_state->invalidate_all;
index 648c76400493a778d350e129f8671e2d646731a2..90cc6bbc7bdff0c0f536cc685b3ebb9a3df450ed 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 63a1164d437fbb0622a94ac12153ae8ef51ce370..fa71565a0cf96acb2ee0cc489486f55aaf843606 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 90ac26c508bc21de420a6d469e515b69b2e6df61..2efb38951db95ae4a60e7fcadf2a1e23a40bc555 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004
+ *                     Authors: Cyril Concolato 
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 8f5cfc45e3d0eb395bbfae44ec08ebc5be967556..9c90f2360cf20bd8f8e1470e136597c140490601 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 42db1f533bc842e2e6bdf9004e238ea07cd8a6d5..101b30ace05bf38da11ab283423ece2f25019889 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 273df27c65c3b6df15fe7a03f7a1dda554ca1014..b205bea667485753e11a7d0036725388476ce26d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -940,7 +941,7 @@ static Bool gf_sc_texture_enable_matte_texture(GF_Node *n)
 #else
 
 /*To remove: gcc 4.6 introduces this warning*/
-#if __GNUC__ == 4 && __GNUC_MINOR__ == 6
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Waddress"
 #endif
@@ -1032,9 +1033,9 @@ static Bool gf_sc_texture_enable_matte_texture(GF_Node *n)
                GLTEXPARAM( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
                glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,1,1,0,GL_RGBA,GL_UNSIGNED_BYTE,texture);
                
-               /* fin de la génération de la texture donnée par la fraction ! */
+               /* fin de la g\E9n\E9ration de la texture donn\E9e par la fraction ! */
                
-               /* mélange effectif des textures ! } */
+               /* m\E9lange effectif des textures ! } */
                glActiveTexture(GL_TEXTURE1);
                tx_bind(b_surf);
 
@@ -1102,7 +1103,7 @@ static Bool gf_sc_texture_enable_matte_texture(GF_Node *n)
        }
        /* end INVERT */
 
-       /* opération REPLACE_ALPHA */
+       /* op\E9ration REPLACE_ALPHA */
        if (!strcmp(action,"REPLACE_ALPHA")) {
                glActiveTexture(GL_TEXTURE0);
                tx_bind(b_surf);
index 68509e69665e8a4312f1bf894b5f2682dabbf5e8..85a76702fe23e319503a8555321ee064a2b77ca0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 5cfd8a366d0e696b655559f1a287d29290661cc6..2b70ce48aa0bff269def07e062f9f514847c03c3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 156082da6767fb69946efa6eb4199bd475b75229..3705a2ba60983ff5ee135e3477cd9ca3172a3087 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 62d8580109a350ff455c7951610ebf46a20e7195..61052ef7a031e80eef1991ac9f033e86da5e154e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index e5840eab09bffbd753759ad3b83c11cfed7ad97c..5516cb5c59e2c4c78a0b0f04b2061cb6991c64bc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index a458758814af17a9acfa066e2be0fb97ec2c9073..f3629079438ddfaa9e47b2f0840c8624568040a2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -356,7 +357,7 @@ void visual_3d_setup_projection(GF_TraverseState *tr_state, Bool is_layer)
                Fixed interocular_dist_pixel;
                Fixed delta = 0;
 
-               interocular_dist_pixel = FLT2FIX(6.8f) + tr_state->visual->compositor->interoccular_offset;
+               interocular_dist_pixel = tr_state->visual->compositor->interoccular_distance + tr_state->visual->compositor->interoccular_offset;
 
                view_idx = tr_state->visual->current_view;
                view_idx -= tr_state->visual->nb_views/2;
@@ -367,9 +368,9 @@ void visual_3d_setup_projection(GF_TraverseState *tr_state, Bool is_layer)
                if (tr_state->visual->reverse_views) delta = - delta;
 
                tr_state->camera->flags |= CAM_IS_DIRTY;
-               camera_update(tr_state->camera, &tr_state->transform, tr_state->visual->center_coords, delta, tr_state->visual->compositor->video_out->view_distance, tr_state->visual->compositor->view_distance_offset, tr_state->visual->camera_layout);
+               camera_update_stereo(tr_state->camera, &tr_state->transform, tr_state->visual->center_coords, delta, tr_state->visual->compositor->video_out->view_distance, tr_state->visual->compositor->focus_distance, tr_state->visual->camera_layout);
        } else {
-               camera_update(tr_state->camera, &tr_state->transform, tr_state->visual->center_coords, 0, 0, 0, GF_3D_CAMERA_STRAIGHT);
+               camera_update(tr_state->camera, &tr_state->transform, tr_state->visual->center_coords);
        }
 
        /*setup projection/modelview*/
index 545a248795b689d00a54a44c8296d80b9bb83e85..6f5787a7aba1d9cdcc563321f0ff0158364643bd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index e4d50bea2f781cc49e5c23c04019573cf0d86d7c..4fe850ce7982163fc2e9428ff17cab879f8d612c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
@@ -1115,7 +1116,7 @@ void VS3D_DrawMeshIntern(GF_TraverseState *tr_state, GF_Mesh *mesh)
 
 #if defined(GPAC_FIXED_POINT) && !defined(GPAC_USE_OGL_ES)
        if (color_array) gf_free(color_array);
-       if (!mesh->mesh_type && !(mesh->flags & MESH_NO_TEXTURE)) {
+       if (tr_state->mesh_num_textures && !mesh->mesh_type && !(mesh->flags & MESH_NO_TEXTURE)) {
                glMatrixMode(GL_TEXTURE);
                glPopMatrix();
                glMatrixMode(GL_MODELVIEW);
index c30a6d7c6f2dfe5b8819e17af36a8a4101a80614..a31d7236afa523a99955d65da2ab600fa1f414f2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Compositor sub-project
index 04692ab71c36eb2e4c04597d69c6d37e92fbefe0..102796855a12576e622b4a56f9a818f506b0c08c 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
- *                     Copyright (c) ENST 2008 - 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC 
 #pragma comment (linker, EXPORT_SYMBOL(gf_asprintf) )
 
 /* Ring Buffer */
+#ifndef GPAC_DISABLE_PLAYER
 #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_read) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_write) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_available_for_read ) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_del) )
+#endif
 
 /* List */
 #pragma comment (linker, EXPORT_SYMBOL(gf_list_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_bs_get_position) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_bs_get_size) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_bs_get_refreshed_size) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_bs_set_output_buffering) )
 
 /* Thread */
 #pragma comment (linker, EXPORT_SYMBOL(gf_th_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_url_is_local) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_url_get_absolute_path) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_url_concatenate) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_url_get_resource_path) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_url_get_resource_name) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_utc_time_since_1970) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_net_get_ntp) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_net_has_ipv6) )
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_init) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_new) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_force_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_del) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_remove) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_save) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_filename) )
 
 
+#ifndef GPAC_DISABLE_PLAYER
 #pragma comment (linker, EXPORT_SYMBOL(gf_modules_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_modules_del) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_modules_refresh) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_modules_get_option) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_modules_set_option) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_modules_get_config) )
+#endif
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_utf8_wcstombs) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_utf8_mbstowcs) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_utf8_wcslen) )
+#ifndef GPAC_DISABLE_PLAYER
 #pragma comment (linker, EXPORT_SYMBOL(gf_utf8_is_right_to_left) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_utf8_reorder_bidi) )
+#endif
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_new_simple) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_del) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_process) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_process_headers) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_get_cache_name) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_get_stats) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_fetch_data) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_asin) )
 #endif /*GPAC_FIXED_POINT*/
 
+#ifndef GPAC_DISABLE_PLAYER
 #pragma comment (linker, EXPORT_SYMBOL(gf_angle_diff) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_v2d_len) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_v2d_from_polar) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_path_get_outline) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_path_point_over) )
 
+#endif //GPAC_DISABLE_PLAYER
+
 /*mpeg4_odf.h exports*/
 #pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_new) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_del) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_open_progressive) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_missing_bytes) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_fragmented) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_fragmented_duration) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_fragments_count) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_track_fragmented) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_release_segment) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_open_segment) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_ismacryp_media) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_ismacryp_delete_sample) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_ismacryp_sample) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_avc_svc_type) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_avc_config_get) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_svc_config_get) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_3gp_config_get) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_meta_primary_item_id) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_JPEG2000) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_rvc_config) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_rap_roll_info) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_reset_fragment_info) )
 
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_rvc_config) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_sample_rap_group) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_sample_roll_group) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_composition_offset_mode) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_output_buffering) )
+
 
 #ifndef GPAC_DISABLE_ISOM_HINTING
 #pragma comment (linker, EXPORT_SYMBOL(gf_isom_setup_hint_track) )
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_map_esd) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_get_file_hash) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_reduce_aspect_ratio) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_get_reduced_frame_rate) )
 
 #endif /*GPAC_DISABLE_ISOM*/
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_import_chapters) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_change_pl) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_avc_rewrite_samples) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_split_svc) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_merge_svc) )
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
 #ifndef GPAC_DISABLE_ISOM_WRITE
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_set_pes_framing) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_stream_name) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_crc32_check) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_restamp) )
+
 
 /* carousel.h */
-#ifndef GPAC_DISABLE_DSMCC
+#ifdef GPAC_ENABLE_DSMCC
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_channel_application_info) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_process_dsmcc) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_init_dsmcc_overlord) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_dmscc_overlord) )
-#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_demux_dmscc_init) )
 #endif
+#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_demux_dmscc_init) )
 
 
 #ifndef GPAC_DISABLE_MPEG2TS_MUX
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_wget_with_cache) )
 
 #ifndef GPAC_DISABLE_ISOM_WRITE
-#pragma comment (linker, EXPORT_SYMBOL(gf_media_mpd_start) )
-#pragma comment (linker, EXPORT_SYMBOL(gf_media_mpd_end) )
+/*to be removed once TS fragmenter is moved to libgpac */
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_mpd_format_segment_name) )
 #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_fragment_file) )
 #endif
 #endif
 
+#pragma comment (linker, EXPORT_SYMBOL(gf_dasher_segment_files) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dasher_next_update_time) )
+
 /* dvb_mpe.h */
 #ifdef GPAC_ENST_PRIVATE
 #pragma comment (linker, EXPORT_SYMBOL(gf_dvb_mpe_section_del) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dvb_mpe_shutdown) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_print_mpe_info) )
 #endif
+
+#ifndef GPAC_DISABLE_DASH_CLIENT
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_new) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_del) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_open) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_close) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_url) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_group_count) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_group_udta) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_set_group_udta) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_is_group_selected) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_info) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_switch_quality) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_duration) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_check_mpd_root_type) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_get_segment_mime) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_get_segment_init_url) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_select) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_groups_set_language) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_in_last_period) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_period_switch_status) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_request_period_switch) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_is_running) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_get_num_segments_ready) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_discard_segment) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_get_next_segment_location) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_get_max_segments_in_cache) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_set_group_done) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_in_period_setup) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_seek) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_get_playback_start_range) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_segment_switch_forced) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_current_segment_start_time) )
+#pragma comment (linker, EXPORT_SYMBOL(gf_dash_group_get_presentation_time_offset) )
+
+#endif
+
index b0444f011a60f59ffc5162dc1670f27c7f50de16..e3bce0749772f2c75a54ad2ca5122daf21055a07 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index 20d178e4a48f2fc8311733e6931c862a68c0cfe2..ed30a39843090b236615beefeccd12004f29e087 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index 067b69847cf48b0c457e85aa34248ce2c7d901fa..0ed2abb0877bfe7f4ae753693613a89b562807a8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / RTP input module
@@ -44,7 +45,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char
        hdr_bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);
        aux_bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);
 
-//     printf("parsing packet %d size %d ts %d M %d\n", hdr->SequenceNumber, size, hdr->TimeStamp, hdr->Marker);
+//     fprintf(stderr, "parsing packet %d size %d ts %d M %d\n", hdr->SequenceNumber, size, hdr->TimeStamp, hdr->Marker);
 
        /*global AU header len*/
        au_hdr_size = 0;
@@ -593,15 +594,19 @@ static void gf_rtp_h264_flush(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, Bool m
        gf_bs_del(rtp->inter_bs);
        rtp->inter_bs = NULL;
        nal_s = data_size-4;
-       data[0] = nal_s>>24; data[1] = nal_s>>16; data[2] = nal_s>>8; data[3] = nal_s&0xFF;
+
+       if (rtp->flags & GF_RTP_AVC_USE_ANNEX_B) {
+               data[0] = data[1] = data[2] = 0; data[3] = 1;
+       } else {
+               data[0] = nal_s>>24; data[1] = nal_s>>16; data[2] = nal_s>>8; data[3] = nal_s&0xFF;
+       }
        /*set F-bit since nal is corrupted*/
        if (missed_end) data[4] |= 0x80;
 
        rtp->sl_hdr.accessUnitEndFlag = (rtp->flags & GF_RTP_UNRELIABLE_M) ? 0 : hdr->Marker;
        rtp->sl_hdr.compositionTimeStampFlag = 1;
        rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;
-       rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;
-       rtp->sl_hdr.decodingTimeStampFlag = 1;
+       rtp->sl_hdr.decodingTimeStampFlag = 0;
        rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK);
        rtp->sl_hdr.accessUnitStartFlag = 0;
        rtp->sl_hdr.randomAccessPointFlag = 0;
@@ -626,8 +631,7 @@ void gf_rtp_parse_h264(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload
                rtp->sl_hdr.accessUnitStartFlag = 1;
                rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;
                rtp->sl_hdr.compositionTimeStampFlag = 1;
-               rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;
-               rtp->sl_hdr.decodingTimeStampFlag = 1;
+               rtp->sl_hdr.decodingTimeStampFlag = 0;
                rtp->sl_hdr.randomAccessPointFlag = 0;
        } else if (rtp->sl_hdr.accessUnitEndFlag) {
                rtp->flags |= GF_RTP_UNRELIABLE_M;
@@ -644,9 +648,15 @@ void gf_rtp_parse_h264(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload
                        return;
 
                rtp->sl_hdr.accessUnitEndFlag = 0;
-               /*signal NALU size on 4 bytes*/
-               nalhdr[0] = size>>24; nalhdr[1] = size>>16; nalhdr[2] = size>>8; nalhdr[3] = size&0xFF;
+
+               if (rtp->flags & GF_RTP_AVC_USE_ANNEX_B) {
+                       nalhdr[0] = 0; nalhdr[1] = 0; nalhdr[2] = 0; nalhdr[3] = 1;
+               } else {
+                       /*signal NALU size on 4 bytes*/
+                       nalhdr[0] = size>>24; nalhdr[1] = size>>16; nalhdr[2] = size>>8; nalhdr[3] = size&0xFF;
+               }
                rtp->on_sl_packet(rtp->udta, nalhdr, 4, &rtp->sl_hdr, GF_OK);
+
                rtp->sl_hdr.accessUnitStartFlag = 0;
                rtp->sl_hdr.compositionTimeStampFlag = 0;
                rtp->sl_hdr.accessUnitEndFlag = (rtp->flags & GF_RTP_UNRELIABLE_M) ? 0 : hdr->Marker;
@@ -667,9 +677,13 @@ void gf_rtp_parse_h264(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload
                        }
                        if (rtp->flags & GF_RTP_AVC_WAIT_RAP) send = 0;
 
-                       /*signal NALU size on 4 bytes*/
-                       nalhdr[0] = nal_size>>24; nalhdr[1] = nal_size>>16; nalhdr[2] = nal_size>>8; nalhdr[3] = nal_size&0xFF;
                        if (send) {
+                               /*signal NALU size on 4 bytes*/
+                               if (rtp->flags & GF_RTP_AVC_USE_ANNEX_B) {
+                                       nalhdr[0] = 0; nalhdr[1] = 0; nalhdr[2] = 0; nalhdr[3] = 1;
+                               } else {
+                                       nalhdr[0] = nal_size>>24; nalhdr[1] = nal_size>>16; nalhdr[2] = nal_size>>8; nalhdr[3] = nal_size&0xFF;
+                               }
                                rtp->on_sl_packet(rtp->udta, nalhdr, 4, &rtp->sl_hdr, GF_OK);
                                rtp->sl_hdr.accessUnitStartFlag = 0;
                                rtp->sl_hdr.compositionTimeStampFlag = 0;
index f7c4049998bc62d1156d7c0d1ea66755a1f6f8f1..071327feae83713033ffed2d074992efc36e6c2c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index ffc7c7cd43c671172d61a0edeeb3ee25e94964fe..58d792381c4dfd0ee93715bb95e037d431bd85d1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index 660133cae22f3f6440a4ba778677f70535a5477e..8ed5dd03a00ccab23ffbdf3b7de4ac65c0cba99c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index c9d59319e4c0a3832821dbcfbb4b514a7defc1d3..7dddb71ab1503df860353a1db7111bc49fdbb917 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index 335d4603467dbbc14dadcec200d2a3ce1a6397a7..4d638a02482ae85dcef74726016e2e27b5494af0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index ef1c9d7e20d73fff9285a4116e65036868ce0743..183349ff2f889b5c2234b479c4bf29dc08985f49 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index 3d3da54b32f73184610abe14ffc99846e45c155c..6f1199a500d95b7f254ff63c23b6eaa34c0426ba 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
@@ -100,8 +101,6 @@ GF_Err gf_rtsp_refill_buffer(GF_RTSPSession *sess)
        res = sess->CurrentSize - sess->CurrentPos;
        if (!res) return gf_rtsp_fill_buffer(sess);
 
-//     printf("Forcing reading\n");
-       
        ptr = (char *)gf_malloc(sizeof(char) * res);
        memcpy(ptr, sess->TCPBuffer+sess->CurrentPos, res);
        memcpy(sess->TCPBuffer, ptr, res);
index c4d01361da7cb9f2162c73c70e13219c90ff2301..d1a37de4dec380a6379171947e71fbdc847671db 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
@@ -702,7 +703,7 @@ GF_Err gf_rtsp_send_response(GF_RTSPSession *sess, GF_RTSPResponse *rsp)
        //send buffer
        e = gf_rtsp_send_data(sess, buffer, size);
        if (e) return e;
-//     printf("RTSP Send Response\n\n%s\n\n", buffer);
+//     fprintf(stderr, "RTSP Send Response\n\n%s\n\n", buffer);
 
 exit:
        if (buffer) gf_free(buffer);
index a509bab22df4ffe15b89138662b39423fff012b6..e8e6c64f0859887a4ba657e70d4a82f1c2acc22a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index c0eb06d3fbce98b8ebad6ce31bf94958e809f2a7..6d3972dd14bc68b9521aa73cdda9a7fa8fe0335e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
index b75f512981e43351a410c625ee01742b5e08a17f..e88e74d147c3922e7c7548255212c076979a4a3e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
 #include <gpac/internal/isomedia_dev.h>
 #include <gpac/constants.h>
 
+#ifndef GPAC_DISABLE_AV_PARSERS
+#include <gpac/internal/media_dev.h>
+#endif
+
 #ifndef GPAC_DISABLE_ISOM
 
 static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg)
@@ -38,6 +43,9 @@ static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg)
        cfg_new->nal_unit_size = cfg->nal_unit_size;
        cfg_new->profile_compatibility = cfg->profile_compatibility;
        cfg_new->complete_representation = cfg->complete_representation;
+       cfg_new->chroma_bit_depth = cfg->chroma_bit_depth;
+       cfg_new->luma_bit_depth = cfg->luma_bit_depth;
+       cfg_new->chroma_format = cfg->chroma_format;
 
        count = gf_list_count(cfg->sequenceParameterSets);
        for (i=0; i<count; i++) {
@@ -58,6 +66,19 @@ static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg)
                memcpy(p2->data, p1->data, sizeof(char)*p1->size);
                gf_list_add(cfg_new->pictureParameterSets, p2);
        }
+
+       if (cfg->sequenceParameterSetExtensions) {
+               cfg_new->sequenceParameterSetExtensions = gf_list_new();
+               count = gf_list_count(cfg->sequenceParameterSetExtensions);
+               for (i=0; i<count; i++) {
+                       p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->sequenceParameterSetExtensions, i);
+                       p2 = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
+                       p2->size = p1->size;
+                       p2->data = (char*)gf_malloc(sizeof(char)*p1->size);
+                       memcpy(p2->data, p1->data, sizeof(char)*p1->size);
+                       gf_list_add(cfg_new->sequenceParameterSetExtensions, p2);
+               }
+       }
        return cfg_new; 
 }
 
@@ -198,8 +219,8 @@ GF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfi
        entry->avc_config = (GF_AVCConfigurationBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_AVCC);
        entry->avc_config->config = AVC_DuplicateConfig(cfg);
        entry->dataReferenceIndex = dataRefIndex;
-       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry);
-       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
+       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        AVC_RewriteESDescriptor(entry);
        return e;
 }
@@ -214,7 +235,7 @@ static GF_Err gf_isom_avc_config_update_ex(GF_ISOFile *the_file, u32 trackNumber
        if (e) return e;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !trak->Media || !cfg || !DescriptionIndex) return GF_BAD_PARAM;
-       entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!entry) return GF_BAD_PARAM;
        switch (entry->type) {
        case GF_ISOM_BOX_TYPE_AVC1:
@@ -267,6 +288,35 @@ GF_Err gf_isom_svc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 Desc
        return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, is_add ? 1 : 2);
 }
 
+GF_Err gf_isom_svc_config_del(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_Err e;
+       GF_MPEGVisualSampleEntryBox *entry;
+
+       e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
+       if (e) return e;
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak || !trak->Media || !DescriptionIndex) return GF_BAD_PARAM;
+       entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
+       if (!entry) return GF_BAD_PARAM;
+       switch (entry->type) {
+       case GF_ISOM_BOX_TYPE_AVC1:
+       case GF_ISOM_BOX_TYPE_AVC2:
+       case GF_ISOM_BOX_TYPE_SVC1:
+               break;
+       default:
+               return GF_BAD_PARAM;
+       }
+
+       if (entry->svc_config) {
+                       gf_isom_box_del((GF_Box*)entry->svc_config);
+                       entry->svc_config = NULL;
+               }
+       AVC_RewriteESDescriptor(entry);
+       return GF_OK;
+}
+
 GF_EXPORT
 GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber)
 {
@@ -279,7 +329,7 @@ GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber)
        if (e) return e;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !trak->Media) return GF_BAD_PARAM;
-       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0);
+       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, 0);
        if (!entry) return GF_OK;
        switch (entry->type) {
        case GF_ISOM_BOX_TYPE_AVC1:
@@ -296,6 +346,40 @@ GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber)
        return GF_OK;
 }
 
+GF_Err gf_isom_svc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_Err e;
+       u32 dataRefIndex;
+       GF_MPEGVisualSampleEntryBox *entry;
+
+       e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
+       if (e) return e;
+       
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM;
+
+       //get or create the data ref
+       e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
+       if (e) return e;
+       if (!dataRefIndex) {
+               e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
+               if (e) return e;
+       }
+       trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
+
+       //create a new entry
+       entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_SVC1);
+       if (!entry) return GF_OUT_OF_MEM;
+       entry->svc_config = (GF_AVCConfigurationBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_SVCC);
+       entry->svc_config->config = AVC_DuplicateConfig(cfg);
+       entry->dataReferenceIndex = dataRefIndex;
+       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
+       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
+       AVC_RewriteESDescriptor(entry);
+       return e;
+}
+
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 GF_EXPORT
@@ -305,7 +389,7 @@ GF_AVCConfig *gf_isom_avc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32
        GF_MPEGVisualSampleEntryBox *entry;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !trak->Media || !DescriptionIndex) return NULL;
-       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!entry) return NULL;
        //if (entry->type != GF_ISOM_BOX_TYPE_AVC1) return NULL;
        if (!entry->avc_config) return NULL;
@@ -319,12 +403,36 @@ GF_AVCConfig *gf_isom_svc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32
        GF_MPEGVisualSampleEntryBox *entry;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !trak->Media || !DescriptionIndex) return NULL;
-       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!entry) return NULL;
        if (!entry->svc_config) return NULL;
        return AVC_DuplicateConfig(entry->svc_config->config);
 }
 
+GF_EXPORT
+u32 gf_isom_get_avc_svc_type(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_MPEGVisualSampleEntryBox *entry;
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak || !trak->Media || !DescriptionIndex) return GF_ISOM_AVCTYPE_NONE;
+       entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
+       if (!entry) return GF_ISOM_AVCTYPE_NONE;
+       switch (entry->type) {
+       case GF_ISOM_BOX_TYPE_AVC1:
+       case GF_ISOM_BOX_TYPE_AVC2:
+       case GF_ISOM_BOX_TYPE_SVC1:
+               break;
+       default:
+               return GF_ISOM_AVCTYPE_NONE;
+       }
+       if (entry->avc_config && !entry->svc_config) return GF_ISOM_AVCTYPE_AVC_ONLY;
+       if (entry->avc_config && entry->svc_config) return GF_ISOM_AVCTYPE_AVC_SVC;
+       if (!entry->avc_config && entry->svc_config) return GF_ISOM_AVCTYPE_SVC_ONLY;
+       return GF_ISOM_AVCTYPE_NONE;
+}
+
+
 void btrt_del(GF_Box *s)
 {
        GF_MPEG4BitRateBox *ptr = (GF_MPEG4BitRateBox *)s;
@@ -463,12 +571,15 @@ GF_Err avcc_Read(GF_Box *s, GF_BitStream *bs)
        gf_bs_read_int(bs, 3);
        count = gf_bs_read_int(bs, 5);
 
+       ptr->size -= 7; //including 2nd count
+
        for (i=0; i<count; i++) {
                GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *) gf_malloc(sizeof(GF_AVCConfigSlot));
                sl->size = gf_bs_read_u16(bs);
                sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
                gf_bs_read_data(bs, sl->data, sl->size);
                gf_list_add(ptr->config->sequenceParameterSets, sl);
+               ptr->size -= 2+sl->size;
        }
 
        count = gf_bs_read_u8(bs);
@@ -478,6 +589,57 @@ GF_Err avcc_Read(GF_Box *s, GF_BitStream *bs)
                sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
                gf_bs_read_data(bs, sl->data, sl->size);
                gf_list_add(ptr->config->pictureParameterSets, sl);
+               ptr->size -= 2+sl->size;
+       }
+
+       if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) {
+
+               switch (ptr->config->AVCProfileIndication) {
+               case 100:
+               case 110:
+               case 122:
+               case 144:
+                       if (!ptr->size) {
+#ifndef GPAC_DISABLE_AV_PARSERS
+                               AVCState avc;
+                               s32 idx, vui_flag_pos;
+                               GF_AVCConfigSlot *sl = gf_list_get(ptr->config->sequenceParameterSets, 0);
+                               idx = AVC_ReadSeqInfo(sl->data+1, sl->size-1, &avc, 0, &vui_flag_pos);
+                               if (idx>=0) {
+                                       ptr->config->chroma_format = avc.sps[idx].chroma_format;
+                                       ptr->config->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8;
+                                       ptr->config->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8;
+                               }
+#else
+                               /*set default values ...*/
+                               ptr->config->chroma_format = 1;
+                               ptr->config->luma_bit_depth = 8;
+                               ptr->config->chroma_bit_depth = 8;
+#endif
+                               return GF_OK;
+                       }
+                       gf_bs_read_int(bs, 6);
+                       ptr->config->chroma_format = gf_bs_read_int(bs, 2);
+                       gf_bs_read_int(bs, 5);
+                       ptr->config->luma_bit_depth = 8 + gf_bs_read_int(bs, 3);
+                       gf_bs_read_int(bs, 5);
+                       ptr->config->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3);
+
+                       count = gf_bs_read_int(bs, 8);
+                       ptr->size -= 4;
+                       if (count) {
+                               ptr->config->sequenceParameterSetExtensions = gf_list_new();
+                               for (i=0; i<count; i++) {
+                                       GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_malloc(sizeof(GF_AVCConfigSlot));
+                                       sl->size = gf_bs_read_u16(bs);
+                                       sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
+                                       gf_bs_read_data(bs, sl->data, sl->size);
+                                       gf_list_add(ptr->config->sequenceParameterSetExtensions, sl);
+                                       ptr->size -= sl->size + 2;
+                               }
+                       }
+                       break;
+               }
        }
        return GF_OK;
 }
@@ -528,6 +690,31 @@ GF_Err avcc_Write(GF_Box *s, GF_BitStream *bs)
                gf_bs_write_u16(bs, sl->size);
                gf_bs_write_data(bs, sl->data, sl->size);
        }
+
+
+       if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) {
+               switch (ptr->config->AVCProfileIndication) {
+               case 100:
+               case 110:
+               case 122:
+               case 144:
+                       gf_bs_write_int(bs, 0xFF, 6);
+                       gf_bs_write_int(bs, ptr->config->chroma_format, 2);
+                       gf_bs_write_int(bs, 0xFF, 5);
+                       gf_bs_write_int(bs, ptr->config->luma_bit_depth - 8, 3);
+                       gf_bs_write_int(bs, 0xFF, 5);
+                       gf_bs_write_int(bs, ptr->config->chroma_bit_depth - 8, 3);
+
+                       count = ptr->config->sequenceParameterSetExtensions ? gf_list_count(ptr->config->sequenceParameterSetExtensions) : 0;
+                       gf_bs_write_u8(bs, count);
+                       for (i=0; i<count; i++) {
+                               GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *) gf_list_get(ptr->config->sequenceParameterSetExtensions, i);
+                               gf_bs_write_u16(bs, sl->size);
+                               gf_bs_write_data(bs, sl->data, sl->size);
+                       }
+                       break;
+               }
+       }
        return GF_OK;
 }
 GF_Err avcc_Size(GF_Box *s)
@@ -543,9 +730,26 @@ GF_Err avcc_Size(GF_Box *s)
        }
        ptr->size += 7;
        count = gf_list_count(ptr->config->sequenceParameterSets);
-       for (i=0; i<count; i++) ptr->size += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->sequenceParameterSets, i))->size;
+       for (i=0; i<count; i++) 
+               ptr->size += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->sequenceParameterSets, i))->size;
+
        count = gf_list_count(ptr->config->pictureParameterSets);
-       for (i=0; i<count; i++) ptr->size += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->pictureParameterSets, i))->size;
+       for (i=0; i<count; i++) 
+               ptr->size += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->pictureParameterSets, i))->size;
+
+       if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) {
+               switch (ptr->config->AVCProfileIndication) {
+               case 100:
+               case 110:
+               case 122:
+               case 144:
+                       ptr->size += 4;
+                       count = ptr->config->sequenceParameterSetExtensions ?gf_list_count(ptr->config->sequenceParameterSetExtensions) : 0;
+                       for (i=0; i<count; i++) 
+                               ptr->size += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->sequenceParameterSetExtensions, i))->size;
+                       break;
+               }
+       }
        return GF_OK;
 }
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
index df6b8f5d6a18a76c3f6fe271ff5a027ae19136fe..f6b7c53c857c0d946a4ba0b20fe7a3c8fb0f89b0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -30,8 +31,9 @@ void gppa_del(GF_Box *s)
 {
        GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
+
        if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
-       if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info);
        gf_free(ptr);
 }
 
@@ -50,11 +52,8 @@ GF_Err gppa_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *gppa_New(u32 type)
 {
-       GF_3GPPAudioSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_3GPPAudioSampleEntryBox);
-       if (tmp == NULL) return NULL;
+       ISOM_DECL_BOX_ALLOC(GF_3GPPAudioSampleEntryBox, type);
        gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
-       tmp->type = type;
        return (GF_Box *)tmp;
 }
 
@@ -89,19 +88,16 @@ GF_Err gppa_Size(GF_Box *s)
 
 GF_Box *gppv_New(u32 type)
 {
-       GF_3GPPVisualSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_3GPPVisualSampleEntryBox);
-       if (tmp == NULL) return NULL;
+       ISOM_DECL_BOX_ALLOC(GF_3GPPVisualSampleEntryBox, type);
        gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
-       tmp->type = type;
        return (GF_Box *)tmp;
 }
 void gppv_del(GF_Box *s)
 {
        GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
        if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
-       if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info);
        gf_free(ptr);
 }
 
@@ -148,10 +144,7 @@ GF_Err gppv_Size(GF_Box *s)
 
 GF_Box *gppc_New(u32 type)
 {
-       GF_3GPPConfigBox *tmp = (GF_3GPPConfigBox *) gf_malloc(sizeof(GF_3GPPConfigBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_3GPPConfigBox));
-       tmp->type = type;
+       ISOM_DECL_BOX_ALLOC(GF_3GPPConfigBox, type);
        return (GF_Box *)tmp;
 }
 
@@ -252,10 +245,7 @@ GF_Err gppc_Size(GF_Box *s)
 
 GF_Box *ftab_New()
 {
-       GF_FontTableBox *tmp;
-       GF_SAFEALLOC(tmp, GF_FontTableBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_FTAB;
+       ISOM_DECL_BOX_ALLOC(GF_FontTableBox, GF_ISOM_BOX_TYPE_FTAB);
        return (GF_Box *) tmp;
 }
 void ftab_del(GF_Box *s)
@@ -329,17 +319,15 @@ GF_Err ftab_Size(GF_Box *s)
 
 GF_Box *text_New()
 {
-       GF_TextSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_TextSampleEntryBox);
-       if (!tmp)
-               return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TEXT;
+       ISOM_DECL_BOX_ALLOC(GF_TextSampleEntryBox, GF_ISOM_BOX_TYPE_TEXT);
        return (GF_Box *) tmp;
 }
 
 void text_del(GF_Box *s)
 {
        GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->textName)
                gf_free(ptr->textName);
        gf_free(ptr);
@@ -347,17 +335,16 @@ void text_del(GF_Box *s)
 
 GF_Box *tx3g_New()
 {
-       GF_Tx3gSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_Tx3gSampleEntryBox);
-       if (!tmp)
-               return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TX3G;
+       ISOM_DECL_BOX_ALLOC(GF_Tx3gSampleEntryBox, GF_ISOM_BOX_TYPE_TX3G);
        return (GF_Box *) tmp;
 }
 
 void tx3g_del(GF_Box *s)
 {
        GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
+       
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->font_table)
                gf_isom_box_del((GF_Box *)ptr->font_table);
        gf_free(ptr);
@@ -580,10 +567,7 @@ GF_Err text_Size(GF_Box *s)
 
 GF_Box *styl_New()
 {
-       GF_TextStyleBox *tmp;
-       GF_SAFEALLOC(tmp, GF_TextStyleBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_STYL;
+       ISOM_DECL_BOX_ALLOC(GF_TextStyleBox, GF_ISOM_BOX_TYPE_STYL);
        return (GF_Box *) tmp;
 }
 
@@ -635,10 +619,7 @@ GF_Err styl_Size(GF_Box *s)
 
 GF_Box *hlit_New()
 {
-       GF_TextHighlightBox *tmp;
-       GF_SAFEALLOC(tmp, GF_TextHighlightBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_HLIT;
+       ISOM_DECL_BOX_ALLOC(GF_TextHighlightBox, GF_ISOM_BOX_TYPE_HLIT);
        return (GF_Box *) tmp;
 }
 
@@ -679,10 +660,7 @@ GF_Err hlit_Size(GF_Box *s)
 
 GF_Box *hclr_New()
 {
-       GF_TextHighlightColorBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextHighlightColorBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_HCLR;
+       ISOM_DECL_BOX_ALLOC(GF_TextHighlightColorBox, GF_ISOM_BOX_TYPE_HCLR);
        return (GF_Box *) tmp;
 }
 
@@ -721,10 +699,7 @@ GF_Err hclr_Size(GF_Box *s)
 
 GF_Box *krok_New()
 {
-       GF_TextKaraokeBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextKaraokeBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_KROK;
+       ISOM_DECL_BOX_ALLOC(GF_TextKaraokeBox, GF_ISOM_BOX_TYPE_KROK);
        return (GF_Box *) tmp;
 }
 
@@ -785,10 +760,7 @@ GF_Err krok_Size(GF_Box *s)
 
 GF_Box *dlay_New()
 {
-       GF_TextScrollDelayBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextScrollDelayBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_DLAY;
+       ISOM_DECL_BOX_ALLOC(GF_TextScrollDelayBox, GF_ISOM_BOX_TYPE_DLAY);
        return (GF_Box *) tmp;
 }
 
@@ -827,10 +799,7 @@ GF_Err dlay_Size(GF_Box *s)
 
 GF_Box *href_New()
 {
-       GF_TextHyperTextBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextHyperTextBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_HREF;
+       ISOM_DECL_BOX_ALLOC(GF_TextHyperTextBox, GF_ISOM_BOX_TYPE_HREF);
        return (GF_Box *) tmp;
 }
 
@@ -907,10 +876,7 @@ GF_Err href_Size(GF_Box *s)
 
 GF_Box *tbox_New()
 {
-       GF_TextBoxBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextBoxBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TBOX;
+       ISOM_DECL_BOX_ALLOC(GF_TextBoxBox, GF_ISOM_BOX_TYPE_TBOX);
        return (GF_Box *) tmp;
 }
 
@@ -950,10 +916,7 @@ GF_Err tbox_Size(GF_Box *s)
 
 GF_Box *blnk_New()
 {
-       GF_TextBlinkBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextBlinkBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_BLNK;
+       ISOM_DECL_BOX_ALLOC(GF_TextBlinkBox, GF_ISOM_BOX_TYPE_BLNK);
        return (GF_Box *) tmp;
 }
 
@@ -994,10 +957,7 @@ GF_Err blnk_Size(GF_Box *s)
 
 GF_Box *twrp_New()
 {
-       GF_TextWrapBox*tmp;
-       GF_SAFEALLOC(tmp, GF_TextWrapBox);
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TWRP;
+       ISOM_DECL_BOX_ALLOC(GF_TextWrapBox, GF_ISOM_BOX_TYPE_TWRP);
        return (GF_Box *) tmp;
 }
 
@@ -1064,13 +1024,8 @@ GF_Err tsel_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *tsel_New()
 {
-       GF_TrackSelectionBox *tmp;
-       
-       tmp = (GF_TrackSelectionBox *) gf_malloc(sizeof(GF_TrackSelectionBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackSelectionBox));
+       ISOM_DECL_BOX_ALLOC(GF_TrackSelectionBox, GF_ISOM_BOX_TYPE_TSEL);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_TSEL;
        return (GF_Box *)tmp;
 }
 
@@ -1109,12 +1064,8 @@ GF_Err tsel_Size(GF_Box *s)
 
 GF_Box *dimC_New()
 {
-       GF_DIMSSceneConfigBox *tmp;
-       
-       GF_SAFEALLOC(tmp, GF_DIMSSceneConfigBox);
-       if (tmp == NULL) return NULL;
+       ISOM_DECL_BOX_ALLOC(GF_DIMSSceneConfigBox, GF_ISOM_BOX_TYPE_DIMC);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_DIMC;
        return (GF_Box *)tmp;
 }
 void dimC_del(GF_Box *s)
@@ -1195,11 +1146,7 @@ GF_Err dimC_Size(GF_Box *s)
 
 GF_Box *diST_New()
 {
-       GF_DIMSScriptTypesBox *tmp;
-       
-       GF_SAFEALLOC(tmp, GF_DIMSScriptTypesBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_DIST;
+       ISOM_DECL_BOX_ALLOC(GF_DIMSScriptTypesBox, GF_ISOM_BOX_TYPE_DIST);
        return (GF_Box *)tmp;
 }
 void diST_del(GF_Box *s)
@@ -1253,17 +1200,16 @@ GF_Err diST_Size(GF_Box *s)
 
 GF_Box *dims_New()
 {
-       GF_DIMSSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_DIMSSampleEntryBox);
-       tmp->type = GF_ISOM_BOX_TYPE_DIMS;
+       ISOM_DECL_BOX_ALLOC(GF_DIMSSampleEntryBox, GF_ISOM_BOX_TYPE_DIMS);
        return (GF_Box*)tmp;
 }
 void dims_del(GF_Box *s)
 {
        GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (p->config) gf_isom_box_del((GF_Box *)p->config);
        if (p->bitrate ) gf_isom_box_del((GF_Box *)p->bitrate);
-       if (p->protection_info) gf_isom_box_del((GF_Box *)p->protection_info);
        if (p->scripts) gf_isom_box_del((GF_Box *)p->scripts);
        gf_free(p);
 }
@@ -1285,12 +1231,10 @@ static GF_Err dims_AddBox(GF_Box *s, GF_Box *a)
                p->bitrate = (GF_MPEG4BitRateBox*)a;
                break;
        case GF_ISOM_BOX_TYPE_SINF:
-               if (p->protection_info) return GF_ISOM_INVALID_FILE;
-               p->protection_info = (GF_ProtectionInfoBox*)a;
+               gf_list_add(p->protections, a);
                break;
        default:
-               gf_isom_box_del(a);
-               break;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -1323,11 +1267,7 @@ GF_Err dims_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_write((GF_Box *)p->bitrate, bs);
                if (e) return e;
        }
-       if (p->protection_info) {
-               e = gf_isom_box_write((GF_Box *)p->protection_info, bs);
-               if (e) return e;
-       }
-       return GF_OK;
+       return gf_isom_box_array_write(s, p->protections, bs);
 }
 
 GF_Err dims_Size(GF_Box *s)
@@ -1342,11 +1282,6 @@ GF_Err dims_Size(GF_Box *s)
                if (e) return e;
                p->size += p->config->size;
        }
-       if (p->protection_info) {
-               e = gf_isom_box_size((GF_Box *) p->protection_info); 
-               if (e) return e;
-               p->size += p->protection_info->size;
-       }
        if (p->bitrate) {
                e = gf_isom_box_size((GF_Box *) p->bitrate); 
                if (e) return e;
@@ -1357,7 +1292,7 @@ GF_Err dims_Size(GF_Box *s)
                if (e) return e;
                p->size += p->scripts->size;
        }
-       return GF_OK;
+       return gf_isom_box_array_size(s, p->protections);
 }
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
diff --git a/src/isomedia/box_code_adobe.c b/src/isomedia/box_code_adobe.c
new file mode 100644 (file)
index 0000000..32069d8
--- /dev/null
@@ -0,0 +1,691 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Author: Romain Bouqueau\r
+ *                     Copyright (c) Romain Bouqueau 2012-\r
+ *                             All rights reserved\r
+ *\r
+ *          Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com)\r
+ *\r
+ *  This file is part of GPAC / ISO Media File Format sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#ifndef GPAC_DISABLE_ISOM_ADOBE\r
+\r
+#include <gpac/internal/isomedia_dev.h>\r
+\r
+#ifndef GPAC_DISABLE_ISOM\r
+\r
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS\r
+\r
+void abst_del(GF_Box *s)\r
+{\r
+       GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;\r
+       if (ptr == NULL) return;\r
+\r
+       if (ptr->movie_identifier)\r
+               gf_free(ptr->movie_identifier);\r
+       if (ptr->drm_data)\r
+               gf_free(ptr->drm_data);\r
+       if (ptr->meta_data)\r
+               gf_free(ptr->meta_data);\r
+\r
+       while (gf_list_count(ptr->server_entry_table)) {\r
+               gf_free(gf_list_get(ptr->server_entry_table, 0));\r
+               gf_list_rem(ptr->server_entry_table, 0);\r
+       }\r
+       gf_list_del(ptr->server_entry_table);\r
+\r
+       while (gf_list_count(ptr->quality_entry_table)) {\r
+               gf_free(gf_list_get(ptr->quality_entry_table, 0));\r
+               gf_list_rem(ptr->quality_entry_table, 0);\r
+       }\r
+       gf_list_del(ptr->quality_entry_table);\r
+\r
+       while (gf_list_count(ptr->segment_run_table_entries)) {\r
+               gf_isom_box_del((GF_Box *)gf_list_get(ptr->segment_run_table_entries, 0));\r
+               gf_list_rem(ptr->segment_run_table_entries, 0);\r
+       }\r
+       gf_list_del(ptr->segment_run_table_entries);\r
+\r
+       while (gf_list_count(ptr->fragment_run_table_entries)) {\r
+               gf_isom_box_del((GF_Box *)gf_list_get(ptr->fragment_run_table_entries, 0));\r
+               gf_list_rem(ptr->fragment_run_table_entries, 0);\r
+       }\r
+       gf_list_del(ptr->fragment_run_table_entries);\r
+\r
+       gf_free(ptr);\r
+}\r
+\r
+GF_Err abst_Read(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;\r
+       int i;\r
+       u32 tmp_strsize = (u32) ptr->size - 8;\r
+       char *tmp_str = gf_malloc(sizeof(char)*tmp_strsize);\r
+\r
+       GF_Err e = gf_isom_full_box_read(s, bs);\r
+       if (e) return e;\r
+\r
+       ptr->bootstrapinfo_version = gf_bs_read_u32(bs);\r
+       ptr->profile = gf_bs_read_int(bs, 2);\r
+       ptr->live = gf_bs_read_int(bs, 1);\r
+       ptr->update = gf_bs_read_int(bs, 1);\r
+       ptr->reserved = gf_bs_read_int(bs, 4);\r
+       ptr->time_scale = gf_bs_read_u32(bs);\r
+       ptr->current_media_time = gf_bs_read_u64(bs);\r
+       ptr->smpte_time_code_offset = gf_bs_read_u64(bs);\r
+       i=0;\r
+       tmp_strsize=(u32)ptr->size-8;\r
+       while (tmp_strsize) {\r
+               tmp_str[i] = gf_bs_read_u8(bs);\r
+               tmp_strsize--;\r
+               if (!tmp_str[i])\r
+                       break;\r
+               i++;\r
+       }\r
+       if (i)\r
+               ptr->movie_identifier = gf_strdup(tmp_str);\r
+       \r
+       ptr->server_entry_count = gf_bs_read_u8(bs);\r
+       for (i=0; i<ptr->server_entry_count; i++) {\r
+               int j=0;\r
+               tmp_strsize=(u32)ptr->size-8;\r
+               while (tmp_strsize) {\r
+                       tmp_str[j] = gf_bs_read_u8(bs);\r
+                       tmp_strsize--;\r
+                       if (!tmp_str[j])\r
+                               break;\r
+                       j++;\r
+               }\r
+               gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i);\r
+       }\r
+       \r
+       ptr->quality_entry_count = gf_bs_read_u8(bs);\r
+       for (i=0; i<ptr->quality_entry_count; i++) {\r
+               int j=0;\r
+               tmp_strsize=(u32)ptr->size-8;\r
+               while (tmp_strsize) {\r
+                       tmp_str[j] = gf_bs_read_u8(bs);\r
+                       tmp_strsize--;\r
+                       if (!tmp_str[j])\r
+                               break;\r
+                       j++;\r
+               }\r
+               gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i);\r
+       }\r
+\r
+       i=0;\r
+       tmp_strsize=(u32)ptr->size-8;\r
+       while (tmp_strsize) {\r
+               tmp_str[i] = gf_bs_read_u8(bs);\r
+               tmp_strsize--;\r
+               if (!tmp_str[i])\r
+                       break;\r
+               i++;\r
+       }\r
+       if (i)\r
+               ptr->drm_data = gf_strdup(tmp_str);\r
+\r
+       i=0;\r
+       tmp_strsize=(u32)ptr->size-8;\r
+       while (tmp_strsize) {\r
+               tmp_str[i] = gf_bs_read_u8(bs);\r
+               tmp_strsize--;\r
+               if (!tmp_str[i])\r
+                       break;\r
+               i++;\r
+       }\r
+       if (i)\r
+               ptr->meta_data = gf_strdup(tmp_str);\r
+       \r
+       ptr->segment_run_table_count = gf_bs_read_u8(bs);\r
+       for (i=0; i<ptr->segment_run_table_count; i++) {\r
+               GF_AdobeSegmentRunTableBox *asrt;\r
+               e = gf_isom_parse_box((GF_Box **)&asrt, bs);\r
+               if (e) return e;\r
+               gf_list_insert(ptr->segment_run_table_entries, asrt, i);\r
+       }\r
+       \r
+       ptr->fragment_run_table_count = gf_bs_read_u8(bs);\r
+       for (i=0; i<ptr->fragment_run_table_count; i++) {\r
+               GF_AdobeFragmentRunTableBox *afrt;      \r
+               e = gf_isom_parse_box((GF_Box **)&afrt, bs);\r
+               if (e) return e;\r
+               gf_list_insert(ptr->fragment_run_table_entries, afrt, i);\r
+       }\r
+\r
+       gf_free(tmp_str);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+GF_Box *abst_New()\r
+{\r
+       ISOM_DECL_BOX_ALLOC(GF_AdobeBootstrapInfoBox, GF_ISOM_BOX_TYPE_ABST);\r
+       tmp->server_entry_table = gf_list_new();\r
+       tmp->quality_entry_table = gf_list_new();\r
+       tmp->segment_run_table_entries = gf_list_new();\r
+       tmp->fragment_run_table_entries = gf_list_new();\r
+       return (GF_Box *)tmp;\r
+}\r
+\r
+#ifndef GPAC_DISABLE_ISOM_WRITE\r
+\r
+GF_Err abst_Write(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       GF_Err e;\r
+       unsigned int i;\r
+       GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;\r
+\r
+       e = gf_isom_full_box_write(s, bs);\r
+       if (e) return e;\r
+\r
+       gf_bs_write_u32(bs, ptr->bootstrapinfo_version);\r
+       gf_bs_write_int(bs, ptr->profile, 2);\r
+       gf_bs_write_int(bs, ptr->live, 1);\r
+       gf_bs_write_int(bs, ptr->update, 1);\r
+       gf_bs_write_int(bs, ptr->reserved, 4);\r
+       gf_bs_write_u32(bs, ptr->time_scale);\r
+       gf_bs_write_u64(bs, ptr->current_media_time);\r
+       gf_bs_write_u64(bs, ptr->smpte_time_code_offset);\r
+       if (ptr->movie_identifier)\r
+               gf_bs_write_data(bs, ptr->movie_identifier, (u32)strlen(ptr->movie_identifier) + 1);\r
+       else\r
+               gf_bs_write_u8(bs, 0);\r
+\r
+       gf_bs_write_u8(bs, ptr->server_entry_count);\r
+       for (i=0; i<ptr->server_entry_count; i++) {\r
+               char *str = (char*)gf_list_get(ptr->server_entry_table, i);\r
+               gf_bs_write_data(bs, str, (u32)strlen(str) + 1);\r
+       }\r
+\r
+       gf_bs_write_u8(bs, ptr->quality_entry_count);\r
+       for (i=0; i<ptr->quality_entry_count; i++) {\r
+               char *str = (char*)gf_list_get(ptr->quality_entry_table, i);\r
+               gf_bs_write_data(bs, str, (u32)strlen(str) + 1);\r
+       }\r
+\r
+       if (ptr->drm_data)\r
+               gf_bs_write_data(bs, ptr->drm_data, (u32)strlen(ptr->drm_data) + 1);\r
+       else\r
+               gf_bs_write_u8(bs, 0);\r
+\r
+       if (ptr->meta_data)\r
+               gf_bs_write_data(bs, ptr->meta_data, (u32)strlen(ptr->meta_data) + 1);\r
+       else\r
+               gf_bs_write_u8(bs, 0);\r
+\r
+       gf_bs_write_u8(bs, ptr->segment_run_table_count);\r
+       for (i=0; i<ptr->segment_run_table_count; i++) {\r
+               e = gf_isom_box_write((GF_Box *)gf_list_get(ptr->segment_run_table_entries, i), bs);\r
+               if (e) return e;\r
+       }\r
+\r
+       gf_bs_write_u8(bs, ptr->fragment_run_table_count);\r
+       for (i=0; i<ptr->fragment_run_table_count; i++) {\r
+               e = gf_isom_box_write((GF_Box *)gf_list_get(ptr->fragment_run_table_entries, i), bs);\r
+               if (e) return e;\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+\r
+GF_Err abst_Size(GF_Box *s)\r
+{\r
+       GF_Err e;\r
+       int i;\r
+       GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;\r
+       \r
+       e = gf_isom_full_box_get_size(s);\r
+       if (e) return e;\r
+\r
+       s->size += 25\r
+                       + (ptr->movie_identifier ? (strlen(ptr->movie_identifier) + 1) : 1)\r
+                       + 1;\r
+\r
+       for (i=0; i<ptr->server_entry_count; i++)\r
+                       s->size += strlen(gf_list_get(ptr->server_entry_table, i)) + 1;\r
+\r
+       s->size += 1;\r
+\r
+       for (i=0; i<ptr->quality_entry_count; i++)\r
+                       s->size += strlen(gf_list_get(ptr->quality_entry_table, i)) + 1;\r
+\r
+       s->size += (ptr->drm_data ? (strlen(ptr->drm_data) + 1) : 1)\r
+                       + (ptr->meta_data ? (strlen(ptr->meta_data) + 1) : 1)\r
+                       + 1;\r
+\r
+       for (i=0; i<ptr->segment_run_table_count; i++) {\r
+               GF_Box *box = (GF_Box *)gf_list_get(ptr->segment_run_table_entries, i);\r
+               e = gf_isom_box_size(box);\r
+               if (e) return e;\r
+               s->size += box->size;\r
+       }\r
+               \r
+       s->size += 1;\r
+       for (i=0; i<ptr->fragment_run_table_count; i++) {\r
+               GF_Box *box = (GF_Box *)gf_list_get(ptr->fragment_run_table_entries, i);\r
+               e = gf_isom_box_size(box);\r
+               if (e) return e;\r
+               s->size += box->size;\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+#endif /*GPAC_DISABLE_ISOM_WRITE*/\r
+\r
+void afra_del(GF_Box *s)\r
+{\r
+       GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;\r
+       if (ptr == NULL) return;\r
+\r
+       while (gf_list_count(ptr->local_access_entries)) {\r
+               gf_free(gf_list_get(ptr->local_access_entries, 0));\r
+               gf_list_rem(ptr->local_access_entries, 0);\r
+       }\r
+       gf_list_del(ptr->local_access_entries);\r
+\r
+       while (gf_list_count(ptr->global_access_entries)) {\r
+               gf_free(gf_list_get(ptr->global_access_entries, 0));\r
+               gf_list_rem(ptr->global_access_entries, 0);\r
+       }\r
+       gf_list_del(ptr->global_access_entries);\r
+\r
+       gf_free(ptr);\r
+}\r
+\r
+GF_Err afra_Read(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       unsigned int i;\r
+       GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;\r
+\r
+       GF_Err e = gf_isom_full_box_read(s, bs);\r
+       if (e) return e;\r
+\r
+       ptr->long_ids = gf_bs_read_int(bs, 1);\r
+       ptr->long_offsets = gf_bs_read_int(bs, 1);\r
+       ptr->global_entries = gf_bs_read_int(bs, 1);\r
+       ptr->reserved = gf_bs_read_int(bs, 5);\r
+       ptr->time_scale = gf_bs_read_u32(bs);\r
+\r
+       ptr->entry_count = gf_bs_read_u32(bs);\r
+       for (i=0; i<ptr->entry_count; i++) {\r
+               GF_AfraEntry *ae = gf_malloc(sizeof(GF_AfraEntry));\r
+\r
+               ae->time = gf_bs_read_u64(bs);\r
+               if (ptr->long_offsets)\r
+                       ae->offset = gf_bs_read_u64(bs);\r
+               else\r
+                       ae->offset = gf_bs_read_u32(bs);\r
+\r
+               gf_list_insert(ptr->local_access_entries, ae, i);\r
+       }\r
+\r
+       if (ptr->global_entries) {\r
+               ptr->global_entry_count = gf_bs_read_u32(bs);\r
+               for (i=0; i<ptr->global_entry_count; i++) {\r
+                       GF_GlobalAfraEntry *ae = gf_malloc(sizeof(GF_GlobalAfraEntry));\r
+\r
+                       ae->time = gf_bs_read_u64(bs);\r
+                       if (ptr->long_ids) {\r
+                               ae->segment = gf_bs_read_u32(bs);\r
+                               ae->fragment = gf_bs_read_u32(bs);\r
+                       } else {\r
+                               ae->segment = gf_bs_read_u16(bs);\r
+                               ae->fragment = gf_bs_read_u16(bs);\r
+                       }\r
+                       if (ptr->long_offsets) {\r
+                               ae->afra_offset = gf_bs_read_u64(bs);\r
+                               ae->offset_from_afra = gf_bs_read_u64(bs);\r
+                       }else {\r
+                               ae->afra_offset = gf_bs_read_u32(bs);\r
+                               ae->offset_from_afra = gf_bs_read_u32(bs);\r
+                       }\r
+\r
+                       gf_list_insert(ptr->global_access_entries, ae, i);\r
+               }\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+GF_Box *afra_New()\r
+{\r
+       ISOM_DECL_BOX_ALLOC(GF_AdobeFragRandomAccessBox, GF_ISOM_BOX_TYPE_AFRA);\r
+       tmp->local_access_entries = gf_list_new();\r
+       tmp->global_access_entries = gf_list_new();\r
+       return (GF_Box *)tmp;\r
+}\r
+\r
+#ifndef GPAC_DISABLE_ISOM_WRITE\r
+\r
+GF_Err afra_Write(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       GF_Err e;\r
+       unsigned int i;\r
+       GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;\r
+\r
+       e = gf_isom_full_box_write(s, bs);\r
+       if (e) return e;\r
+\r
+       gf_bs_write_int(bs, ptr->long_ids, 1);\r
+       gf_bs_write_int(bs, ptr->long_offsets, 1);\r
+       gf_bs_write_int(bs, ptr->global_entries, 1);\r
+       gf_bs_write_int(bs, 0, 5);\r
+       gf_bs_write_u32(bs, ptr->time_scale);\r
+\r
+       gf_bs_write_u32(bs, ptr->entry_count);\r
+       for (i=0; i<ptr->entry_count; i++) {\r
+               GF_AfraEntry *ae = (GF_AfraEntry *)gf_list_get(ptr->local_access_entries, i);\r
+               gf_bs_write_u64(bs, ae->time);\r
+               if (ptr->long_offsets)\r
+                       gf_bs_write_u64(bs, ae->offset);\r
+               else\r
+                       gf_bs_write_u32(bs, (u32)ae->offset);\r
+       }\r
+\r
+       if (ptr->global_entries) {\r
+               gf_bs_write_u32(bs, ptr->global_entry_count);\r
+               for (i=0; i<ptr->global_entry_count; i++) {\r
+                       GF_GlobalAfraEntry *gae = (GF_GlobalAfraEntry *)gf_list_get(ptr->global_access_entries, i);\r
+                       gf_bs_write_u64(bs, gae->time);\r
+                       if (ptr->long_ids) {\r
+                               gf_bs_write_u32(bs, gae->segment);\r
+                               gf_bs_write_u32(bs, gae->fragment);\r
+                       } else {\r
+                               gf_bs_write_u16(bs, (u16)gae->segment);\r
+                               gf_bs_write_u16(bs, (u16)gae->fragment);\r
+                       }\r
+                       if (ptr->long_offsets) {\r
+                               gf_bs_write_u64(bs, gae->afra_offset);\r
+                               gf_bs_write_u64(bs, gae->offset_from_afra);\r
+                       } else {\r
+                               gf_bs_write_u32(bs, (u32)gae->afra_offset);\r
+                               gf_bs_write_u32(bs, (u32)gae->offset_from_afra);\r
+                       }\r
+               }\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+\r
+GF_Err afra_Size(GF_Box *s)\r
+{\r
+       GF_Err e;\r
+       GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;\r
+\r
+       e = gf_isom_full_box_get_size(s);\r
+       if (e) return e;\r
+\r
+       s->size += 9\r
+                       + ptr->entry_count * (ptr->long_offsets ? 16 : 12)\r
+                       + (ptr->global_entries ? 4 + ptr->global_entry_count * (4 + (ptr->long_offsets ? 16 : 8) + (ptr->long_ids ? 8 : 4)) : 0);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+#endif /*GPAC_DISABLE_ISOM_WRITE*/\r
+\r
+void asrt_del(GF_Box *s)\r
+{\r
+       GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;\r
+       if (ptr == NULL) return;\r
+\r
+       while (gf_list_count(ptr->quality_segment_url_modifiers)) {\r
+               gf_free(gf_list_get(ptr->quality_segment_url_modifiers, 0));\r
+               gf_list_rem(ptr->quality_segment_url_modifiers, 0);\r
+       }\r
+       gf_list_del(ptr->quality_segment_url_modifiers);\r
+\r
+       while (gf_list_count(ptr->segment_run_entry_table)) {\r
+               gf_free(gf_list_get(ptr->segment_run_entry_table, 0));\r
+               gf_list_rem(ptr->segment_run_entry_table, 0);\r
+       }\r
+       gf_list_del(ptr->segment_run_entry_table);\r
+\r
+       gf_free(ptr);\r
+}\r
+\r
+GF_Err asrt_Read(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       unsigned int i;\r
+       GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;\r
+\r
+       GF_Err e = gf_isom_full_box_read(s, bs);\r
+       if (e) return e;\r
+\r
+       ptr->quality_entry_count = gf_bs_read_u8(bs);\r
+       for (i=0; i<ptr->quality_entry_count; i++) {\r
+               int j=0;\r
+               u32 tmp_strsize=(u32)ptr->size-8;\r
+               char *tmp_str = (char*) gf_malloc(tmp_strsize);\r
+               while (tmp_strsize) {\r
+                       tmp_str[j] = gf_bs_read_u8(bs);\r
+                       tmp_strsize--;\r
+                       if (!tmp_str[j])\r
+                               break;\r
+                       j++;\r
+               }\r
+               gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i);\r
+       }\r
+\r
+       ptr->segment_run_entry_count = gf_bs_read_u32(bs);\r
+       for (i=0; i<ptr->segment_run_entry_count; i++) {\r
+               GF_AdobeSegmentRunEntry *sre = gf_malloc(sizeof(GF_AdobeSegmentRunEntry));\r
+               sre->first_segment = gf_bs_read_u32(bs);\r
+               sre->fragment_per_segment = gf_bs_read_u32(bs);\r
+               gf_list_insert(ptr->segment_run_entry_table, sre, i);\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+GF_Box *asrt_New()\r
+{\r
+       ISOM_DECL_BOX_ALLOC(GF_AdobeSegmentRunTableBox, GF_ISOM_BOX_TYPE_ASRT);\r
+       tmp->quality_segment_url_modifiers = gf_list_new();\r
+       tmp->segment_run_entry_table = gf_list_new();\r
+       return (GF_Box *)tmp;\r
+}\r
+\r
+#ifndef GPAC_DISABLE_ISOM_WRITE\r
+\r
+GF_Err asrt_Write(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       GF_Err e;\r
+       unsigned int i;\r
+       GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;\r
+\r
+       e = gf_isom_full_box_write(s, bs);\r
+       if (e) return e;\r
+\r
+       gf_bs_write_u8(bs, ptr->quality_entry_count);\r
+       for (i=0; i<ptr->quality_entry_count; i++) {\r
+               char *str = (char*)gf_list_get(ptr->quality_segment_url_modifiers, i);\r
+               gf_bs_write_data(bs, str, (u32)strlen(str) + 1);\r
+       }\r
+\r
+       gf_bs_write_u32(bs, ptr->segment_run_entry_count);\r
+       for (i=0; i<ptr->segment_run_entry_count; i++) {\r
+               GF_AdobeSegmentRunEntry *sre = (GF_AdobeSegmentRunEntry *)gf_list_get(ptr->segment_run_entry_table, i);\r
+               gf_bs_write_u32(bs, sre->first_segment);\r
+               gf_bs_write_u32(bs, sre->fragment_per_segment);\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+\r
+GF_Err asrt_Size(GF_Box *s)\r
+{\r
+       int i;\r
+       GF_Err e;\r
+       GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;\r
+\r
+       e = gf_isom_full_box_get_size(s);\r
+       if (e) return e;\r
+\r
+       s->size += 5;\r
+\r
+       for (i=0; i<ptr->quality_entry_count; i++)\r
+               s->size += strlen(gf_list_get(ptr->quality_segment_url_modifiers, i)) + 1;\r
+\r
+       s->size += ptr->segment_run_entry_count * sizeof(GF_AdobeSegmentRunEntry);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+#endif /*GPAC_DISABLE_ISOM_WRITE*/\r
+\r
+void afrt_del(GF_Box *s)\r
+{\r
+       GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;\r
+       if (ptr == NULL) return;\r
+\r
+       while (gf_list_count(ptr->quality_segment_url_modifiers)) {\r
+               gf_free(gf_list_get(ptr->quality_segment_url_modifiers, 0));\r
+               gf_list_rem(ptr->quality_segment_url_modifiers, 0);\r
+       }\r
+       gf_list_del(ptr->quality_segment_url_modifiers);\r
+\r
+       while (gf_list_count(ptr->fragment_run_entry_table)) {\r
+               gf_free(gf_list_get(ptr->fragment_run_entry_table, 0));\r
+               gf_list_rem(ptr->fragment_run_entry_table, 0);\r
+       }\r
+       gf_list_del(ptr->fragment_run_entry_table);\r
+\r
+       gf_free(ptr);\r
+}\r
+\r
+GF_Err afrt_Read(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       unsigned int i;\r
+       GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;\r
+\r
+       GF_Err e = gf_isom_full_box_read(s, bs);\r
+       if (e) return e;\r
+\r
+       ptr->timescale = gf_bs_read_u32(bs);\r
+\r
+       ptr->quality_entry_count = gf_bs_read_u8(bs);\r
+       for (i=0; i<ptr->quality_entry_count; i++) {\r
+               int j=0;\r
+               u32 tmp_strsize=(u32)ptr->size-8;\r
+               char *tmp_str = (char*) gf_malloc(tmp_strsize);\r
+               while (tmp_strsize) {\r
+                       tmp_str[j] = gf_bs_read_u8(bs);\r
+                       tmp_strsize--;\r
+                       if (!tmp_str[j])\r
+                               break;\r
+                       j++;\r
+               }\r
+               gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i);\r
+       }\r
+\r
+       ptr->fragment_run_entry_count = gf_bs_read_u32(bs);\r
+       for (i=0; i<ptr->fragment_run_entry_count; i++) {\r
+               GF_AdobeFragmentRunEntry *fre = gf_malloc(sizeof(GF_AdobeFragmentRunEntry));\r
+               fre->first_fragment = gf_bs_read_u32(bs);\r
+               fre->first_fragment_timestamp = gf_bs_read_u64(bs);\r
+               fre->fragment_duration = gf_bs_read_u32(bs);\r
+               if (!fre->fragment_duration)\r
+                       fre->discontinuity_indicator = gf_bs_read_u8(bs);\r
+               gf_list_insert(ptr->fragment_run_entry_table, fre, i);\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+GF_Box *afrt_New()\r
+{\r
+       ISOM_DECL_BOX_ALLOC(GF_AdobeFragmentRunTableBox, GF_ISOM_BOX_TYPE_AFRT);\r
+       tmp->quality_segment_url_modifiers = gf_list_new();\r
+       tmp->fragment_run_entry_table = gf_list_new();\r
+       return (GF_Box *)tmp;\r
+}\r
+\r
+#ifndef GPAC_DISABLE_ISOM_WRITE\r
+\r
+GF_Err afrt_Write(GF_Box *s, GF_BitStream *bs)\r
+{\r
+       GF_Err e;\r
+       unsigned int i;\r
+       GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;\r
+\r
+       e = gf_isom_full_box_write(s, bs);\r
+       if (e) return e;\r
+\r
+       gf_bs_write_u32(bs, ptr->timescale);\r
+       gf_bs_write_u8(bs, ptr->quality_entry_count);\r
+       for (i=0; i<ptr->quality_entry_count; i++) {\r
+               char *str = (char*)gf_list_get(ptr->quality_segment_url_modifiers, i);\r
+               gf_bs_write_data(bs, str, (u32)strlen(str) + 1);\r
+       }\r
+\r
+       gf_bs_write_u32(bs, ptr->fragment_run_entry_count);\r
+       for (i=0; i<ptr->fragment_run_entry_count; i++) {\r
+               GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(ptr->fragment_run_entry_table, i);\r
+               gf_bs_write_u32(bs, fre->first_fragment);\r
+               gf_bs_write_u64(bs, fre->first_fragment_timestamp);\r
+               gf_bs_write_u32(bs, fre->fragment_duration);\r
+               if (!fre->fragment_duration)\r
+                       gf_bs_write_u8(bs, fre->discontinuity_indicator);\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+\r
+GF_Err afrt_Size(GF_Box *s)\r
+{\r
+       u32 i;\r
+       GF_Err e;\r
+       GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;\r
+\r
+       e = gf_isom_full_box_get_size(s);\r
+       if (e) return e;\r
+\r
+       s->size += 5;\r
+\r
+       for (i=0; i<ptr->quality_entry_count; i++)\r
+               s->size += strlen(gf_list_get(ptr->quality_segment_url_modifiers, i)) + 1;\r
+\r
+       s->size += 4;\r
+\r
+       for (i=0; i<ptr->fragment_run_entry_count; i++) {\r
+               GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(ptr->fragment_run_entry_table, i);\r
+               if (fre->fragment_duration)\r
+                       s->size += 16;\r
+               else\r
+                       s->size += 17;\r
+       }\r
+\r
+       return GF_OK;\r
+}\r
+\r
+#endif /*GPAC_DISABLE_ISOM_WRITE*/\r
+\r
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/\r
+\r
+#endif /*GPAC_DISABLE_ISOM*/\r
+\r
+#endif /*GPAC_DISABLE_ISOM_ADOBE*/\r
index 7a92d5ee8b645fc4f63996e05dd977baa7a817b9..a2b2514ed85bba10d471b49a7e759f777f7edf6b 100644 (file)
@@ -1,12 +1,27 @@
 /*
-Author: Andrew Voznytsa <av@polynet.lviv.ua>
-
-Project: GPAC - Multimedia Framework C SDK
-Module: ISO Media File Format sub-project
-
-Copyright: (c) 2006, Andrew Voznytsa
-License: see License.txt in the top level directory.
-*/
+ *                     GPAC - Multimedia Framework C SDK
+ *
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2006-2012
+ *                             All rights reserved
+ *
+ *  This file is part of GPAC / ISO Media File Format 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. 
+ *
+ */
 
 #include <gpac/internal/isomedia_dev.h>
 
@@ -16,7 +31,6 @@ void ilst_del(GF_Box *s)
 {
        GF_ItemListBox *ptr = (GF_ItemListBox *)s;
        if (ptr == NULL) return;
-       gf_isom_box_array_del(ptr->tags);
        gf_free(ptr);
 }
 
@@ -34,7 +48,7 @@ GF_Err ilst_Read(GF_Box *s, GF_BitStream *bs)
                        if (e) return e;
                        if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
                        ptr->size -= a->size;
-                       gf_list_add(ptr->tags, a);
+                       gf_list_add(ptr->other_boxes, a);
                } else {
                        gf_bs_read_u32(bs);
                        ptr->size -= 4;
@@ -45,11 +59,8 @@ GF_Err ilst_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *ilst_New()
 {
-       GF_ItemListBox *tmp = (GF_ItemListBox *) gf_malloc(sizeof(GF_ItemListBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ItemListBox));
-       tmp->type = GF_ISOM_BOX_TYPE_ILST;
-       tmp->tags = gf_list_new();
+       ISOM_DECL_BOX_ALLOC(GF_ItemListBox, GF_ISOM_BOX_TYPE_ILST);
+       tmp->other_boxes = gf_list_new();
        return (GF_Box *)tmp;
 }
 
@@ -58,24 +69,24 @@ GF_Box *ilst_New()
 GF_Err ilst_Write(GF_Box *s, GF_BitStream *bs)
 {
        GF_Err e;
-       GF_ItemListBox *ptr = (GF_ItemListBox *)s;
+//     GF_ItemListBox *ptr = (GF_ItemListBox *)s;
 
        e = gf_isom_box_write_header(s, bs);
        if (e) return e;
 
-       return gf_isom_box_array_write(s, ptr->tags, bs);
+       return GF_OK;
 }
 
 
 GF_Err ilst_Size(GF_Box *s)
 {
        GF_Err e;
-       GF_ItemListBox *ptr = (GF_ItemListBox *)s;
+//     GF_ItemListBox *ptr = (GF_ItemListBox *)s;
        
        e = gf_isom_box_get_size(s);
        if (e) return e;
 
-       return gf_isom_box_array_size(s, ptr->tags);
+       return GF_OK;
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -124,13 +135,7 @@ GF_Err ListItem_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *ListItem_New(u32 type)
 {
-       GF_ListItemBox *tmp;
-       
-       tmp = (GF_ListItemBox *) gf_malloc(sizeof(GF_ListItemBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ListItemBox));
-
-       tmp->type = type;
+       ISOM_DECL_BOX_ALLOC(GF_ListItemBox, type);
 
        tmp->data = (GF_DataBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_DATA);
 
@@ -216,14 +221,9 @@ GF_Err data_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *data_New()
 {
-       GF_DataBox *tmp;
-       
-       tmp = (GF_DataBox *) gf_malloc(sizeof(GF_DataBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_DataBox));
+       ISOM_DECL_BOX_ALLOC(GF_DataBox, GF_ISOM_BOX_TYPE_DATA);
 
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_DATA;
 
        return (GF_Box *)tmp;
 }
@@ -271,8 +271,8 @@ GF_MetaBox *gf_isom_apple_get_meta_extensions(GF_ISOFile *mov)
        map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL);
        if (!map) return NULL;
 
-       for(i = 0; i < gf_list_count(map->boxList); i++){
-               meta = (GF_MetaBox*)gf_list_get(map->boxList, i);
+       for(i = 0; i < gf_list_count(map->other_boxes); i++){
+               meta = (GF_MetaBox*)gf_list_get(map->other_boxes, i);
 
                if(meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta;
        }
@@ -297,8 +297,8 @@ GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov)
 
        map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL);
        if (map){
-               for(i = 0; i < gf_list_count(map->boxList); i++){
-                       meta = (GF_MetaBox*)gf_list_get(map->boxList, i);
+               for(i = 0; i < gf_list_count(map->other_boxes); i++){
+                       meta = (GF_MetaBox*)gf_list_get(map->other_boxes, i);
 
                        if(meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta;
                }
@@ -313,6 +313,7 @@ GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov)
                        return NULL;
                }
                meta->handler->handlerType = GF_ISOM_HANDLER_TYPE_MDIR;
+               if (!meta->other_boxes) meta->other_boxes = gf_list_new();
                gf_list_add(meta->other_boxes, gf_isom_box_new(GF_ISOM_BOX_TYPE_ILST));
                udta_AddBox(mov->moov->udta, (GF_Box *)meta);
        }
index 33420b6859835b594ec8b3f6680a8c4345410dc5..f0eec99e34bda0c2844d10bfeaab44cd563f84b5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -54,13 +55,8 @@ GF_Err co64_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *co64_New()
 {
-       GF_ChunkLargeOffsetBox *tmp;
-       
-       tmp = (GF_ChunkLargeOffsetBox *) gf_malloc(sizeof(GF_ChunkLargeOffsetBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ChunkLargeOffsetBox));
+       ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64);     
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_CO64;
        return (GF_Box *)tmp;
 }
 
@@ -106,14 +102,9 @@ void cprt_del(GF_Box *s)
 
 GF_Box *chpl_New()
 {
-       GF_ChapterListBox *tmp;
-       
-       tmp = (GF_ChapterListBox *) gf_malloc(sizeof(GF_ChapterListBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ChapterListBox));
+       ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL);
        tmp->list = gf_list_new();
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_CHPL;
     tmp->version = 1;
        return (GF_Box *)tmp;
 }
@@ -258,14 +249,9 @@ GF_Err cprt_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *cprt_New()
 {
-       GF_CopyrightBox *tmp;
-       
-       tmp = (GF_CopyrightBox *) gf_malloc(sizeof(GF_CopyrightBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_CopyrightBox));
+       ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT);
 
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_CPRT;
        tmp->packedLanguageCode[0] = 'u';
        tmp->packedLanguageCode[1] = 'n';
        tmp->packedLanguageCode[2] = 'd';
@@ -330,12 +316,15 @@ GF_Err ctts_Read(GF_Box *s, GF_BitStream *bs)
        if (e) return e;
        ptr->nb_entries = gf_bs_read_u32(bs);
        ptr->alloc_size = ptr->nb_entries;
-       ptr->entries = gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
+       ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
        if (!ptr->entries) return GF_OUT_OF_MEM;
        sampleCount = 0;
        for (i=0; i<ptr->nb_entries; i++) {
                ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
-               ptr->entries[i].decodingOffset = gf_bs_read_u32(bs);
+               if (ptr->version)
+                       ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32);
+               else
+                       ptr->entries[i].decodingOffset = (s32) gf_bs_read_u32(bs);
                sampleCount += ptr->entries[i].sampleCount;
        }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -346,14 +335,9 @@ GF_Err ctts_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *ctts_New()
 {
-       GF_CompositionOffsetBox *tmp;
-       
-       tmp = (GF_CompositionOffsetBox *) gf_malloc(sizeof(GF_CompositionOffsetBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_CompositionOffsetBox));
+       ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS);
 
        gf_isom_full_box_init((GF_Box *) tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_CTTS;
        return (GF_Box *) tmp;
 }
 
@@ -372,7 +356,11 @@ GF_Err ctts_Write(GF_Box *s, GF_BitStream *bs)
        gf_bs_write_u32(bs, ptr->nb_entries);
        for (i=0; i<ptr->nb_entries; i++ ) {
                gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
-               gf_bs_write_u32(bs, ptr->entries[i].decodingOffset);
+               if (ptr->version) {
+                       gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32);
+               } else {
+                       gf_bs_write_u32(bs, (u32) ptr->entries[i].decodingOffset);
+               }
        }
        return GF_OK;
 }
@@ -390,6 +378,67 @@ GF_Err ctts_Size(GF_Box *s)
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
+void cslg_del(GF_Box *s)
+{
+       GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
+       if (ptr == NULL) return;
+       gf_free(ptr);
+       return;
+}
+
+GF_Err cslg_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
+
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       ptr->compositionToDTSShift = gf_bs_read_int(bs, 32);
+       ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
+       ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
+       ptr->compositionStartTime = gf_bs_read_int(bs, 32);
+       ptr->compositionEndTime = gf_bs_read_int(bs, 32);
+       return GF_OK;
+}
+
+GF_Box *cslg_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG);
+
+       gf_isom_full_box_init((GF_Box *) tmp);
+       return (GF_Box *) tmp;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err cslg_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
+
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gf_bs_write_int(bs, ptr->compositionToDTSShift, 32);
+       gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32);
+       gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32);
+       gf_bs_write_int(bs, ptr->compositionStartTime, 32);
+       gf_bs_write_int(bs, ptr->compositionEndTime, 32);
+       return GF_OK;
+}
+
+GF_Err cslg_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
+       
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += 20;
+       return GF_OK;
+}
+
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
 void url_del(GF_Box *s)
 {
        GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
@@ -417,12 +466,8 @@ GF_Err url_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *url_New()
 {
-       GF_DataEntryURLBox *tmp = (GF_DataEntryURLBox *) gf_malloc(sizeof(GF_DataEntryURLBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_DataEntryURLBox));
-
+       ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_URL;
        return (GF_Box *)tmp;
 }
 
@@ -523,11 +568,8 @@ GF_Err urn_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *urn_New()
 {
-       GF_DataEntryURNBox *tmp = (GF_DataEntryURNBox *) gf_malloc(sizeof(GF_DataEntryURNBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_DataEntryURNBox));
+       ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_URN;
        return (GF_Box *)tmp;
 }
 
@@ -598,8 +640,7 @@ GF_Err defa_Read(GF_Box *s, GF_BitStream *bs)
 //warning: we don't have any boxType, trick has to be done while creating..
 GF_Box *defa_New()
 {
-       GF_UnknownBox *tmp = (GF_UnknownBox *) gf_malloc(sizeof(GF_UnknownBox));
-       memset(tmp, 0, sizeof(GF_UnknownBox));
+       ISOM_DECL_BOX_ALLOC(GF_UnknownBox, 0);
        return (GF_Box *) tmp;
 }
 
@@ -657,12 +698,9 @@ GF_Err uuid_Read(GF_Box *s, GF_BitStream *bs)
        return GF_OK;
 }
 
-//warning: we don't have any boxType, trick has to be done while creating..
 GF_Box *uuid_New()
 {
-       GF_UnknownUUIDBox *tmp = (GF_UnknownUUIDBox *) gf_malloc(sizeof(GF_UnknownUUIDBox));
-       memset(tmp, 0, sizeof(GF_UnknownUUIDBox));
-       tmp->type = GF_ISOM_BOX_TYPE_UUID;
+       ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID);
        return (GF_Box *) tmp;
 }
 
@@ -712,9 +750,9 @@ GF_Err dinf_AddBox(GF_Box *s, GF_Box *a)
                if (ptr->dref) return GF_ISOM_INVALID_FILE;
                ptr->dref = (GF_DataReferenceBox *)a;
                return GF_OK;           
+       default:
+               return gf_isom_box_add_default(s, a);
        }
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-       gf_isom_box_del(a);
        return GF_OK;           
 }
 
@@ -725,10 +763,7 @@ GF_Err dinf_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *dinf_New()
 {
-       GF_DataInformationBox *tmp = (GF_DataInformationBox *) gf_malloc(sizeof(GF_DataInformationBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_DataInformationBox));
-       tmp->type = GF_ISOM_BOX_TYPE_DINF;
+       ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF);
        return (GF_Box *)tmp;
 }
 
@@ -767,52 +802,35 @@ void dref_del(GF_Box *s)
 {
        GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s;
        if (ptr == NULL) return;
-       gf_isom_box_array_del(ptr->boxList);
        gf_free(ptr);
 }
 
 
 GF_Err dref_AddDataEntry(GF_DataReferenceBox *ptr, GF_Box *entry)
 {
-       return gf_list_add(ptr->boxList, entry);
+       return gf_isom_box_add_default((GF_Box *)ptr, entry);
 }
 
 GF_Err dref_Read(GF_Box *s, GF_BitStream *bs)
 {
        GF_Err e;
-       u32 count, i;
-       GF_Box *a;
+       //u32 count;
        GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
        
        if (ptr == NULL) return GF_BAD_PARAM;
        e = gf_isom_full_box_read(s, bs);
        if (e) return e;
-       count = gf_bs_read_u32(bs);
+       //count = 
+       gf_bs_read_u32(bs);
+       ptr->size -= 4;
 
-       for ( i = 0; i < count; i++ ) {
-               e = gf_isom_parse_box(&a, bs);
-               if (e) return e;
-               if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
-               e = gf_list_add(ptr->boxList, a);
-               if (e) return e;
-               ptr->size -= a->size;
-       }
-       return GF_OK;
+       return gf_isom_read_box_list(s, bs, gf_isom_box_add_default);
 }
 
 GF_Box *dref_New()
 {
-       GF_DataReferenceBox *tmp = (GF_DataReferenceBox *) gf_malloc(sizeof(GF_DataReferenceBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_DataReferenceBox));
-
+       ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF);
        gf_isom_full_box_init((GF_Box *) tmp);
-       tmp->boxList = gf_list_new();
-       if (!tmp->boxList) {
-               gf_free(tmp);
-               return NULL;
-       }
-       tmp->type = GF_ISOM_BOX_TYPE_DREF;
        return (GF_Box *)tmp;
 }
 
@@ -828,9 +846,9 @@ GF_Err dref_Write(GF_Box *s, GF_BitStream *bs)
 
        e = gf_isom_full_box_write(s, bs);
        if (e) return e;
-       count = gf_list_count(ptr->boxList);
+       count = ptr->other_boxes ? gf_list_count(ptr->other_boxes) : 0;
        gf_bs_write_u32(bs, count);
-       return gf_isom_box_array_write(s, ptr->boxList, bs);
+       return GF_OK;
 }
 
 GF_Err dref_Size(GF_Box *s)
@@ -842,8 +860,6 @@ GF_Err dref_Size(GF_Box *s)
        e = gf_isom_full_box_get_size(s);
        if (e) return e;
        ptr->size += 4;
-       e = gf_isom_box_array_size(s, ptr->boxList);
-       if (e) return e;
        return GF_OK;
 }
 
@@ -864,9 +880,9 @@ GF_Err edts_AddBox(GF_Box *s, GF_Box *a)
                if (ptr->editList) return GF_BAD_PARAM;
                ptr->editList = (GF_EditListBox *)a;
                return GF_OK;
+       } else {
+               return gf_isom_box_add_default(s, a);
        }
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-       gf_isom_box_del(a);
        return GF_OK;           
 }
 
@@ -878,10 +894,7 @@ GF_Err edts_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *edts_New()
 {
-       GF_EditBox *tmp;
-       GF_SAFEALLOC(tmp, GF_EditBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_EDTS;
+       ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS);
        return (GF_Box *) tmp;
 }
 
@@ -976,11 +989,7 @@ GF_Err elst_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *elst_New()
 {
-       GF_EditListBox *tmp;
-       
-       tmp = (GF_EditListBox *) gf_malloc(sizeof(GF_EditListBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_EditListBox));
+       ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST);
 
        gf_isom_full_box_init((GF_Box *)tmp);
        tmp->entryList = gf_list_new();
@@ -988,7 +997,6 @@ GF_Box *elst_New()
                gf_free(tmp);
                return NULL;
        }
-       tmp->type = GF_ISOM_BOX_TYPE_ELST;
        return (GF_Box *)tmp;
 }
 
@@ -1101,13 +1109,9 @@ GF_Err esds_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *esds_New()
 {
-       GF_ESDBox *tmp = (GF_ESDBox *) gf_malloc(sizeof(GF_ESDBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ESDBox));
+       ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS);
 
        gf_isom_full_box_init((GF_Box *) tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_ESDS;
-
        return (GF_Box *)tmp;
 }
 
@@ -1172,10 +1176,7 @@ GF_Err free_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *free_New()
 {
-       GF_FreeSpaceBox *tmp = (GF_FreeSpaceBox *) gf_malloc(sizeof(GF_FreeSpaceBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_FreeSpaceBox));
-       tmp->type = GF_ISOM_BOX_TYPE_FREE;
+       ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE);
        return (GF_Box *)tmp;
 }
 
@@ -1222,13 +1223,7 @@ void ftyp_del(GF_Box *s)
 
 GF_Box *ftyp_New()
 {
-       GF_FileTypeBox *tmp;
-       
-       tmp = (GF_FileTypeBox *) gf_malloc(sizeof(GF_FileTypeBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_FileTypeBox));
-
-       tmp->type = GF_ISOM_BOX_TYPE_FTYP;
+       ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP);
        return (GF_Box *)tmp;
 }
 
@@ -1290,16 +1285,16 @@ GF_Err ftyp_Size(GF_Box *s)
 void gnrm_del(GF_Box *s)
 {
        GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
        if (ptr->data) gf_free(ptr->data);
        gf_free(ptr);
 }
 
 GF_Box *gnrm_New()
 {
-       GF_GenericSampleEntryBox *tmp = (GF_GenericSampleEntryBox *) gf_malloc(sizeof(GF_GenericSampleEntryBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_GenericSampleEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_GNRM;
+       ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM);
+
+       gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
        return (GF_Box *)tmp;
 }
 
@@ -1340,16 +1335,14 @@ GF_Err gnrm_Size(GF_Box *s)
 void gnrv_del(GF_Box *s)
 {
        GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
        if (ptr->data) gf_free(ptr->data);
        gf_free(ptr);
 }
 
 GF_Box *gnrv_New()
 {
-       GF_GenericVisualSampleEntryBox *tmp = (GF_GenericVisualSampleEntryBox *) gf_malloc(sizeof(GF_GenericVisualSampleEntryBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_GenericVisualSampleEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_GNRV;
+       ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV);
        gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*) tmp);
        return (GF_Box *)tmp;
 }
@@ -1393,16 +1386,14 @@ GF_Err gnrv_Size(GF_Box *s)
 void gnra_del(GF_Box *s)
 {
        GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
        if (ptr->data) gf_free(ptr->data);
        gf_free(ptr);
 }
 
 GF_Box *gnra_New()
 {
-       GF_GenericAudioSampleEntryBox *tmp = (GF_GenericAudioSampleEntryBox *) gf_malloc(sizeof(GF_GenericAudioSampleEntryBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_GenericAudioSampleEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_GNRA;
+       ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA);
        gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*) tmp);
        return (GF_Box *)tmp;
 }
@@ -1479,11 +1470,8 @@ GF_Err hdlr_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *hdlr_New()
 {
-       GF_HandlerBox *tmp = (GF_HandlerBox *) gf_malloc(sizeof(GF_HandlerBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_HandlerBox));
+       ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_HDLR;
        return (GF_Box *)tmp;
 }
 
@@ -1522,29 +1510,14 @@ GF_Err hdlr_Size(GF_Box *s)
 void hinf_del(GF_Box *s)
 {
        GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
-       gf_isom_box_array_del(hinf->boxList);
-       gf_list_del(hinf->dataRates);
        gf_free(hinf);
 }
 
 GF_Box *hinf_New()
 {
-       GF_HintInfoBox *tmp = (GF_HintInfoBox *)gf_malloc(sizeof(GF_HintInfoBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_HintInfoBox));
+       ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF);
 
-       tmp->boxList = gf_list_new();
-       if (!tmp->boxList) {
-               gf_free(tmp);
-               return NULL;
-       }
-       tmp->dataRates = gf_list_new();
-       if (!tmp->dataRates) {
-               gf_list_del(tmp->boxList);
-               gf_free(tmp);
-               return NULL;
-       }
-       tmp->type = GF_ISOM_BOX_TYPE_HINF;
+       tmp->other_boxes = gf_list_new();
        return (GF_Box *)tmp;
 }
 
@@ -1556,15 +1529,13 @@ GF_Err hinf_AddBox(GF_Box *s, GF_Box *a)
        switch (a->type) {
        case GF_ISOM_BOX_TYPE_MAXR:
                i=0;
-               while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->dataRates, &i))) {
-                       if (maxR->granularity == ((GF_MAXRBox *)a)->granularity) return GF_ISOM_INVALID_FILE;
+               while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->other_boxes, &i))) {
+                       if ((maxR->type==GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == ((GF_MAXRBox *)a)->granularity))
+                               return GF_ISOM_INVALID_FILE;
                }
-               gf_list_add(hinf->dataRates, a);
-               break;
-       default:
                break;
        }
-       return gf_list_add(hinf->boxList, a);
+       return gf_isom_box_add_default(s, a);
 }
 
 
@@ -1577,21 +1548,15 @@ GF_Err hinf_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Err hinf_Write(GF_Box *s, GF_BitStream *bs)
 {
-       GF_Err e;
-       GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
+//     GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
        if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
-       return gf_isom_box_array_write(s, ptr->boxList, bs);
+       return gf_isom_box_write_header(s, bs);
 }
 
 GF_Err hinf_Size(GF_Box *s)
 {
-       GF_Err e;
-       GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
-       e = gf_isom_box_get_size(s);
-       if (e) return e;
-       return gf_isom_box_array_size(s, ptr->boxList);
+//     GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
+       return gf_isom_box_get_size(s);
 }
 #endif /*GPAC_DISABLE_ISOM_WRITE*/     
 
@@ -1620,13 +1585,9 @@ GF_Err hmhd_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *hmhd_New()
 {
-       GF_HintMediaHeaderBox *tmp = (GF_HintMediaHeaderBox *) gf_malloc(sizeof(GF_HintMediaHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_HintMediaHeaderBox));
+       ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD);
        
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_HMHD;
-
        return (GF_Box *)tmp;
 }
 
@@ -1662,15 +1623,13 @@ GF_Err hmhd_Size(GF_Box *s)
 
 GF_Box *hnti_New()
 {
-       GF_HintTrackInfoBox *tmp = (GF_HintTrackInfoBox *)gf_malloc(sizeof(GF_HintTrackInfoBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_HintTrackInfoBox));
-       tmp->boxList = gf_list_new();
-       if (!tmp->boxList) {
+       ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI);
+
+       tmp->hints = gf_list_new();
+       if (!tmp->hints) {
                gf_free(tmp);
                return NULL;
        }
-       tmp->type = GF_ISOM_BOX_TYPE_HNTI;
        return (GF_Box *)tmp;
 }
 
@@ -1679,8 +1638,8 @@ void hnti_del(GF_Box *a)
        GF_Box *t;
        GF_RTPBox *rtp;
        GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)a;
-       while (gf_list_count(ptr->boxList)) {
-               t = (GF_Box*)gf_list_get(ptr->boxList, 0);
+       while (gf_list_count(ptr->hints)) {
+               t = (GF_Box*)gf_list_get(ptr->hints, 0);
                if (t->type != GF_ISOM_BOX_TYPE_RTP) {
                        gf_isom_box_del(t);
                } else {
@@ -1688,9 +1647,9 @@ void hnti_del(GF_Box *a)
                        if (rtp->sdpText) gf_free(rtp->sdpText);
                        gf_free(rtp);
                }
-               gf_list_rem(ptr->boxList, 0);
+               gf_list_rem(ptr->hints, 0);
        }
-       gf_list_del(ptr->boxList);
+       gf_list_del(ptr->hints);
        gf_free(ptr);
 }
 
@@ -1708,7 +1667,7 @@ GF_Err hnti_AddBox(GF_HintTrackInfoBox *hnti, GF_Box *a)
        default:
                break;
        }
-       return gf_list_add(hnti->boxList, a);
+       return gf_list_add(hnti->hints, a);
 }
 
 GF_Err hnti_Read(GF_Box *s, GF_BitStream *bs)
@@ -1782,9 +1741,9 @@ GF_Err hnti_Write(GF_Box *s, GF_BitStream *bs)
        e = gf_isom_box_write_header(s, bs);
        if (e) return e;
 
-       count = gf_list_count(ptr->boxList);
+       count = gf_list_count(ptr->hints);
        for (i = 0; i < count; i ++) {
-               a = (GF_Box*)gf_list_get(ptr->boxList, i);
+               a = (GF_Box*)gf_list_get(ptr->hints, i);
                if (a->type != GF_ISOM_BOX_TYPE_RTP) {
                        e = gf_isom_box_write(a, bs);
                        if (e) return e;
@@ -1815,9 +1774,9 @@ GF_Err hnti_Size(GF_Box *s)
        e = gf_isom_box_get_size(s);
        if (e) return e;
 
-       count = gf_list_count(ptr->boxList);
+       count = gf_list_count(ptr->hints);
        for (i = 0; i < count; i ++) {
-               a = (GF_Box*)gf_list_get(ptr->boxList, i);
+               a = (GF_Box*)gf_list_get(ptr->hints, i);
                if (a->type != GF_ISOM_BOX_TYPE_RTP) {
                        e = gf_isom_box_size(a);
                        if (e) return e;
@@ -1863,10 +1822,7 @@ GF_Err sdp_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *sdp_New()
 {
-       GF_SDPBox *tmp = (GF_SDPBox *) gf_malloc(sizeof(GF_SDPBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_SDPBox));
-       tmp->type = GF_ISOM_BOX_TYPE_SDP;
+       ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -1911,10 +1867,7 @@ GF_Err trpy_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *trpy_New()
 {
-       GF_TRPYBox *tmp = (GF_TRPYBox *) gf_malloc(sizeof(GF_TRPYBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TRPY;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -1956,10 +1909,7 @@ GF_Err totl_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *totl_New()
 {
-       GF_TOTLBox *tmp = (GF_TOTLBox *) gf_malloc(sizeof(GF_TOTLBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TOTL;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
        return (GF_Box *)tmp;
 }
 
@@ -2002,10 +1952,7 @@ GF_Err nump_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *nump_New()
 {
-       GF_NUMPBox *tmp = (GF_NUMPBox *) gf_malloc(sizeof(GF_NUMPBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_NUMP;
-       tmp->nbPackets = 0;
+       ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
        return (GF_Box *)tmp;
 }
 
@@ -2047,10 +1994,7 @@ GF_Err npck_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *npck_New()
 {
-       GF_NPCKBox *tmp = (GF_NPCKBox *) gf_malloc(sizeof(GF_NPCKBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_NPCK;
-       tmp->nbPackets = 0;
+       ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2092,10 +2036,7 @@ GF_Err tpyl_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *tpyl_New()
 {
-       GF_NTYLBox *tmp = (GF_NTYLBox *) gf_malloc(sizeof(GF_NTYLBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TPYL;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2135,10 +2076,7 @@ GF_Err tpay_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *tpay_New()
 {
-       GF_TPAYBox *tmp = (GF_TPAYBox *) gf_malloc(sizeof(GF_TPAYBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TPAY;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2181,10 +2119,7 @@ GF_Err maxr_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *maxr_New()
 {
-       GF_MAXRBox *tmp = (GF_MAXRBox *) gf_malloc(sizeof(GF_MAXRBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_MAXR;
-       tmp->granularity = tmp->maxDataRate = 0;
+       ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2226,10 +2161,7 @@ GF_Err dmed_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *dmed_New()
 {
-       GF_DMEDBox *tmp = (GF_DMEDBox *) gf_malloc(sizeof(GF_DMEDBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_DMED;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2269,10 +2201,7 @@ GF_Err dimm_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *dimm_New()
 {
-       GF_DIMMBox *tmp = (GF_DIMMBox *) gf_malloc(sizeof(GF_DIMMBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_DIMM;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2312,10 +2241,7 @@ GF_Err drep_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *drep_New()
 {
-       GF_DREPBox *tmp = (GF_DREPBox *) gf_malloc(sizeof(GF_DREPBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_DREP;
-       tmp->nbBytes = 0;
+       ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2357,10 +2283,7 @@ GF_Err tmin_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *tmin_New()
 {
-       GF_TMINBox *tmp = (GF_TMINBox *) gf_malloc(sizeof(GF_TMINBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TMIN;
-       tmp->minTime = 0;
+       ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2401,10 +2324,7 @@ GF_Err tmax_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *tmax_New()
 {
-       GF_TMAXBox *tmp = (GF_TMAXBox *) gf_malloc(sizeof(GF_TMAXBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TMAX;
-       tmp->maxTime = 0;
+       ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2445,10 +2365,7 @@ GF_Err pmax_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *pmax_New()
 {
-       GF_PMAXBox *tmp = (GF_PMAXBox *) gf_malloc(sizeof(GF_PMAXBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_PMAX;
-       tmp->maxSize = 0;
+       ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2489,10 +2406,7 @@ GF_Err dmax_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *dmax_New()
 {
-       GF_DMAXBox *tmp = (GF_DMAXBox *) gf_malloc(sizeof(GF_DMAXBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_DMAX;
-       tmp->maxDur = 0;
+       ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2543,11 +2457,7 @@ GF_Err payt_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *payt_New()
 {
-       GF_PAYTBox *tmp = (GF_PAYTBox *) gf_malloc(sizeof(GF_PAYTBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_PAYT;
-       tmp->payloadCode = 0;
-       tmp->payloadString = NULL;
+       ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2602,10 +2512,7 @@ GF_Err name_Read(GF_Box *s, GF_BitStream *bs)
 }
 GF_Box *name_New()
 {
-       GF_NameBox *tmp = (GF_NameBox *) gf_malloc(sizeof(GF_NameBox));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_NAME;
-       tmp->string = NULL;
+       ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_ISOM_BOX_TYPE_NAME);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -2662,11 +2569,8 @@ GF_Err iods_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *iods_New()
 {
-       GF_ObjectDescriptorBox *tmp = (GF_ObjectDescriptorBox *) gf_malloc(sizeof(GF_ObjectDescriptorBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ObjectDescriptorBox));
+       ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_IODS;
        return (GF_Box *)tmp;
 }
 
@@ -2726,10 +2630,7 @@ GF_Err mdat_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mdat_New()
 {
-       GF_MediaDataBox *tmp = (GF_MediaDataBox *) gf_malloc(sizeof(GF_MediaDataBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MediaDataBox));
-       tmp->type = GF_ISOM_BOX_TYPE_MDAT;
+       ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT);
        return (GF_Box *)tmp;
 }
 
@@ -2810,12 +2711,9 @@ GF_Err mdhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mdhd_New()
 {
-       GF_MediaHeaderBox *tmp = (GF_MediaHeaderBox *) gf_malloc(sizeof(GF_MediaHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MediaHeaderBox));
+       ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD);
 
        gf_isom_full_box_init((GF_Box *) tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_MDHD;
 
        tmp->packedLanguage[0] = 'u';
        tmp->packedLanguage[1] = 'n';
@@ -2896,9 +2794,9 @@ GF_Err mdia_AddBox(GF_Box *s, GF_Box *a)
           if (ptr->information) return GF_ISOM_INVALID_FILE;
           ptr->information = (GF_MediaInformationBox *)a;
           return GF_OK;
+       default:
+               return gf_isom_box_add_default(s, a);
        }
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-       gf_isom_box_del(a);
        return GF_OK;           
 }
 
@@ -2910,10 +2808,7 @@ GF_Err mdia_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mdia_New()
 {   
-       GF_MediaBox *tmp = (GF_MediaBox *) gf_malloc(sizeof(GF_MediaBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MediaBox));
-       tmp->type = GF_ISOM_BOX_TYPE_MDIA;
+       ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA);
        return (GF_Box *)tmp;
 }
 
@@ -2991,10 +2886,7 @@ GF_Err mfhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mfhd_New()
 {
-       GF_MovieFragmentHeaderBox *tmp = (GF_MovieFragmentHeaderBox *) gf_malloc(sizeof(GF_MovieFragmentHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MovieFragmentHeaderBox));
-       tmp->type = GF_ISOM_BOX_TYPE_MFHD;
+       ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD);
        return (GF_Box *)tmp;
 }
 
@@ -3043,7 +2935,6 @@ void minf_del(GF_Box *s)
        if (ptr->InfoHeader) gf_isom_box_del((GF_Box *)ptr->InfoHeader);
        if (ptr->dataInformation) gf_isom_box_del((GF_Box *)ptr->dataInformation);
        if (ptr->sampleTable) gf_isom_box_del((GF_Box *)ptr->sampleTable);
-       gf_isom_box_array_del(ptr->boxes);
        gf_free(ptr);
 }
 
@@ -3070,7 +2961,7 @@ GF_Err minf_AddBox(GF_Box *s, GF_Box *a)
                ptr->sampleTable = (GF_SampleTableBox *)a;
                return GF_OK;
        default:
-               return gf_list_add(ptr->boxes, a);
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -3083,11 +2974,7 @@ GF_Err minf_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *minf_New()
 {
-       GF_MediaInformationBox *tmp = (GF_MediaInformationBox *) gf_malloc(sizeof(GF_MediaInformationBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MediaInformationBox));
-       tmp->type = GF_ISOM_BOX_TYPE_MINF;
-       tmp->boxes = gf_list_new();
+       ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF);
        return (GF_Box *)tmp;
 }
 
@@ -3118,7 +3005,7 @@ GF_Err minf_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_write((GF_Box *) ptr->sampleTable, bs);
                if (e) return e;
        }
-       return gf_isom_box_array_write(s, ptr->boxes, bs);
+       return GF_OK;
 }
 
 GF_Err minf_Size(GF_Box *s)
@@ -3143,7 +3030,7 @@ GF_Err minf_Size(GF_Box *s)
                if (e) return e;
                ptr->size += ptr->sampleTable->size;
        }       
-       return gf_isom_box_array_size(s, ptr->boxes);
+       return GF_OK;
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -3171,10 +3058,9 @@ GF_Err moof_AddBox(GF_Box *s, GF_Box *a)
                return GF_OK;
        case GF_ISOM_BOX_TYPE_TRAF:
                return gf_list_add(ptr->TrackList, a);
+       case GF_ISOM_BOX_TYPE_PSSH:
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               return GF_OK;           
+               return gf_isom_box_add_default(s, a);
        }
 }
 
@@ -3185,10 +3071,7 @@ GF_Err moof_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *moof_New()
 {
-       GF_MovieFragmentBox *tmp = (GF_MovieFragmentBox *) gf_malloc(sizeof(GF_MovieFragmentBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MovieFragmentBox));
-       tmp->type = GF_ISOM_BOX_TYPE_MOOF;
+       ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF);
        tmp->TrackList = gf_list_new();
        return (GF_Box *)tmp;
 }
@@ -3249,7 +3132,6 @@ void moov_del(GF_Box *s)
 #endif
 
        gf_isom_box_array_del(ptr->trackList);
-       gf_isom_box_array_del(ptr->boxes);
        gf_free(ptr);
 }
 
@@ -3295,13 +3177,13 @@ GF_Err moov_AddBox(GF_Box *s, GF_Box *a)
                //set our pointer to this obj
                ((GF_TrackBox *)a)->moov = ptr;
                return gf_list_add(ptr->trackList, a);
+       case GF_ISOM_BOX_TYPE_PSSH:
        default:
-               return gf_list_add(ptr->boxes, a);
+               return gf_isom_box_add_default(s, a);
        }
 }
 
 
-
 GF_Err moov_Read(GF_Box *s, GF_BitStream *bs)
 {
        return gf_isom_read_box_list(s, bs, moov_AddBox);
@@ -3309,21 +3191,12 @@ GF_Err moov_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *moov_New()
 {
-       GF_MovieBox *tmp = (GF_MovieBox *) gf_malloc(sizeof(GF_MovieBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MovieBox));
+       ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV);
        tmp->trackList = gf_list_new();
        if (!tmp->trackList) {
                gf_free(tmp);
                return NULL;
        }
-       tmp->boxes = gf_list_new();
-       if (!tmp->boxes) {
-               gf_list_del(tmp->trackList);
-               gf_free(tmp);
-               return NULL;
-       }
-       tmp->type = GF_ISOM_BOX_TYPE_MOOV;
        return (GF_Box *)tmp;
 }
 
@@ -3366,7 +3239,7 @@ GF_Err moov_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_write((GF_Box *) ptr->udta, bs);
                if (e) return e;
        }
-       return gf_isom_box_array_write(s, ptr->boxes, bs);
+       return GF_OK;
 }
 
 GF_Err moov_Size(GF_Box *s)
@@ -3404,9 +3277,7 @@ GF_Err moov_Size(GF_Box *s)
        }
 #endif
 
-       e = gf_isom_box_array_size(s, ptr->trackList);
-       if (e) return e;
-       return gf_isom_box_array_size(s, ptr->boxes);
+       return gf_isom_box_array_size(s, ptr->trackList);
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -3415,9 +3286,10 @@ void mp4a_del(GF_Box *s)
 {
        GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
        if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
-       if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info);
        gf_free(ptr);
 }
 
@@ -3430,8 +3302,7 @@ GF_Err mp4a_AddBox(GF_Box *s, GF_Box *a)
                ptr->esd = (GF_ESDBox *)a;
                break;
        case GF_ISOM_BOX_TYPE_SINF:
-               if (ptr->protection_info) return GF_ISOM_INVALID_FILE;
-               ptr->protection_info = (GF_ProtectionInfoBox*)a;
+               gf_list_add(ptr->protections, a);
                break;
        case GF_4CC('w','a','v','e'):
                if (ptr->esd) return GF_ISOM_INVALID_FILE;
@@ -3456,9 +3327,7 @@ GF_Err mp4a_AddBox(GF_Box *s, GF_Box *a)
                }
                break;
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               break;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -3497,18 +3366,14 @@ GF_Err mp4a_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mp4a_New()
 {
-       GF_MPEGAudioSampleEntryBox *tmp = (GF_MPEGAudioSampleEntryBox *)gf_malloc(sizeof(GF_MPEGAudioSampleEntryBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MPEGAudioSampleEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_MP4A;
+       ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A);
        gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
        return (GF_Box *)tmp;
 }
 
 GF_Box *enca_New() 
 {
-       GF_Box *tmp = mp4a_New();
-       tmp->type = GF_ISOM_BOX_TYPE_ENCA;
+       ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_ENCA);
        return tmp;
 }
 
@@ -3524,11 +3389,8 @@ GF_Err mp4a_Write(GF_Box *s, GF_BitStream *bs)
        gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
        e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
        if (e) return e;
-       if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCA)) {
-               e = gf_isom_box_write((GF_Box *)ptr->protection_info, bs);
-               if (e) return e;
-       }
-       return GF_OK;
+
+       return gf_isom_box_array_write(s, ptr->protections, bs);
 }
 
 GF_Err mp4a_Size(GF_Box *s)
@@ -3543,12 +3405,7 @@ GF_Err mp4a_Size(GF_Box *s)
        e = gf_isom_box_size((GF_Box *)ptr->esd);
        if (e) return e;
        ptr->size += ptr->esd->size;
-       if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCA)) {
-               e = gf_isom_box_size((GF_Box *)ptr->protection_info);
-               if (e) return e;
-               ptr->size += ptr->protection_info->size;
-       }
-       return GF_OK;
+       return gf_isom_box_array_size(s, ptr->protections);
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -3558,9 +3415,10 @@ void mp4s_del(GF_Box *s)
 {
        GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
        if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
-       if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info);
        gf_free(ptr);
 }
 
@@ -3573,13 +3431,10 @@ GF_Err mp4s_AddBox(GF_Box *s, GF_Box *a)
                ptr->esd = (GF_ESDBox *)a;
                break;
        case GF_ISOM_BOX_TYPE_SINF:
-               if (ptr->protection_info) return GF_ISOM_INVALID_FILE;
-               ptr->protection_info = (GF_ProtectionInfoBox*)a;
+               gf_list_add(ptr->protections, a);
                break;
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               break;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -3595,18 +3450,14 @@ GF_Err mp4s_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mp4s_New()
 {
-       GF_MPEGSampleEntryBox *tmp = (GF_MPEGSampleEntryBox *) gf_malloc(sizeof(GF_MPEGSampleEntryBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MPEGSampleEntryBox));
-
-       tmp->type = GF_ISOM_BOX_TYPE_MP4S;
+       ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S);
+       gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
        return (GF_Box *)tmp;
 }
 
 GF_Box *encs_New()
 {
-       GF_Box *tmp = mp4s_New();
-       tmp->type = GF_ISOM_BOX_TYPE_ENCS;
+       ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_ENCS);
        return tmp;
 }
 
@@ -3624,10 +3475,7 @@ GF_Err mp4s_Write(GF_Box *s, GF_BitStream *bs)
        gf_bs_write_u16(bs, ptr->dataReferenceIndex);
        e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
        if (e) return e;
-       if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCS)) {
-               e = gf_isom_box_write((GF_Box *)ptr->protection_info, bs);
-       }
-       return e;
+       return gf_isom_box_array_write(s, ptr->protections, bs);
 }
 
 GF_Err mp4s_Size(GF_Box *s)
@@ -3641,12 +3489,7 @@ GF_Err mp4s_Size(GF_Box *s)
        e = gf_isom_box_size((GF_Box *)ptr->esd);
        if (e) return e;
        ptr->size += ptr->esd->size;
-       if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCS)) {
-               e = gf_isom_box_size((GF_Box *)ptr->protection_info);
-               if (e) return e;
-               ptr->size += ptr->protection_info->size;
-       }
-       return GF_OK;
+       return gf_isom_box_array_size(s, ptr->protections);
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -3655,6 +3498,8 @@ void mp4v_del(GF_Box *s)
 {
        GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
        if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
        if (ptr->avc_config) gf_isom_box_del((GF_Box *) ptr->avc_config);
@@ -3668,7 +3513,6 @@ void mp4v_del(GF_Box *s)
        if (ptr->pasp) gf_isom_box_del((GF_Box *)ptr->pasp);
        if (ptr->rvcc) gf_isom_box_del((GF_Box *)ptr->rvcc);
 
-       if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info);
        gf_free(ptr);
 }
 
@@ -3681,8 +3525,7 @@ GF_Err mp4v_AddBox(GF_Box *s, GF_Box *a)
                ptr->esd = (GF_ESDBox *)a;
                break;
        case GF_ISOM_BOX_TYPE_SINF:
-               if (ptr->protection_info) return GF_ISOM_INVALID_FILE;
-               ptr->protection_info = (GF_ProtectionInfoBox*)a;
+               gf_list_add(ptr->protections, a);
                break;
        case GF_ISOM_BOX_TYPE_AVCC:
                if (ptr->avc_config) return GF_ISOM_INVALID_FILE;
@@ -3713,9 +3556,7 @@ GF_Err mp4v_AddBox(GF_Box *s, GF_Box *a)
                ptr->rvcc = (GF_RVCConfigurationBox *)a;
                break;
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               break;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -3812,15 +3653,11 @@ GF_Err mp4v_Write(GF_Box *s, GF_BitStream *bs)
                        if (e) return e;
                }
        }
-       if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCV)) {
-               e = gf_isom_box_write((GF_Box *)ptr->protection_info, bs);
-               if (e) return e;
-       }
        if (ptr->rvcc) {
                e = gf_isom_box_write((GF_Box *)ptr->rvcc, bs);
                if (e) return e;
        }
-       return e;
+       return gf_isom_box_array_write(s, ptr->protections, bs);
 }
 
 GF_Err mp4v_Size(GF_Box *s)
@@ -3876,12 +3713,7 @@ GF_Err mp4v_Size(GF_Box *s)
                if (e) return e;
                ptr->size += ptr->rvcc->size;
        }
-       if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCV)) {
-               e = gf_isom_box_size((GF_Box *)ptr->protection_info);
-               if (e) return e;
-               ptr->size += ptr->protection_info->size;
-       }
-       return GF_OK;
+       return gf_isom_box_array_size(s, ptr->protections);
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -3911,9 +3743,9 @@ GF_Err mvex_AddBox(GF_Box *s, GF_Box *a)
                if (ptr->mehd) break;
                ptr->mehd = (GF_MovieExtendsHeaderBox*)a;
                return GF_OK;
+       default:
+               return gf_isom_box_add_default(s, a);
        }
-       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-       gf_isom_box_del(a);
        return GF_OK;           
 }
 
@@ -3926,15 +3758,12 @@ GF_Err mvex_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mvex_New()
 {
-       GF_MovieExtendsBox *tmp = (GF_MovieExtendsBox *) gf_malloc(sizeof(GF_MovieExtendsBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MovieExtendsBox));
+       ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX);
        tmp->TrackExList = gf_list_new();
        if (!tmp->TrackExList) {
                gf_free(tmp);
                return NULL;
        }
-       tmp->type = GF_ISOM_BOX_TYPE_MVEX;
        return (GF_Box *)tmp;
 }
 
@@ -3950,6 +3779,10 @@ GF_Err mvex_Write(GF_Box *s, GF_BitStream *bs)
        if (!s) return GF_BAD_PARAM;
        e = gf_isom_box_write_header(s, bs);
        if (e) return e;
+       if (ptr->mehd) {
+               e = gf_isom_box_write((GF_Box *)ptr->mehd, bs);
+               if (e) return e;
+       }
        return gf_isom_box_array_write(s, ptr->TrackExList, bs);
 }
 
@@ -3959,6 +3792,11 @@ GF_Err mvex_Size(GF_Box *s)
        GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
        e = gf_isom_box_get_size(s);
        if (e) return e;
+       if (ptr->mehd) {
+               e = gf_isom_box_size((GF_Box *)ptr->mehd);
+               if (e) return e;
+               ptr->size += ptr->mehd->size;
+       }
        return gf_isom_box_array_size(s, ptr->TrackExList);
 }
 
@@ -3968,10 +3806,7 @@ GF_Err mvex_Size(GF_Box *s)
 
 GF_Box *mehd_New()
 {
-       GF_MovieExtendsHeaderBox *tmp;
-       GF_SAFEALLOC(tmp, GF_MovieExtendsHeaderBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_MEHD;
+       ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
        return (GF_Box *)tmp;
 }
 void mehd_del(GF_Box *s)
@@ -4069,12 +3904,10 @@ GF_Err mvhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *mvhd_New()
 {
-       GF_MovieHeaderBox *tmp = (GF_MovieHeaderBox *) gf_malloc(sizeof(GF_MovieHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MovieHeaderBox));
+       ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD);
 
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_MVHD;
+
        tmp->preferredRate = (1<<16);
        tmp->preferredVolume = (1<<8);
 
@@ -4133,7 +3966,8 @@ GF_Err mvhd_Size(GF_Box *s)
 {
        GF_Err e;
        GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
-       ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
+       if (ptr->duration==(u64) -1) ptr->version = 0;
+       else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
        e = gf_isom_full_box_get_size(s);
        if (e) return e;
        ptr->size += (ptr->version == 1) ? 28 : 16;
@@ -4162,10 +3996,8 @@ GF_Err nmhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *nmhd_New()
 {
-       GF_MPEGMediaHeaderBox *tmp = (GF_MPEGMediaHeaderBox *) gf_malloc(sizeof(GF_MPEGMediaHeaderBox));
-       if (tmp == NULL) return NULL;
+       ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD);
        gf_isom_full_box_init((GF_Box *) tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_NMHD;
        return (GF_Box *)tmp;
 }
 
@@ -4222,14 +4054,8 @@ GF_Err padb_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *padb_New()
 {
-       GF_PaddingBitsBox *tmp;
-       
-       tmp = (GF_PaddingBitsBox *) gf_malloc(sizeof(GF_PaddingBitsBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_PaddingBitsBox));
-
+       ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_FADB;
        return (GF_Box *)tmp;
 }
 
@@ -4293,11 +4119,7 @@ GF_Err rely_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *rely_New()
 {
-       GF_RelyHintBox *tmp = (GF_RelyHintBox *)gf_malloc(sizeof(GF_RelyHintBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_RelyHintBox));
-       tmp->type = GF_ISOM_BOX_TYPE_RELY;
-
+       ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY);
        return (GF_Box *)tmp;
 }
 
@@ -4342,10 +4164,7 @@ GF_Err rtpo_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *rtpo_New()
 {
-       GF_RTPOBox *tmp = (GF_RTPOBox *) gf_malloc(sizeof(GF_RTPOBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_RTPOBox));
-       tmp->type = GF_ISOM_BOX_TYPE_RTPO;
+       ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO);
        return (GF_Box *)tmp;
 }
 #ifndef GPAC_DISABLE_ISOM_WRITE
@@ -4393,11 +4212,8 @@ GF_Err smhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *smhd_New()
 {
-       GF_SoundMediaHeaderBox *tmp = (GF_SoundMediaHeaderBox *) gf_malloc(sizeof(GF_SoundMediaHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SoundMediaHeaderBox));
+       ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD);
        gf_isom_full_box_init((GF_Box *) tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_SMHD;
        return (GF_Box *)tmp;
 }
 
@@ -4444,10 +4260,7 @@ GF_Err snro_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *snro_New()
 {
-       GF_SeqOffHintEntryBox *tmp = (GF_SeqOffHintEntryBox *) gf_malloc(sizeof(GF_SeqOffHintEntryBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_SeqOffHintEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_SNRO;
+       ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO);
        return (GF_Box *)tmp;
 }
 
@@ -4485,6 +4298,7 @@ void stbl_del(GF_Box *s)
 
        if (ptr->ChunkOffset) gf_isom_box_del(ptr->ChunkOffset);
        if (ptr->CompositionOffset) gf_isom_box_del((GF_Box *) ptr->CompositionOffset);
+       if (ptr->CompositionToDecode) gf_isom_box_del((GF_Box *) ptr->CompositionToDecode);
        if (ptr->DegradationPriority) gf_isom_box_del((GF_Box *) ptr->DegradationPriority);
        if (ptr->SampleDescription) gf_isom_box_del((GF_Box *) ptr->SampleDescription);
        if (ptr->SampleSize) gf_isom_box_del((GF_Box *) ptr->SampleSize);
@@ -4499,6 +4313,9 @@ void stbl_del(GF_Box *s)
        if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
        if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);
 
+       if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
+       if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
+
        gf_free(ptr);
 }
 
@@ -4514,6 +4331,10 @@ GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a)
                if (ptr->CompositionOffset) return GF_ISOM_INVALID_FILE;
                ptr->CompositionOffset = (GF_CompositionOffsetBox *)a;
                break;
+       case GF_ISOM_BOX_TYPE_CSLG:
+               if (ptr->CompositionToDecode) return GF_ISOM_INVALID_FILE;
+               ptr->CompositionToDecode = (GF_CompositionToDecodeBox *)a;
+               break;
        case GF_ISOM_BOX_TYPE_STSS:
                if (ptr->SyncSample) return GF_ISOM_INVALID_FILE;
                ptr->SyncSample = (GF_SyncSampleBox *)a;
@@ -4531,7 +4352,7 @@ GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a)
                if (ptr->SampleToChunk) return GF_ISOM_INVALID_FILE;
                ptr->SampleToChunk = (GF_SampleToChunkBox *)a;
                break;
-       case GF_ISOM_BOX_TYPE_FADB:
+       case GF_ISOM_BOX_TYPE_PADB:
                if (ptr->PaddingBits) return GF_ISOM_INVALID_FILE;
                ptr->PaddingBits = (GF_PaddingBitsBox *) a;
                break;
@@ -4576,10 +4397,17 @@ GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a)
                gf_list_add(ptr->sampleGroupsDescription, a);
                break;
 
-       default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
+       case GF_ISOM_BOX_TYPE_SAIZ:
+               if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
+               gf_list_add(ptr->sai_sizes, a);
                break;
+       case GF_ISOM_BOX_TYPE_SAIO:
+               if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
+               gf_list_add(ptr->sai_offsets, a);
+               break;
+
+       default:
+               return gf_isom_box_add_default((GF_Box *)ptr, a);
        }
        return GF_OK;
 }
@@ -4632,11 +4460,7 @@ GF_Err stbl_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stbl_New()
 {
-       GF_SampleTableBox *tmp = (GF_SampleTableBox *) gf_malloc(sizeof(GF_SampleTableBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SampleTableBox));
-
-       tmp->type = GF_ISOM_BOX_TYPE_STBL;
+       ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL);
        //maxSamplePer chunk is 10 by default
        tmp->MaxSamplePerChunk = 10;
        tmp->groupID = 1;
@@ -4667,6 +4491,10 @@ GF_Err stbl_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_write((GF_Box *) ptr->CompositionOffset, bs);
                if (e) return e;
        }
+       if (ptr->CompositionToDecode)   {
+               e = gf_isom_box_write((GF_Box *) ptr->CompositionToDecode, bs);
+               if (e) return e;
+       }
        if (ptr->SyncSample) {
                e = gf_isom_box_write((GF_Box *) ptr->SyncSample, bs);
                if (e) return e;
@@ -4711,6 +4539,14 @@ GF_Err stbl_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
                if (e) return e;
        }
+       if (ptr->sai_sizes) {
+               e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
+               if (e) return e;
+       }
+       if (ptr->sai_offsets) {
+               e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
+               if (e) return e;
+       }
 
 #if WRITE_SAMPLE_FRAGMENTS
        //sampleFragments
@@ -4762,6 +4598,11 @@ GF_Err stbl_Size(GF_Box *s)
                if (e) return e;
                ptr->size += ptr->CompositionOffset->size;
        }
+       if (ptr->CompositionToDecode)   {
+               e = gf_isom_box_size((GF_Box *) ptr->CompositionToDecode);
+               if (e) return e;
+               ptr->size += ptr->CompositionToDecode->size;
+       }
        if (ptr->DegradationPriority) {
                e = gf_isom_box_size((GF_Box *) ptr->DegradationPriority);
                if (e) return e;
@@ -4810,6 +4651,14 @@ GF_Err stbl_Size(GF_Box *s)
                e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
                if (e) return e;
        }       
+       if (ptr->sai_sizes) {
+               e = gf_isom_box_array_size(s, ptr->sai_sizes);
+               if (e) return e;
+       }       
+       if (ptr->sai_offsets) {
+               e = gf_isom_box_array_size(s, ptr->sai_offsets);
+               if (e) return e;
+       }       
        return GF_OK;
 }
 
@@ -4849,11 +4698,8 @@ GF_Err stco_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stco_New()
 {
-       GF_ChunkOffsetBox *tmp = (GF_ChunkOffsetBox *) gf_malloc(sizeof(GF_ChunkOffsetBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ChunkOffsetBox));
+       ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_STCO;
        return (GF_Box *)tmp;
 }
 
@@ -4907,25 +4753,21 @@ GF_Err stdp_Read(GF_Box *s, GF_BitStream *bs)
 
        e = gf_isom_full_box_read(s, bs);
        if (e) return e;
-       /*out-of-order stdp, assume no padding at the end*/
-       if (!ptr->nb_entries) ptr->nb_entries = (u32) (ptr->size-8) / 2;
+       /*out-of-order stdp, assume no padding at the end and take the entire remaining data for entries*/
+       if (!ptr->nb_entries) ptr->nb_entries = (u32) ptr->size / 2;
+
        ptr->priorities = (u16 *) gf_malloc(ptr->nb_entries * sizeof(u16));
        if (ptr->priorities == NULL) return GF_OUT_OF_MEM;
        for (entry = 0; entry < ptr->nb_entries; entry++) {
-               //we have a bit for padding
-               gf_bs_read_int(bs, 1);
-               ptr->priorities[entry] = gf_bs_read_int(bs, 15);
+               ptr->priorities[entry] = gf_bs_read_u16(bs);
        }
        return GF_OK;
 }
 
 GF_Box *stdp_New()
 {
-       GF_DegradationPriorityBox *tmp = (GF_DegradationPriorityBox *) gf_malloc(sizeof(GF_DegradationPriorityBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_DegradationPriorityBox));
+       ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_STDP;
        return (GF_Box *)tmp;
 }
 
@@ -4941,8 +4783,7 @@ GF_Err stdp_Write(GF_Box *s, GF_BitStream *bs)
        if (e) return e;
 
        for (i = 0; i < ptr->nb_entries; i++) {
-               gf_bs_write_int(bs, 0, 1);
-               gf_bs_write_int(bs, ptr->priorities[i], 15);
+               gf_bs_write_u16(bs, ptr->priorities[i]);
        }
        return GF_OK;
 }
@@ -5001,11 +4842,8 @@ GF_Err stsc_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stsc_New()
 {
-       GF_SampleToChunkBox *tmp = (GF_SampleToChunkBox *) gf_malloc(sizeof(GF_SampleToChunkBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SampleToChunkBox));
+       ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_STSC;
        return (GF_Box *)tmp;
 }
 
@@ -5045,7 +4883,6 @@ void stsd_del(GF_Box *s)
 {
        GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
        if (ptr == NULL) return;
-       gf_isom_box_array_del(ptr->boxList);
        gf_free(ptr);
 }
 
@@ -5074,7 +4911,7 @@ GF_Err stsd_AddBox(GF_SampleDescriptionBox *ptr, GF_Box *a)
        case GF_ISOM_BOX_TYPE_DIMS:
        case GF_ISOM_BOX_TYPE_AC3:
        case GF_ISOM_BOX_TYPE_LSR1:
-               return gf_list_add(ptr->boxList, a);
+               return gf_isom_box_add_default((GF_Box*)ptr, a);
        /*for 3GP config, we must set the type*/
        case GF_ISOM_SUBTYPE_3GP_AMR:
        case GF_ISOM_SUBTYPE_3GP_AMR_WB:
@@ -5083,12 +4920,12 @@ GF_Err stsd_AddBox(GF_SampleDescriptionBox *ptr, GF_Box *a)
        case GF_ISOM_SUBTYPE_3GP_SMV:
        {
                ((GF_3GPPAudioSampleEntryBox *)a)->info->cfg.type = a->type;
-               return gf_list_add(ptr->boxList, a);
+               return gf_isom_box_add_default((GF_Box*)ptr, a);
        }
        case GF_ISOM_SUBTYPE_3GP_H263:
        {
                ((GF_3GPPVisualSampleEntryBox *)a)->info->cfg.type = a->type;
-               return gf_list_add(ptr->boxList, a);
+               return gf_isom_box_add_default((GF_Box*)ptr, a);
        }
 
        //unknown sample description: we need a specific box to handle the data ref index
@@ -5100,7 +4937,7 @@ GF_Err stsd_AddBox(GF_SampleDescriptionBox *ptr, GF_Box *a)
                        gf_isom_box_del(a);
                        return GF_OK;
                }
-               return gf_list_add(ptr->boxList, a);
+               return gf_isom_box_add_default((GF_Box*)ptr, a);
        }
 }
 
@@ -5127,16 +4964,9 @@ GF_Err stsd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stsd_New()
 {
-       GF_SampleDescriptionBox *tmp = (GF_SampleDescriptionBox *) gf_malloc(sizeof(GF_SampleDescriptionBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SampleDescriptionBox));
+       ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->boxList = gf_list_new();
-       if (! tmp->boxList) {
-               gf_free(tmp);
-               return NULL;
-       }
-       tmp->type = GF_ISOM_BOX_TYPE_STSD;
+       tmp->other_boxes = gf_list_new();
        return (GF_Box *)tmp;
 }
 
@@ -5151,9 +4981,9 @@ GF_Err stsd_Write(GF_Box *s, GF_BitStream *bs)
 
        e = gf_isom_full_box_write(s, bs);
        if (e) return e;
-       nb_entries = gf_list_count(ptr->boxList);
+       nb_entries = gf_list_count(ptr->other_boxes);
        gf_bs_write_u32(bs, nb_entries);
-       return gf_isom_box_array_write(s, ptr->boxList, bs);
+       return GF_OK;
 }
 
 GF_Err stsd_Size(GF_Box *s)
@@ -5163,7 +4993,7 @@ GF_Err stsd_Size(GF_Box *s)
        e = gf_isom_full_box_get_size(s);
        if (e) return e;
        ptr->size += 4;
-       return gf_isom_box_array_size(s, ptr->boxList);
+       return GF_OK;
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -5225,11 +5055,7 @@ GF_Err stsf_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stsf_New()
 {
-       GF_SampleFragmentBox *tmp;
-       
-       tmp = (GF_SampleFragmentBox *) gf_malloc(sizeof(GF_SampleFragmentBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SampleFragmentBox));
+       ISOM_DECL_BOX_ALLOC(GF_SampleFragmentBox, GF_ISOM_BOX_TYPE_STSF);
 
        gf_isom_full_box_init((GF_Box *) tmp);
        tmp->entryList = gf_list_new();
@@ -5237,7 +5063,6 @@ GF_Box *stsf_New()
                gf_free(tmp);
                return NULL;
        }
-       tmp->type = GF_ISOM_BOX_TYPE_STSF;
        return (GF_Box *) tmp;
 }
 
@@ -5328,16 +5153,13 @@ GF_Err stsh_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stsh_New()
 {
-       GF_ShadowSyncBox *tmp = (GF_ShadowSyncBox *) gf_malloc(sizeof(GF_ShadowSyncBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ShadowSyncBox));
+       ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH);
        gf_isom_full_box_init((GF_Box *)tmp);
        tmp->entries = gf_list_new();
        if (!tmp->entries) {
                gf_free(tmp);
                return NULL;
        }
-       tmp->type = GF_ISOM_BOX_TYPE_STSH;
        return (GF_Box *)tmp;
 }
 
@@ -5405,11 +5227,8 @@ GF_Err stss_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stss_New()
 {
-       GF_SyncSampleBox *tmp = (GF_SyncSampleBox *) gf_malloc(sizeof(GF_SyncSampleBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SyncSampleBox));
+       ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_STSS;
        return (GF_Box*)tmp;
 }
 
@@ -5538,9 +5357,7 @@ GF_Err stsz_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stsz_New()
 {
-       GF_SampleSizeBox *tmp = (GF_SampleSizeBox *) gf_malloc(sizeof(GF_SampleSizeBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SampleSizeBox));
+       ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0);
 
        gf_isom_full_box_init((GF_Box *)tmp);
        //type is unknown here, can be regular or compact table
@@ -5706,11 +5523,8 @@ GF_Err stts_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *stts_New()
 {
-       GF_TimeToSampleBox *tmp = (GF_TimeToSampleBox *) gf_malloc(sizeof(GF_TimeToSampleBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TimeToSampleBox));
+       ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_STTS;
        return (GF_Box *)tmp;
 }
 
@@ -5787,10 +5601,7 @@ GF_Err tfhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *tfhd_New()
 {
-       GF_TrackFragmentHeaderBox *tmp = (GF_TrackFragmentHeaderBox *) gf_malloc(sizeof(GF_TrackFragmentHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackFragmentHeaderBox));
-       tmp->type = GF_ISOM_BOX_TYPE_TFHD;
+       ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD);
        //NO FLAGS SET BY DEFAULT
        return (GF_Box *)tmp;
 }
@@ -5866,10 +5677,7 @@ GF_Err tims_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *tims_New()
 {
-       GF_TSHintEntryBox *tmp = (GF_TSHintEntryBox *) gf_malloc(sizeof(GF_TSHintEntryBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_TSHintEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_TIMS;
+       ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS);
        return (GF_Box *)tmp;
 }
 
@@ -5948,11 +5756,8 @@ GF_Err tkhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *tkhd_New()
 {
-       GF_TrackHeaderBox *tmp = (GF_TrackHeaderBox *) gf_malloc(sizeof(GF_TrackHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackHeaderBox));
+       ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_TKHD;
        tmp->matrix[0] = 0x00010000;
        tmp->matrix[4] = 0x00010000;
        tmp->matrix[8] = 0x40000000;
@@ -6009,7 +5814,8 @@ GF_Err tkhd_Size(GF_Box *s)
        GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
        e = gf_isom_full_box_get_size(s);
        if (e) return e;
-       ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
+       if (ptr->duration==(u64) -1) ptr->version = 0;
+       else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
        ptr->size += (ptr->version == 1) ? 32 : 20;
        ptr->size += 60;
        return GF_OK;
@@ -6029,9 +5835,12 @@ void traf_del(GF_Box *s)
        if (ptr->sdtp) gf_isom_box_del((GF_Box *) ptr->sdtp);
        if (ptr->subs) gf_isom_box_del((GF_Box *) ptr->subs);
        if (ptr->tfdt) gf_isom_box_del((GF_Box *) ptr->tfdt);
+       if (ptr->piff_sample_encryption) gf_isom_box_del((GF_Box *) ptr->piff_sample_encryption);
        gf_isom_box_array_del(ptr->TrackRuns);
        if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
        if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);
+       if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
+       if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
        gf_free(ptr);
 }
 
@@ -6066,10 +5875,25 @@ GF_Err traf_AddBox(GF_Box *s, GF_Box *a)
                if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new();
                gf_list_add(ptr->sampleGroupsDescription, a);
                return GF_OK;           
-       default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
+       case GF_ISOM_BOX_TYPE_SAIZ:
+               if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
+               gf_list_add(ptr->sai_sizes, a);
+               return GF_OK;
+       case GF_ISOM_BOX_TYPE_SAIO:
+               if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
+               gf_list_add(ptr->sai_offsets, a);
                return GF_OK;           
+       case GF_ISOM_BOX_TYPE_UUID:
+               if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_PSEC) {
+                       if (ptr->piff_sample_encryption) return GF_ISOM_INVALID_FILE;
+                       ptr->piff_sample_encryption = (GF_PIFFSampleEncryptionBox *)a;
+                       ptr->piff_sample_encryption->traf = ptr;
+                       return GF_OK;
+               } else {
+                       return gf_isom_box_add_default(s, a);
+               }
+       default:
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;           
 }
@@ -6077,16 +5901,50 @@ GF_Err traf_AddBox(GF_Box *s, GF_Box *a)
 
 GF_Err traf_Read(GF_Box *s, GF_BitStream *bs)
 {
-       GF_Err e = gf_isom_read_box_list(s, bs, traf_AddBox);
-       return e;
+       GF_Box *a;
+
+       GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
+
+       while (ptr->size) {
+               GF_Err e = gf_isom_parse_box(&a, bs);
+               if (e) return e;
+
+
+               //we need to read the DegPriority in a different way...
+               if ((a->type == GF_ISOM_BOX_TYPE_STDP) || (a->type == GF_ISOM_BOX_TYPE_SDTP)) { 
+                       u32 nb_samples=0, i=0;
+                       u64 s = a->size;
+                       for (i=0; i<gf_list_count(ptr->TrackRuns); i++) {
+                               GF_TrackFragmentRunBox *trun = gf_list_get(ptr->TrackRuns, i);
+                               nb_samples+=trun->sample_count;
+                       }
+                       if (a->type == GF_ISOM_BOX_TYPE_STDP) {
+                               if (nb_samples) ((GF_DegradationPriorityBox *)a)->nb_entries = nb_samples;
+                               e = stdp_Read(a, bs);
+                       } else {
+                               if (nb_samples) ((GF_SampleDependencyTypeBox *)a)->sampleCount = nb_samples;
+                               e = sdtp_Read(a, bs);
+                       }
+                       if (e) {
+                               gf_isom_box_del(a);
+                               return e;
+                       }
+                       a->size = s;
+               }
+               if (ptr->size<a->size) {
+                       gf_isom_box_del(a);
+                       return GF_ISOM_INVALID_FILE;
+               }
+               ptr->size -= a->size;
+               e = traf_AddBox((GF_Box*)ptr, a);
+               if (e) return e;
+       }
+       return GF_OK;
 }
 
 GF_Box *traf_New()
 {
-       GF_TrackFragmentBox *tmp;
-       GF_SAFEALLOC(tmp, GF_TrackFragmentBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_TRAF;
+       ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF);
        tmp->TrackRuns = gf_list_new();
        return (GF_Box *)tmp;
 }
@@ -6128,10 +5986,22 @@ GF_Err traf_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
                if (e) return e;
        }
+       if (ptr->sai_sizes) {
+               e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
+               if (e) return e;
+       }
+       if (ptr->sai_offsets) {
+               e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
+               if (e) return e;
+       }
        e = gf_isom_box_array_write(s, ptr->TrackRuns, bs);
        if (e) return e;
 
-       return e;
+       if (ptr->piff_sample_encryption) {
+               e = gf_isom_box_write((GF_Box *) ptr->piff_sample_encryption, bs);
+               if (e) return e;
+       }
+       return GF_OK;
 }
 
 GF_Err traf_Size(GF_Box *s)
@@ -6146,6 +6016,11 @@ GF_Err traf_Size(GF_Box *s)
                if (e) return e;
                ptr->size += ptr->tfhd->size;
        }
+       if (ptr->piff_sample_encryption) {
+               e = gf_isom_box_size((GF_Box *) ptr->piff_sample_encryption);
+               if (e) return e;
+               ptr->size += ptr->piff_sample_encryption->size;
+       }
        if (ptr->subs) {
                e = gf_isom_box_size((GF_Box *) ptr->subs);
                if (e) return e;
@@ -6170,7 +6045,14 @@ GF_Err traf_Size(GF_Box *s)
                e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
                if (e) return e;
        }
-
+       if (ptr->sai_sizes) {
+               e = gf_isom_box_array_size(s, ptr->sai_sizes);
+               if (e) return e;
+       }
+       if (ptr->sai_offsets) {
+               e = gf_isom_box_array_size(s, ptr->sai_offsets);
+               if (e) return e;
+       }
        return gf_isom_box_array_size(s, ptr->TrackRuns);
 }
 
@@ -6192,7 +6074,6 @@ void trak_del(GF_Box *s)
        if (ptr->References) gf_isom_box_del((GF_Box *)ptr->References);
        if (ptr->editBox) gf_isom_box_del((GF_Box *)ptr->editBox);
        if (ptr->meta) gf_isom_box_del((GF_Box *)ptr->meta);
-       gf_isom_box_array_del(ptr->boxes);
        if (ptr->name) gf_free(ptr->name); 
        gf_free(ptr);
 }
@@ -6207,7 +6088,7 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak)
        u32 i;
 
        i=0;
-       while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->boxList, &i))) {
+       while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->other_boxes, &i))) {
                switch (a->type) {
                case GF_ISOM_BOX_TYPE_MP4S:
                case GF_ISOM_BOX_TYPE_ENCS:
@@ -6242,7 +6123,7 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak)
                switch (trak->Media->handler->handlerType) {
                case GF_ISOM_MEDIA_VISUAL:
                        /*remove entry*/
-                       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->boxList, i-1);
+                       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1);
                        genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
                        bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
                        genv->size = a->size;
@@ -6256,11 +6137,11 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak)
                        genv->size = a->size;
                        genv->EntryType = a->type;
                        gf_isom_box_del((GF_Box *)a);
-                       gf_list_insert(trak->Media->information->sampleTable->SampleDescription->boxList, genv, i-1);
+                       gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, genv, i-1);
                        break;
                case GF_ISOM_MEDIA_AUDIO:
                        /*remove entry*/
-                       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->boxList, i-1);
+                       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1);
                        gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
                        gena->size = a->size;
                        bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
@@ -6274,12 +6155,12 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak)
                        gena->size = a->size;
                        gena->EntryType = a->type;
                        gf_isom_box_del((GF_Box *)a);
-                       gf_list_insert(trak->Media->information->sampleTable->SampleDescription->boxList, gena, i-1);
+                       gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, gena, i-1);
                        break;
 
                default:
                        /*remove entry*/
-                       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->boxList, i-1);
+                       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1);
                        genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
                        genm->size = a->size;
                        bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
@@ -6294,7 +6175,7 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak)
                        genm->size = a->size;
                        genm->EntryType = a->type;
                        gf_isom_box_del((GF_Box *)a);
-                       gf_list_insert(trak->Media->information->sampleTable->SampleDescription->boxList, genm, i-1);
+                       gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, genm, i-1);
                        break;
                }
 
@@ -6333,9 +6214,7 @@ GF_Err trak_AddBox(GF_Box *s, GF_Box *a)
                ((GF_MediaBox *)a)->mediaTrack = ptr;
                return GF_OK;
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               return GF_OK;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -6353,11 +6232,7 @@ GF_Err trak_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *trak_New()
 {
-       GF_TrackBox *tmp = (GF_TrackBox *) gf_malloc(sizeof(GF_TrackBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackBox));
-       tmp->type = GF_ISOM_BOX_TYPE_TRAK;
-       tmp->boxes = gf_list_new();
+       ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK);
        return (GF_Box *)tmp;
 }
 
@@ -6395,7 +6270,7 @@ GF_Err trak_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_write((GF_Box *) ptr->udta, bs);
                if (e) return e;
        }
-       return gf_isom_box_array_write(s, ptr->boxes, bs);
+       return GF_OK;
 }
 
 GF_Err trak_Size(GF_Box *s)
@@ -6436,43 +6311,33 @@ GF_Err trak_Size(GF_Box *s)
                if (e) return e;
                ptr->size += ptr->meta->size;
        }
-       return gf_isom_box_array_size(s, ptr->boxes);
+       return GF_OK;
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 
+GF_Err tref_AddBox(GF_Box *ptr, GF_Box *a)
+{
+       return gf_isom_box_add_default(ptr, a);
+}
+
 void tref_del(GF_Box *s)
 {
        GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
        if (ptr == NULL) return;
-       gf_isom_box_array_del(ptr->boxList);
        gf_free(ptr);
 }
 
 
-GF_Err tref_AddBox(GF_Box *s, GF_Box *a)
-{
-       GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
-       return gf_list_add(ptr->boxList, a);
-}
-
 GF_Err tref_Read(GF_Box *s, GF_BitStream *bs)
 {
-       return gf_isom_read_box_list_ex(s, bs, tref_AddBox, s->type);
+       return gf_isom_read_box_list_ex(s, bs, gf_isom_box_add_default, s->type);
 }
 
 GF_Box *tref_New()
 {
-       GF_TrackReferenceBox *tmp = (GF_TrackReferenceBox *) gf_malloc(sizeof(GF_TrackReferenceBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackReferenceBox));
-       tmp->boxList = gf_list_new();
-       if (!tmp->boxList) {
-               gf_free(tmp);
-               return NULL;
-       }
-       tmp->type = GF_ISOM_BOX_TYPE_TREF;
+       ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF);
        return (GF_Box *)tmp;
 }
 
@@ -6482,20 +6347,14 @@ GF_Box *tref_New()
 
 GF_Err tref_Write(GF_Box *s, GF_BitStream *bs)
 {
-       GF_Err e;
-       GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
-       e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
-       return gf_isom_box_array_write(s, ptr->boxList, bs);
+//     GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
+       return gf_isom_box_write_header(s, bs);
 }
 
 GF_Err tref_Size(GF_Box *s)
 {
-       GF_Err e;
-       GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
-       e = gf_isom_box_get_size(s);
-       if (e) return e;
-       return gf_isom_box_array_size(s, ptr->boxList);
+//     GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
+       return gf_isom_box_get_size(s);
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -6530,10 +6389,7 @@ GF_Err reftype_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *reftype_New()
 {
-       GF_TrackReferenceTypeBox *tmp = (GF_TrackReferenceTypeBox *) gf_malloc(sizeof(GF_TrackReferenceTypeBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackReferenceTypeBox));
-       tmp->type = GF_ISOM_BOX_TYPE_REFT;
+       ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT);
        return (GF_Box *)tmp;
 }
 
@@ -6622,10 +6478,7 @@ GF_Err trex_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *trex_New()
 {
-       GF_TrackExtendsBox *tmp = (GF_TrackExtendsBox *) gf_malloc(sizeof(GF_TrackExtendsBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackExtendsBox));
-       tmp->type = GF_ISOM_BOX_TYPE_TREX;
+       ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX);
        return (GF_Box *)tmp;
 }
 
@@ -6744,10 +6597,7 @@ GF_Err trun_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *trun_New()
 {
-       GF_TrackFragmentRunBox *tmp = (GF_TrackFragmentRunBox *) gf_malloc(sizeof(GF_TrackFragmentRunBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_TrackFragmentRunBox));
-       tmp->type = GF_ISOM_BOX_TYPE_TRUN;
+       ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN);
        tmp->entries = gf_list_new();
        //NO FLAGS SET BY DEFAULT
        return (GF_Box *)tmp;
@@ -6850,10 +6700,7 @@ GF_Err tsro_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *tsro_New()
 {
-       GF_TimeOffHintEntryBox *tmp = (GF_TimeOffHintEntryBox *) gf_malloc(sizeof(GF_TimeOffHintEntryBox));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_TimeOffHintEntryBox));
-       tmp->type = GF_ISOM_BOX_TYPE_TSRO;
+       ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO);
        return (GF_Box *)tmp;
 }
 
@@ -6890,7 +6737,7 @@ void udta_del(GF_Box *s)
        if (ptr == NULL) return;
        i=0;
        while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
-               gf_isom_box_array_del(map->boxList);
+               gf_isom_box_array_del(map->other_boxes);
                gf_free(map);
        }
        gf_list_del(ptr->recordList);
@@ -6928,15 +6775,15 @@ GF_Err udta_AddBox(GF_UserDataBox *ptr, GF_Box *a)
                map->boxType = a->type;
                if (a->type == GF_ISOM_BOX_TYPE_UUID) 
                        memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16);
-               map->boxList = gf_list_new();
-               if (!map->boxList) {
+               map->other_boxes = gf_list_new();
+               if (!map->other_boxes) {
                        gf_free(map);
                        return GF_OUT_OF_MEM;
                }
                e = gf_list_add(ptr->recordList, map);
                if (e) return e;
        }
-       return gf_list_add(map->boxList, a);
+       return gf_list_add(map->other_boxes, a);
 }
 
 
@@ -6966,15 +6813,12 @@ GF_Err udta_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *udta_New()
 {
-       GF_UserDataBox *tmp = (GF_UserDataBox *) gf_malloc(sizeof(GF_UserDataBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_UserDataBox));
+       ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA);
        tmp->recordList = gf_list_new();
        if (!tmp->recordList) {
                gf_free(tmp);
                return NULL;
        }
-       tmp->type = GF_ISOM_BOX_TYPE_UDTA;
        return (GF_Box *)tmp;
 }
 
@@ -6994,7 +6838,7 @@ GF_Err udta_Write(GF_Box *s, GF_BitStream *bs)
        while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
                //warning: here we are not passing the actual "parent" of the list
                //but the UDTA box. The parent itself is not an box, we don't care about it
-               e = gf_isom_box_array_write(s, map->boxList, bs);
+               e = gf_isom_box_array_write(s, map->other_boxes, bs);
                if (e) return e;
     }
        return GF_OK;
@@ -7013,7 +6857,7 @@ GF_Err udta_Size(GF_Box *s)
        while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
                //warning: here we are not passing the actual "parent" of the list
                //but the UDTA box. The parent itself is not an box, we don't care about it
-               e = gf_isom_box_array_size(s, map->boxList);
+               e = gf_isom_box_array_size(s, map->other_boxes);
                if (e) return e;
        }
        return GF_OK;
@@ -7042,12 +6886,9 @@ GF_Err vmhd_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *vmhd_New()
 {
-       GF_VideoMediaHeaderBox *tmp = (GF_VideoMediaHeaderBox *) gf_malloc(sizeof(GF_VideoMediaHeaderBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_VideoMediaHeaderBox));
+       ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD);
        gf_isom_full_box_init((GF_Box *)tmp);
        tmp->flags = 1;
-       tmp->type = GF_ISOM_BOX_TYPE_VMHD;
        return (GF_Box *)tmp;
 }
 
@@ -7093,9 +6934,7 @@ GF_Err void_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *void_New()
 {
-       GF_Box *tmp = (GF_Box *) gf_malloc(sizeof(GF_Box));
-       if (!tmp) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_VOID;
+       ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID);
        return tmp;
 }
 
@@ -7120,12 +6959,9 @@ GF_Err void_Size(GF_Box *s)
 
 GF_Box *pdin_New()
 {
-       GF_ProgressiveDownloadBox *tmp = (GF_ProgressiveDownloadBox*) gf_malloc(sizeof(GF_ProgressiveDownloadBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ProgressiveDownloadBox));
+       ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
        gf_isom_full_box_init((GF_Box *)tmp);
        tmp->flags = 1;
-       tmp->type = GF_ISOM_BOX_TYPE_PDIN;
        return (GF_Box *)tmp;
 }
 
@@ -7193,12 +7029,9 @@ GF_Err pdin_Size(GF_Box *s)
 
 GF_Box *sdtp_New()
 {
-       GF_SampleDependencyTypeBox *tmp = (GF_SampleDependencyTypeBox*) gf_malloc(sizeof(GF_SampleDependencyTypeBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SampleDependencyTypeBox));
+       ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP);
        gf_isom_full_box_init((GF_Box *)tmp);
        tmp->flags = 1;
-       tmp->type = GF_ISOM_BOX_TYPE_SDTP;
        return (GF_Box *)tmp;
 }
 
@@ -7255,10 +7088,7 @@ GF_Err sdtp_Size(GF_Box *s)
 
 GF_Box *pasp_New()
 {
-       GF_PixelAspectRatioBox *tmp;
-       GF_SAFEALLOC(tmp, GF_PixelAspectRatioBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_PASP;
+       ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP);
        return (GF_Box *)tmp;
 }
 
@@ -7308,10 +7138,8 @@ GF_Err pasp_Size(GF_Box *s)
 
 GF_Box *metx_New(u32 type)
 {
-       GF_MetaDataSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_MetaDataSampleEntryBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = type;
+       ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, type);
+       gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
        return (GF_Box *)tmp;
 }
 
@@ -7320,6 +7148,8 @@ void metx_del(GF_Box *s)
 {
        GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->content_encoding) gf_free(ptr->content_encoding);
        if (ptr->mime_type_or_namespace) gf_free(ptr->mime_type_or_namespace);
        if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc);
@@ -7333,17 +7163,14 @@ GF_Err metx_AddBox(GF_Box *s, GF_Box *a)
        GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
        switch (a->type) {
        case GF_ISOM_BOX_TYPE_SINF:
-               if (ptr->protection_info) return GF_ISOM_INVALID_FILE;
-               ptr->protection_info = (GF_ProtectionInfoBox*)a;
+               gf_list_add(ptr->protections, a);
                break;
        case GF_ISOM_BOX_TYPE_BTRT:
                if (ptr->bitrate) return GF_ISOM_INVALID_FILE;
                ptr->bitrate = (GF_MPEG4BitRateBox *)a;
                break;
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               break;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -7417,19 +7244,17 @@ GF_Err metx_Write(GF_Box *s, GF_BitStream *bs)
                gf_bs_write_data(bs, ptr->mime_type_or_namespace, strlen(ptr->mime_type_or_namespace));
        gf_bs_write_u8(bs, 0);
        
-       if (ptr->xml_schema_loc) 
-               gf_bs_write_data(bs, ptr->xml_schema_loc, strlen(ptr->xml_schema_loc));
-       gf_bs_write_u8(bs, 0);
+       if (ptr->type == GF_ISOM_BOX_TYPE_METX) { 
+           if (ptr->xml_schema_loc) 
+                   gf_bs_write_data(bs, ptr->xml_schema_loc, strlen(ptr->xml_schema_loc));
+           gf_bs_write_u8(bs, 0);
+    }
 
        if (ptr->bitrate) {
                e = gf_isom_box_write((GF_Box *)ptr->bitrate, bs);
                if (e) return e;
        }
-       if (ptr->protection_info) {
-               e = gf_isom_box_write((GF_Box *)ptr->protection_info, bs);
-               if (e) return e;
-       }
-       return GF_OK;
+       return gf_isom_box_array_size(s, ptr->protections);
 }
 
 GF_Err metx_Size(GF_Box *s)
@@ -7445,33 +7270,29 @@ GF_Err metx_Size(GF_Box *s)
        if (ptr->mime_type_or_namespace)
                ptr->size += strlen(ptr->mime_type_or_namespace);
        ptr->size++;
-       if (ptr->xml_schema_loc)
-               ptr->size += strlen(ptr->xml_schema_loc);
-       ptr->size++;
+       if (ptr->type == GF_ISOM_BOX_TYPE_METX) {
+        if (ptr->xml_schema_loc)
+                   ptr->size += strlen(ptr->xml_schema_loc);
+           ptr->size++;
+    }
 
        if (ptr->bitrate) {
                e = gf_isom_box_size((GF_Box *)ptr->bitrate);
                if (e) return e;
                ptr->size += ptr->bitrate->size;
        }
-       if (ptr->protection_info) {
-               e = gf_isom_box_size((GF_Box *)ptr->protection_info);
-               if (e) return e;
-               ptr->size += ptr->protection_info->size;
-       }
-       return GF_OK;
+       return gf_isom_box_array_size(s, ptr->protections);
 }
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 
 
-GF_Box *dac3_New()
+GF_Box *dac3_New(u32 boxType)
 {
-       GF_AC3ConfigBox *tmp = (GF_AC3ConfigBox *) gf_malloc(sizeof(GF_AC3ConfigBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_AC3ConfigBox));
-       tmp->type = GF_ISOM_BOX_TYPE_DAC3;
+       ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
+       if (boxType==GF_ISOM_BOX_TYPE_DEC3)
+               tmp->cfg.is_ec3 = 1;
        return (GF_Box *)tmp;
 }
 
@@ -7487,13 +7308,34 @@ GF_Err dac3_Read(GF_Box *s, GF_BitStream *bs)
        GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
        if (ptr == NULL) return GF_BAD_PARAM;
 
-       ptr->cfg.fscod = gf_bs_read_int(bs, 2);
-       ptr->cfg.bsid = gf_bs_read_int(bs, 5);
-       ptr->cfg.bsmod = gf_bs_read_int(bs, 3);
-       ptr->cfg.acmod = gf_bs_read_int(bs, 3);
-       ptr->cfg.lfon = gf_bs_read_int(bs, 1);
-       ptr->cfg.brcode = gf_bs_read_int(bs, 5);
-       gf_bs_read_int(bs, 5);
+       if (ptr->cfg.is_ec3) {
+               u32 i;
+               ptr->cfg.brcode = gf_bs_read_int(bs, 13);
+               ptr->cfg.nb_streams = gf_bs_read_int(bs, 3) + 1;
+               for (i=0; i<ptr->cfg.nb_streams; i++) {
+                       ptr->cfg.streams[i].fscod = gf_bs_read_int(bs, 2);
+                       ptr->cfg.streams[i].bsid = gf_bs_read_int(bs, 5);
+                       ptr->cfg.streams[i].bsmod = gf_bs_read_int(bs, 5);
+                       ptr->cfg.streams[i].acmod = gf_bs_read_int(bs, 3);
+                       ptr->cfg.streams[i].lfon = gf_bs_read_int(bs, 1);
+                       gf_bs_read_int(bs, 3);
+                       ptr->cfg.streams[i].nb_dep_sub = gf_bs_read_int(bs, 4);
+                       if (ptr->cfg.streams[i].nb_dep_sub) {
+                               ptr->cfg.streams[i].chan_loc = gf_bs_read_int(bs, 9);
+                       } else {
+                               gf_bs_read_int(bs, 1);
+                       }
+               }
+       } else {
+               ptr->cfg.nb_streams = 1;
+               ptr->cfg.streams[0].fscod = gf_bs_read_int(bs, 2);
+               ptr->cfg.streams[0].bsid = gf_bs_read_int(bs, 5);
+               ptr->cfg.streams[0].bsmod = gf_bs_read_int(bs, 3);
+               ptr->cfg.streams[0].acmod = gf_bs_read_int(bs, 3);
+               ptr->cfg.streams[0].lfon = gf_bs_read_int(bs, 1);
+               ptr->cfg.brcode = gf_bs_read_int(bs, 5);
+               gf_bs_read_int(bs, 5);
+       }
        return GF_OK;
 }
 
@@ -7504,25 +7346,60 @@ GF_Err dac3_Write(GF_Box *s, GF_BitStream *bs)
 {
        GF_Err e;
        GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
-       e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
 
-       gf_bs_write_int(bs, ptr->cfg.fscod, 2);
-       gf_bs_write_int(bs, ptr->cfg.bsid, 5);
-       gf_bs_write_int(bs, ptr->cfg.bsmod, 3);
-       gf_bs_write_int(bs, ptr->cfg.acmod, 3);
-       gf_bs_write_int(bs, ptr->cfg.lfon, 1);
-       gf_bs_write_int(bs, ptr->cfg.brcode, 5);
-       gf_bs_write_int(bs, 0, 5);
+       if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3;
+       e = gf_isom_box_write_header(s, bs);
+       if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3;
+       if (e) return e;
+
+       if (ptr->cfg.is_ec3) {
+               u32 i;
+               gf_bs_write_int(bs, ptr->cfg.brcode, 13);
+               gf_bs_write_int(bs, ptr->cfg.nb_streams - 1, 3);
+               for (i=0; i<ptr->cfg.nb_streams; i++) {
+                       gf_bs_write_int(bs, ptr->cfg.streams[i].fscod, 2);
+                       gf_bs_write_int(bs, ptr->cfg.streams[i].bsid, 5);
+                       gf_bs_write_int(bs, ptr->cfg.streams[i].bsmod, 5);
+                       gf_bs_write_int(bs, ptr->cfg.streams[i].acmod, 3);
+                       gf_bs_write_int(bs, ptr->cfg.streams[i].lfon, 1);
+                       gf_bs_write_int(bs, 0, 3);
+                       gf_bs_write_int(bs, ptr->cfg.streams[i].nb_dep_sub, 4);
+                       if (ptr->cfg.streams[i].nb_dep_sub) {
+                               gf_bs_write_int(bs, ptr->cfg.streams[i].chan_loc, 9);
+                       } else {
+                               gf_bs_write_int(bs, 0, 1);
+                       }
+               }
+       } else {
+               gf_bs_write_int(bs, ptr->cfg.streams[0].fscod, 2);
+               gf_bs_write_int(bs, ptr->cfg.streams[0].bsid, 5);
+               gf_bs_write_int(bs, ptr->cfg.streams[0].bsmod, 3);
+               gf_bs_write_int(bs, ptr->cfg.streams[0].acmod, 3);
+               gf_bs_write_int(bs, ptr->cfg.streams[0].lfon, 1);
+               gf_bs_write_int(bs, ptr->cfg.brcode, 5);
+               gf_bs_write_int(bs, 0, 5);
+       }
        return GF_OK;
 }
 
 GF_Err dac3_Size(GF_Box *s)
 {
+       GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
        GF_Err e;
        e = gf_isom_box_get_size(s);
        if (e) return e;
-       s->size += 3;
+
+       if (ptr->cfg.is_ec3) {
+               u32 i;
+               s->size += 2;
+               for (i=0; i<ptr->cfg.nb_streams; i++) {
+                       s->size += 3;
+                       if (ptr->cfg.streams[i].nb_dep_sub) 
+                               s->size += 1;
+               }
+       } else {
+               s->size += 3;
+       }
        return GF_OK;
 }
 
@@ -7534,8 +7411,9 @@ void ac3_del(GF_Box *s)
 {
        GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
-       if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info);
        gf_free(ptr);
 }
 
@@ -7551,13 +7429,12 @@ GF_Err ac3_Read(GF_Box *s, GF_BitStream *bs)
        return GF_OK;
 }
 
-GF_Box *ac3_New()
+GF_Box *ac3_New(u32 boxType)
 {
-       GF_AC3SampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_AC3SampleEntryBox);
-       if (tmp == NULL) return NULL;
+       ISOM_DECL_BOX_ALLOC(GF_AC3SampleEntryBox, GF_ISOM_BOX_TYPE_AC3);
        gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_AC3;
+       if (boxType==GF_ISOM_BOX_TYPE_EC3)
+               tmp->is_ec3 = 1;
        return (GF_Box *)tmp;
 }
 
@@ -7568,7 +7445,9 @@ GF_Err ac3_Write(GF_Box *s, GF_BitStream *bs)
 {
        GF_Err e;
        GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s;
+       if (ptr->is_ec3) s->type = GF_ISOM_BOX_TYPE_EC3;
        e = gf_isom_box_write_header(s, bs);
+       if (ptr->is_ec3) s->type = GF_ISOM_BOX_TYPE_AC3;
        if (e) return e;
        gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
        return gf_isom_box_write((GF_Box *)ptr->info, bs);
@@ -7610,10 +7489,7 @@ GF_Err lsrc_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *lsrc_New()
 {
-       GF_LASERConfigurationBox *tmp;
-       GF_SAFEALLOC(tmp, GF_LASERConfigurationBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_LSRC;
+       ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC);
        return (GF_Box *)tmp;
 }
 
@@ -7647,6 +7523,8 @@ void lsr1_del(GF_Box *s)
 {
        GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
        if (ptr == NULL) return;
+       gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
+
        if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
        if (ptr->lsr_config) gf_isom_box_del((GF_Box *) ptr->lsr_config);
        if (ptr->bitrate) gf_isom_box_del((GF_Box *) ptr->bitrate);
@@ -7671,9 +7549,7 @@ GF_Err lsr1_AddBox(GF_Box *s, GF_Box *a)
                ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a;
                break;
        default:
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type)));
-               gf_isom_box_del(a);
-               break;
+               return gf_isom_box_add_default(s, a);
        }
        return GF_OK;
 }
@@ -7689,10 +7565,8 @@ GF_Err lsr1_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *lsr1_New()
 {
-       GF_LASeRSampleEntryBox *tmp;
-       GF_SAFEALLOC(tmp, GF_LASeRSampleEntryBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_LSR1;
+       ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1);
+       gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
        return (GF_Box *)tmp;
 }
 
@@ -7797,12 +7671,8 @@ GF_Err sidx_Read(GF_Box *s,GF_BitStream *bs)
 
 GF_Box *sidx_New()
 {
-       GF_SegmentIndexBox *tmp;
-       
-       GF_SAFEALLOC(tmp, GF_SegmentIndexBox);
-       if (tmp == NULL) return NULL;
+       ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_SIDX;
        return (GF_Box *)tmp;
 }
 
@@ -7861,11 +7731,7 @@ GF_Err sidx_Size(GF_Box *s)
 
 GF_Box *pcrb_New()
 {
-       GF_PcrInfoBox *tmp;
-       
-       GF_SAFEALLOC(tmp, GF_PcrInfoBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_PCRB;
+       ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB);
        return (GF_Box *)tmp;
 }
 
@@ -7937,10 +7803,7 @@ GF_Err pcrb_Size(GF_Box *s)
 
 GF_Box *subs_New()
 {
-       GF_SubSampleInformationBox *tmp = (GF_SubSampleInformationBox *) gf_malloc(sizeof(GF_SubSampleInformationBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SubSampleInformationBox));
-       tmp->type = GF_ISOM_BOX_TYPE_SUBS;
+       ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS);
        tmp->Samples = gf_list_new();
        return (GF_Box *)tmp;
 }
@@ -7951,8 +7814,8 @@ void subs_del(GF_Box *s)
        if (ptr == NULL) return;        
 
        while (gf_list_count(ptr->Samples)) {
-               GF_SampleEntry *pSamp;
-               pSamp = (GF_SampleEntry*)gf_list_get(ptr->Samples, 0);
+               GF_SubSampleInfoEntry *pSamp;
+               pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0);
                while (gf_list_count(pSamp->SubSamples)) {
                        GF_SubSampleEntry *pSubSamp;
                        pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, 0);
@@ -7975,7 +7838,7 @@ GF_Err subs_Write(GF_Box *s, GF_BitStream *bs)
        GF_Err e;
        u32 i, j, entry_count;
        u16 subsample_count;
-       GF_SampleEntry *pSamp;
+       GF_SubSampleInfoEntry *pSamp;
        GF_SubSampleEntry *pSubSamp;
        GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
 
@@ -7986,7 +7849,7 @@ GF_Err subs_Write(GF_Box *s, GF_BitStream *bs)
        gf_bs_write_u32(bs, entry_count);
        
        for (i=0; i<entry_count; i++) {
-               pSamp = (GF_SampleEntry*) gf_list_get(ptr->Samples, i);
+               pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
                subsample_count = gf_list_count(pSamp->SubSamples);
                gf_bs_write_u32(bs, pSamp->sample_delta);
                gf_bs_write_u16(bs, subsample_count);
@@ -8010,7 +7873,7 @@ GF_Err subs_Size(GF_Box *s)
 {
        GF_Err e;
        GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
-       GF_SampleEntry *pSamp;
+       GF_SubSampleInfoEntry *pSamp;
        u32 entry_count, i;
        u16 subsample_count;
 
@@ -8022,7 +7885,7 @@ GF_Err subs_Size(GF_Box *s)
        ptr->size += 4;
        entry_count = gf_list_count(ptr->Samples);
        for (i=0; i<entry_count; i++) {
-               pSamp = (GF_SampleEntry*) gf_list_get(ptr->Samples, i);
+               pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
                subsample_count = gf_list_count(pSamp->SubSamples);
                // 4 byte for sample_delta, 2 byte for subsample_count
                // and 6 + (4 or 2) bytes for each subsample
@@ -8047,10 +7910,10 @@ GF_Err subs_Read(GF_Box *s, GF_BitStream *bs)
        ptr->size -= 4;
 
        for (i=0; i<entry_count; i++) {
-               GF_SampleEntry *pSamp = (GF_SampleEntry*) gf_malloc(sizeof(GF_SampleEntry));
+               GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_malloc(sizeof(GF_SubSampleInfoEntry));
                if (!pSamp) return GF_OUT_OF_MEM;
 
-               memset(pSamp, 0, sizeof(GF_SampleEntry));
+               memset(pSamp, 0, sizeof(GF_SubSampleInfoEntry));
                pSamp->SubSamples = gf_list_new();
                pSamp->sample_delta = gf_bs_read_u32(bs);
                subsample_count = gf_bs_read_u16(bs);
@@ -8081,10 +7944,7 @@ GF_Err subs_Read(GF_Box *s, GF_BitStream *bs)
 
 GF_Box *tfdt_New()
 {
-       GF_TFBaseMediaDecodeTimeBox *tmp;
-       GF_SAFEALLOC(tmp, GF_TFBaseMediaDecodeTimeBox);
-       tmp->type = GF_ISOM_BOX_TYPE_TFDT;
-    tmp->version = 0;
+       ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT);
        return (GF_Box *)tmp;
 }
 
@@ -8151,9 +8011,7 @@ GF_Err tfdt_Size(GF_Box *s)
 
 GF_Box *rvcc_New()
 {
-       GF_RVCConfigurationBox *tmp;
-       GF_SAFEALLOC(tmp, GF_RVCConfigurationBox);
-       tmp->type = GF_ISOM_BOX_TYPE_RVCC;
+       ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC);
        return (GF_Box *)tmp;
 }
 
@@ -8208,10 +8066,8 @@ GF_Err rvcc_Size(GF_Box *s)
 
 GF_Box *sbgp_New()
 {
-       GF_SampleGroupBox *p;
-       GF_SAFEALLOC(p, GF_SampleGroupBox);
-       p->type = GF_ISOM_BOX_TYPE_SBGP;
-       return (GF_Box *)p;
+       ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP);
+       return (GF_Box *)tmp;
 }
 void sbgp_del(GF_Box *a)
 {
@@ -8365,14 +8221,11 @@ static u32 sgpd_size_entry(u32 grouping_type, void *entry)
 
 GF_Box *sgpd_New()
 {
-       GF_SampleGroupDescriptionBox *p;
-       GF_SAFEALLOC(p, GF_SampleGroupDescriptionBox);
-       p->type = GF_ISOM_BOX_TYPE_SGPD;
+       ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD);
        /*version 0 is deprecated, use v1 by default*/
-       p->version = 1;
-       p->group_descriptions = gf_list_new();
-
-       return (GF_Box *)p;
+       tmp->version = 1;
+       tmp->group_descriptions = gf_list_new();
+       return (GF_Box *)tmp;
 }
 
 void sgpd_del(GF_Box *a)
@@ -8475,5 +8328,195 @@ GF_Err sgpd_Size(GF_Box *s)
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 
+void saiz_del(GF_Box *s)
+{
+       GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
+       if (ptr == NULL) return;
+       if (ptr->sample_info_size) gf_free(ptr->sample_info_size);
+       gf_free(ptr);
+}
+
+
+GF_Err saiz_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
+
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       if (ptr->flags & 1) {
+               ptr->aux_info_type = gf_bs_read_u32(bs);
+               ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
+               ptr->size -= 8;
+       }
+       ptr->default_sample_info_size = gf_bs_read_u8(bs);
+       ptr->sample_count = gf_bs_read_u32(bs);
+       ptr->size -= 5;
+       if (ptr->default_sample_info_size == 0) {
+               ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count);
+               gf_bs_read_data(bs, ptr->sample_info_size, ptr->sample_count);
+               ptr->size -= ptr->sample_count;
+       }
+       return GF_OK;
+}
+
+GF_Box *saiz_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ);
+       return (GF_Box *)tmp;
+}
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err saiz_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*) s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+
+       if (ptr->flags & 1) {
+               gf_bs_write_u32(bs, ptr->aux_info_type);
+               gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
+       }
+       gf_bs_write_u8(bs, ptr->default_sample_info_size);
+       gf_bs_write_u32(bs, ptr->sample_count);
+       if (ptr->default_sample_info_size) {
+               gf_bs_write_data(bs, ptr->sample_info_size, ptr->sample_count);
+       }
+       return GF_OK;
+}
+
+GF_Err saiz_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
+
+       if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
+               ptr->flags |= 1;
+       }
+
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       if (ptr->flags & 1) ptr->size += 8;
+       ptr->size += 5;
+       if (ptr->default_sample_info_size==0)  ptr->size += ptr->sample_count;
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
+void saio_del(GF_Box *s)
+{
+       GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
+       if (ptr == NULL) return;
+       if (ptr->offsets) gf_free(ptr->offsets);
+       if (ptr->offsets_large) gf_free(ptr->offsets_large);
+       gf_free(ptr);
+}
+
+
+GF_Err saio_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;
+
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       if (ptr->flags & 1) {
+               ptr->aux_info_type = gf_bs_read_u32(bs);
+               ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
+               ptr->size -= 8;
+       }
+       ptr->entry_count = gf_bs_read_u32(bs);
+       ptr->size -= 4;
+       if (ptr->entry_count>1) {
+               u32 i;
+               if (ptr->version==0) {
+                       ptr->offsets = gf_malloc(sizeof(u32)*ptr->entry_count);
+                       for (i=0; i<ptr->entry_count; i++)
+                               ptr->offsets[i] = gf_bs_read_u32(bs);
+                       ptr->size -= 4*ptr->entry_count;
+               } else {
+                       ptr->offsets_large = gf_malloc(sizeof(u64)*ptr->entry_count);
+                       for (i=0; i<ptr->entry_count; i++)
+                               ptr->offsets_large[i] = gf_bs_read_u64(bs);
+                       ptr->size -= 8*ptr->entry_count;
+               }
+       } else {
+               if (ptr->version==0) {
+                       ptr->single_offset = gf_bs_read_u32(bs);
+                       ptr->size -= 4;
+               } else {
+                       ptr->single_offset = gf_bs_read_u64(bs);
+                       ptr->size -= 8;
+               }
+       }
+       return GF_OK;
+}
+
+GF_Box *saio_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
+       return (GF_Box *)tmp;
+}
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err saio_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *) s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+
+       if (ptr->flags & 1) {
+               gf_bs_write_u32(bs, ptr->aux_info_type);
+               gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
+       }
+       gf_bs_write_u32(bs, ptr->entry_count);
+       if (ptr->entry_count>1) {
+               u32 i;
+               if (ptr->version==0) {
+                       assert(ptr->offsets);
+                       for (i=0; i<ptr->entry_count; i++)
+                               gf_bs_write_u32(bs, ptr->offsets[i]);
+               } else {
+                       assert(ptr->offsets_large);
+                       for (i=0; i<ptr->entry_count; i++)
+                               gf_bs_write_u64(bs, ptr->offsets_large[i]);
+               }
+       } else {
+               if (ptr->version==0) {
+                       gf_bs_write_u32(bs, (u32) ptr->single_offset);
+               } else {
+                       gf_bs_write_u64(bs, ptr->single_offset);
+               }
+       }
+       return GF_OK;
+}
+
+GF_Err saio_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
+
+       if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
+               ptr->flags |= 1;
+       }
+       if (ptr->offsets_large || (ptr->single_offset >0xFFFFFFFF)) {
+               ptr->version = 1;
+       }
+
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       if (ptr->flags & 1) ptr->size += 8;
+       ptr->size += 4;
+       ptr->size += ((ptr->version==1) ? 8 : 4) * ptr->entry_count;
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
 
 #endif /*GPAC_DISABLE_ISOM*/
diff --git a/src/isomedia/box_code_drm.c b/src/isomedia/box_code_drm.c
new file mode 100644 (file)
index 0000000..200ad10
--- /dev/null
@@ -0,0 +1,1222 @@
+/*
+ *                     GPAC - Multimedia Framework C SDK
+ *
+ *                     Authors: Cyril Concolato, Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
+ *                                     All rights reserved
+ *
+ *  This file is part of GPAC / ISO Media File Format 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. 
+ *
+ */
+
+#include <gpac/internal/isomedia_dev.h>
+
+#ifndef GPAC_DISABLE_ISOM
+
+/* ProtectionInfo Box */
+GF_Box *sinf_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_ProtectionInfoBox, GF_ISOM_BOX_TYPE_SINF);
+       return (GF_Box *)tmp;
+}
+
+void sinf_del(GF_Box *s)
+{
+       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
+       if (ptr == NULL) return;
+       if (ptr->original_format) gf_isom_box_del((GF_Box *)ptr->original_format);
+       if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
+       if (ptr->scheme_type) gf_isom_box_del((GF_Box *)ptr->scheme_type);
+       gf_free(ptr);
+}
+
+GF_Err sinf_AddBox(GF_Box *s, GF_Box *a)
+{
+       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
+       switch (a->type) {
+       case GF_ISOM_BOX_TYPE_FRMA: 
+               if (ptr->original_format) return GF_ISOM_INVALID_FILE;
+               ptr->original_format = (GF_OriginalFormatBox*)a; 
+               break;
+       case GF_ISOM_BOX_TYPE_SCHM: 
+               if (ptr->scheme_type) return GF_ISOM_INVALID_FILE;
+               ptr->scheme_type = (GF_SchemeTypeBox*)a; 
+               break;
+       case GF_ISOM_BOX_TYPE_SCHI: 
+               if (ptr->info) return GF_ISOM_INVALID_FILE;
+               ptr->info = (GF_SchemeInformationBox*)a; 
+               break;
+       default: 
+               return gf_isom_box_add_default(s, a);
+       }
+       return GF_OK;
+}
+
+GF_Err sinf_Read(GF_Box *s, GF_BitStream *bs)
+{
+       return gf_isom_read_box_list(s, bs, sinf_AddBox);
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err sinf_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+       //frma
+       e = gf_isom_box_write((GF_Box *) ptr->original_format, bs);
+       if (e) return e;
+       // schm
+       e = gf_isom_box_write((GF_Box *) ptr->scheme_type, bs);
+       if (e) return e;
+       // schi
+       e = gf_isom_box_write((GF_Box *) ptr->info, bs);
+       if (e) return e;
+       return GF_OK;
+}
+
+GF_Err sinf_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+       e = gf_isom_box_size((GF_Box *) ptr->original_format);
+       if (e) return e;
+       ptr->size += ptr->original_format->size;
+       e = gf_isom_box_size((GF_Box *) ptr->scheme_type);
+       if (e) return e;
+       ptr->size += ptr->scheme_type->size;
+       e = gf_isom_box_size((GF_Box *) ptr->info);
+       if (e) return e;
+       ptr->size += ptr->info->size;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+/* OriginalFormat Box */
+GF_Box *frma_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OriginalFormatBox, GF_ISOM_BOX_TYPE_FRMA);
+       return (GF_Box *)tmp;
+}
+
+void frma_del(GF_Box *s)
+{
+       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
+       if (ptr == NULL) return;
+       gf_free(ptr);
+}
+
+GF_Err frma_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
+       ptr->data_format = gf_bs_read_u32(bs);
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err frma_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+       gf_bs_write_u32(bs, ptr->data_format);
+       return GF_OK;
+}
+
+GF_Err frma_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+       ptr->size += 4;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+/* SchemeType Box */
+GF_Box *schm_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_SchemeTypeBox, GF_ISOM_BOX_TYPE_SCHM);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void schm_del(GF_Box *s)
+{
+       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
+       if (ptr == NULL) return;
+       if (ptr->URI) gf_free(ptr->URI);
+       gf_free(ptr);
+}
+
+GF_Err schm_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       ptr->scheme_type = gf_bs_read_u32(bs);
+       ptr->scheme_version = gf_bs_read_u32(bs);
+       ptr->size -= 8;
+       if (ptr->size && (ptr->flags & 0x000001)) {
+               u32 len = (u32) (ptr->size);
+               ptr->URI = (char*)gf_malloc(sizeof(char)*len);
+               if (!ptr->URI) return GF_OUT_OF_MEM;
+               gf_bs_read_data(bs, ptr->URI, len);
+       }
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err schm_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       assert(e == GF_OK);
+       gf_bs_write_u32(bs, ptr->scheme_type);
+       gf_bs_write_u32(bs, ptr->scheme_version);
+       if (ptr->flags & 0x000001) gf_bs_write_data(bs, ptr->URI, strlen(ptr->URI)+1);
+       return GF_OK;
+}
+
+GF_Err schm_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += 8;
+       if (ptr->flags & 0x000001) ptr->size += strlen(ptr->URI)+1;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+/* SchemeInformation Box */
+GF_Box *schi_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_SchemeInformationBox, GF_ISOM_BOX_TYPE_SCHI);
+       return (GF_Box *)tmp;
+}
+
+void schi_del(GF_Box *s)
+{
+       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
+       if (ptr == NULL) return;
+       if (ptr->ikms) gf_isom_box_del((GF_Box *)ptr->ikms);
+       if (ptr->isfm) gf_isom_box_del((GF_Box *)ptr->isfm);
+       if (ptr->okms) gf_isom_box_del((GF_Box *)ptr->okms);
+       if (ptr->tenc) gf_isom_box_del((GF_Box *)ptr->tenc);
+       if (ptr->piff_tenc) gf_isom_box_del((GF_Box *)ptr->piff_tenc);
+       gf_free(ptr);
+}
+
+GF_Err schi_AddBox(GF_Box *s, GF_Box *a)
+{
+       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
+       switch (a->type) {
+       case GF_ISOM_BOX_TYPE_IKMS:
+               if (ptr->ikms) return GF_ISOM_INVALID_FILE;
+               ptr->ikms = (GF_ISMAKMSBox*)a;
+               return GF_OK;
+       case GF_ISOM_BOX_TYPE_ISFM:
+               if (ptr->isfm) return GF_ISOM_INVALID_FILE;
+               ptr->isfm = (GF_ISMASampleFormatBox*)a;
+               return GF_OK;
+       case GF_ISOM_BOX_TYPE_ODKM:
+               if (ptr->okms) return GF_ISOM_INVALID_FILE;
+               ptr->okms = (GF_OMADRMKMSBox*)a;
+               return GF_OK;
+       case GF_ISOM_BOX_TYPE_TENC:
+               if (ptr->tenc) return GF_ISOM_INVALID_FILE;
+               ptr->tenc = (GF_TrackEncryptionBox *)a;
+               return GF_OK;
+       case GF_ISOM_BOX_TYPE_UUID:
+               if (((GF_UUIDBox*)a)->internal_4cc==GF_ISOM_BOX_UUID_TENC) {
+                       if (ptr->piff_tenc) return GF_ISOM_INVALID_FILE;
+                       ptr->piff_tenc = (GF_PIFFTrackEncryptionBox *)a;
+                       return GF_OK;
+               } else {
+                       return gf_isom_box_add_default(s, a);
+               }
+       default:
+               return gf_isom_box_add_default(s, a);
+       }
+}
+
+GF_Err schi_Read(GF_Box *s, GF_BitStream *bs)
+{
+       return gf_isom_read_box_list(s, bs, schi_AddBox);
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err schi_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+
+       if (ptr->ikms) {
+               e = gf_isom_box_write((GF_Box *) ptr->ikms, bs);
+               if (e) return e;
+       }
+       if (ptr->isfm) {
+               e = gf_isom_box_write((GF_Box *) ptr->isfm, bs);
+               if (e) return e;
+       }
+       if (ptr->okms) {
+               e = gf_isom_box_write((GF_Box *) ptr->okms, bs);
+               if (e) return e;
+       }
+       if (ptr->tenc) {
+               e = gf_isom_box_write((GF_Box *) ptr->tenc, bs);
+               if (e) return e;
+       }
+       if (ptr->piff_tenc) {
+               e = gf_isom_box_write((GF_Box *) ptr->piff_tenc, bs);
+               if (e) return e;
+       }
+       return GF_OK;
+}
+
+GF_Err schi_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+
+       if (ptr->ikms) {
+               e = gf_isom_box_size((GF_Box *) ptr->ikms);
+               if (e) return e;
+               ptr->size += ptr->ikms->size;
+       }
+       if (ptr->isfm) {
+               e = gf_isom_box_size((GF_Box *) ptr->isfm);
+               if (e) return e;
+               ptr->size += ptr->isfm->size;
+       }
+       if (ptr->okms) {
+               e = gf_isom_box_size((GF_Box *) ptr->okms);
+               if (e) return e;
+               ptr->size += ptr->okms->size;
+       }
+       if (ptr->tenc) {
+               e = gf_isom_box_size((GF_Box *) ptr->tenc);
+               if (e) return e;
+               ptr->size += ptr->tenc->size;
+       }
+       if (ptr->piff_tenc) {
+               e = gf_isom_box_size((GF_Box *) ptr->tenc);
+               if (e) return e;
+               ptr->size += ptr->tenc->size;
+       }
+       return GF_OK;
+}
+
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+/* ISMAKMS Box */
+GF_Box *iKMS_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_ISMAKMSBox, GF_ISOM_BOX_TYPE_IKMS);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void iKMS_del(GF_Box *s)
+{
+       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
+       if (ptr == NULL) return;
+       if (ptr->URI) gf_free(ptr->URI);
+       gf_free(ptr);
+}
+
+GF_Err iKMS_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       u32 len;
+       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
+
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       len = (u32) (ptr->size);
+       ptr->URI = (char*) gf_malloc(sizeof(char)*len);
+       if (!ptr->URI) return GF_OUT_OF_MEM;
+       gf_bs_read_data(bs, ptr->URI, len);
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err iKMS_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gf_bs_write_data(bs, ptr->URI, strlen(ptr->URI)+1);
+       return GF_OK;
+}
+
+GF_Err iKMS_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += strlen(ptr->URI)+1;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+/* ISMASampleFormat Box */
+GF_Box *iSFM_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_ISMASampleFormatBox, GF_ISOM_BOX_TYPE_ISFM);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void iSFM_del(GF_Box *s)
+{
+       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
+       if (ptr == NULL) return;
+       gf_free(ptr);
+}
+
+
+GF_Err iSFM_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
+       if (ptr == NULL) return GF_BAD_PARAM;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       ptr->selective_encryption = gf_bs_read_int(bs, 1);
+       gf_bs_read_int(bs, 7);
+       ptr->key_indicator_length = gf_bs_read_u8(bs);
+       ptr->IV_length = gf_bs_read_u8(bs);
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err iSFM_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gf_bs_write_int(bs, ptr->selective_encryption, 1);
+       gf_bs_write_int(bs, 0, 7);
+       gf_bs_write_u8(bs, ptr->key_indicator_length);
+       gf_bs_write_u8(bs, ptr->IV_length);
+       return GF_OK;
+}
+
+GF_Err iSFM_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += 3;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+
+/* OMADRMCommonHeader Box */
+GF_Box *ohdr_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OMADRMCommonHeaderBox, GF_ISOM_BOX_TYPE_OHDR);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       tmp->other_boxes = gf_list_new();
+       return (GF_Box *)tmp;
+}
+
+void ohdr_del(GF_Box *s)
+{
+       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
+       if (ptr == NULL) return;
+       if (ptr->ContentID) gf_free(ptr->ContentID);
+       if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL);
+       if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders);
+       gf_free(ptr);
+}
+
+GF_Err ohdr_AddBox(GF_Box *s, GF_Box *a)
+{
+       return gf_isom_box_add_default(s, a);
+}
+
+GF_Err ohdr_Read(GF_Box *s, GF_BitStream *bs)
+{
+       u16 cid_len, ri_len;
+       GF_Err e;
+       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
+       if (ptr == NULL) return GF_BAD_PARAM;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       ptr->EncryptionMethod = gf_bs_read_u8(bs);
+       ptr->PaddingScheme = gf_bs_read_u8(bs);
+       ptr->PlaintextLength = gf_bs_read_u64(bs);
+       cid_len = gf_bs_read_u16(bs);
+       ri_len = gf_bs_read_u16(bs);
+       ptr->TextualHeadersLen = gf_bs_read_u16(bs);
+       ptr->size -= 1+1+8+2+2+2;
+       if (ptr->size<cid_len+ri_len+ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE;
+
+       if (cid_len) {
+               ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len+1));
+               gf_bs_read_data(bs, ptr->ContentID, cid_len);
+               ptr->ContentID[cid_len]=0;
+       }
+
+       if (ri_len) {
+               ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len+1));
+               gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len);
+               ptr->RightsIssuerURL[ri_len]=0;
+       }
+       
+       if (ptr->TextualHeadersLen) {
+               ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1));
+               gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
+               ptr->TextualHeaders[ptr->TextualHeadersLen] = 0;
+       }
+
+       ptr->size -= cid_len+ri_len+ptr->TextualHeadersLen;
+
+       return gf_isom_read_box_list(s, bs, ohdr_AddBox);
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err ohdr_Write(GF_Box *s, GF_BitStream *bs)
+{
+       u16 cid_len, ri_len;
+       GF_Err e;
+       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gf_bs_write_u8(bs, ptr->EncryptionMethod);
+       gf_bs_write_u8(bs, ptr->PaddingScheme);
+       gf_bs_write_u64(bs, ptr->PlaintextLength);
+       
+       cid_len = ptr->ContentID ? strlen(ptr->ContentID) : 0;
+       gf_bs_write_u16(bs, cid_len);
+       ri_len = ptr->RightsIssuerURL ? strlen(ptr->RightsIssuerURL) : 0;
+       gf_bs_write_u16(bs, ri_len);
+       gf_bs_write_u16(bs, ptr->TextualHeadersLen);
+
+       if (cid_len) gf_bs_write_data(bs, ptr->ContentID, strlen(ptr->ContentID));
+       if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, strlen(ptr->RightsIssuerURL));
+       if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
+       ptr->size -= cid_len+ri_len+ptr->TextualHeadersLen;
+       return GF_OK;
+}
+
+GF_Err ohdr_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += 1+1+8+2+2+2;
+       if (ptr->ContentID) ptr->size += strlen(ptr->ContentID);
+       if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL);
+       if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+/* OMADRMGroupID Box */
+GF_Box *grpi_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OMADRMGroupIDBox, GF_ISOM_BOX_TYPE_GRPI);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void grpi_del(GF_Box *s)
+{
+       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
+       if (ptr == NULL) return;
+       if (ptr->GroupID) gf_free(ptr->GroupID);
+       if (ptr->GroupKey) gf_free(ptr->GroupKey);
+       gf_free(ptr);
+}
+
+GF_Err grpi_Read(GF_Box *s, GF_BitStream *bs)
+{
+       u16 gid_len;
+       GF_Err e;
+       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s;
+       if (ptr == NULL) return GF_BAD_PARAM;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       gid_len = gf_bs_read_u16(bs);
+       ptr->GKEncryptionMethod = gf_bs_read_u8(bs);
+       ptr->GKLength = gf_bs_read_u16(bs);
+
+       ptr->size -= 1+2+2;
+       if (ptr->size<gid_len+ptr->GKLength) return GF_ISOM_INVALID_FILE;
+
+       ptr->GroupID = gf_malloc(sizeof(char)*(gid_len+1));
+       gf_bs_read_data(bs, ptr->GroupID, gid_len);
+       ptr->GroupID[gid_len]=0;
+       
+       ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength);
+       gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength);
+       ptr->size -= gid_len+ptr->GKLength;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err grpi_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       u16 gid_len;
+       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gid_len = ptr->GroupID ? strlen(ptr->GroupID) : 0;
+       gf_bs_write_u16(bs, gid_len);
+       gf_bs_write_u8(bs, ptr->GKEncryptionMethod);
+       gf_bs_write_u16(bs, ptr->GKLength);
+       gf_bs_write_data(bs, ptr->GroupID, gid_len);
+       gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength);
+       return GF_OK;
+}
+
+GF_Err grpi_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += 2+2+1 + ptr->GKLength;
+       if (ptr->GroupID) ptr->size += strlen(ptr->GroupID);
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+
+
+/* OMADRMMutableInformation Box */
+GF_Box *mdri_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OMADRMMutableInformationBox, GF_ISOM_BOX_TYPE_MDRI);
+       return (GF_Box *)tmp;
+}
+
+void mdri_del(GF_Box *s)
+{
+       GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
+       if (ptr == NULL) return;
+       gf_free(ptr);
+}
+
+GF_Err mdri_Read(GF_Box *s, GF_BitStream *bs)
+{
+       return gf_isom_read_box_list(s, bs, gf_isom_box_add_default);
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err mdri_Write(GF_Box *s, GF_BitStream *bs)
+{
+//     GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
+       GF_Err e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+       return GF_OK;
+}
+
+GF_Err mdri_Size(GF_Box *s)
+{
+       GF_Err e;
+//     GF_OMADRMMutableInformationBox *ptr = (GF_OMADRMMutableInformationBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+/* OMADRMTransactionTracking Box */
+GF_Box *odtt_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OMADRMTransactionTrackingBox, GF_ISOM_BOX_TYPE_ODTT);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void odtt_del(GF_Box *s)
+{
+       GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
+       gf_free(ptr);
+}
+
+GF_Err odtt_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s;
+       if (ptr == NULL) return GF_BAD_PARAM;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       gf_bs_read_data(bs, ptr->TransactionID, 16);
+       ptr->size -= 16;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err odtt_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gf_bs_write_data(bs, ptr->TransactionID, 16);
+       return GF_OK;
+}
+
+GF_Err odtt_Size(GF_Box *s)
+{
+       GF_Err e;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       s->size += 16;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+
+/* OMADRMRightsObject Box */
+GF_Box *odrb_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OMADRMRightsObjectBox, GF_ISOM_BOX_TYPE_ODRB);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void odrb_del(GF_Box *s)
+{
+       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s;
+       if (ptr->oma_ro) gf_free(ptr->oma_ro);
+       gf_free(ptr);
+}
+
+GF_Err odrb_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
+       if (ptr == NULL) return GF_BAD_PARAM;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       ptr->oma_ro_size = (u32) ptr->size;
+       ptr->oma_ro = (char*) gf_malloc(sizeof(char)*ptr->oma_ro_size);
+       gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size);
+       ptr->size = 0;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err odrb_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size);
+       return GF_OK;
+}
+
+GF_Err odrb_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       s->size += ptr->oma_ro_size;
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+
+
+/* OMADRMKMS Box */
+GF_Box *odkm_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_OMADRMKMSBox, GF_ISOM_BOX_TYPE_ODKM);
+       gf_isom_full_box_init((GF_Box *)tmp);
+       return (GF_Box *)tmp;
+}
+
+void odkm_del(GF_Box *s)
+{
+       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
+       if (ptr->hdr) gf_isom_box_del((GF_Box*)ptr->hdr);
+       if (ptr->fmt) gf_isom_box_del((GF_Box*)ptr->fmt);
+       gf_free(ptr);
+}
+
+GF_Err odkm_Add(GF_Box *s, GF_Box *a)
+{
+       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
+       switch (a->type) {
+       case GF_ISOM_BOX_TYPE_OHDR:
+               if (ptr->hdr) gf_isom_box_del((GF_Box*)ptr->hdr);
+               ptr->hdr = (GF_OMADRMCommonHeaderBox *)a;
+               return GF_OK;
+       case GF_ISOM_BOX_TYPE_ODAF:
+               if (ptr->fmt) gf_isom_box_del((GF_Box*)ptr->fmt);
+               ptr->fmt = (GF_OMADRMAUFormatBox*)a;
+               return GF_OK;
+       default:
+               gf_isom_box_del(a);
+               return GF_OK;
+       }
+}
+
+GF_Err odkm_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       if (s == NULL) return GF_BAD_PARAM;
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+       return gf_isom_read_box_list(s, bs, odkm_Add);
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err odkm_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+       if (ptr->hdr) {
+               e = gf_isom_box_write((GF_Box*)ptr->hdr, bs);
+               if (e) return e;
+       }
+       if (ptr->fmt) {
+               e = gf_isom_box_write((GF_Box*)ptr->fmt, bs);
+               if (e) return e;
+       }
+       return GF_OK;
+}
+
+GF_Err odkm_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       if (ptr->hdr) {
+               e = gf_isom_box_size((GF_Box*)ptr->hdr);
+               if (e) return e;
+               ptr->size += ptr->hdr->size;
+       }
+       if (ptr->fmt) {
+               e = gf_isom_box_size((GF_Box*)ptr->fmt);
+               if (e) return e;
+               ptr->size += ptr->fmt->size;
+       }
+       return GF_OK;
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+
+
+GF_Box *pssh_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_ProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_PSSH);
+       return (GF_Box *)tmp;
+}
+
+void pssh_del(GF_Box *s)
+{
+       GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
+       if (ptr == NULL) return;
+       if (ptr->private_data) gf_free(ptr->private_data);
+       if (ptr->KIDs) gf_free(ptr->KIDs);
+       gf_free(ptr);
+}
+
+GF_Err pssh_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s;
+
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+
+       gf_bs_read_data(bs, ptr->SystemID, 16);
+       ptr->size -= 16;
+       if (ptr->version > 0) {
+               ptr->KID_count = gf_bs_read_u32(bs);
+               ptr->size -= 4;
+               if (ptr->KID_count) {
+                       u32 i;
+                       ptr->KIDs = gf_malloc(sizeof(bin128));
+                       for (i=0; i<ptr->KID_count; i++) {
+                               gf_bs_read_data(bs, ptr->KIDs[i], 16);
+                               ptr->size -= 16;
+                       }
+               }
+       }
+       ptr->private_data_size = gf_bs_read_u32(bs);
+       ptr->size -= 4;
+       if (ptr->private_data_size) {
+               ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
+               gf_bs_read_data(bs, ptr->private_data, ptr->private_data_size);
+               ptr->size -= ptr->private_data_size;
+       }
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err pssh_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *) s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+
+       gf_bs_write_data(bs, ptr->SystemID, 16);
+       if (ptr->version > 0) {
+               u32 i;
+               gf_bs_write_u32(bs, ptr->KID_count);
+               for (i=0; i<ptr->KID_count; i++) 
+                       gf_bs_write_data(bs, ptr->KIDs[i], 16);
+       }
+       if (ptr->private_data) {
+               gf_bs_write_u32(bs, ptr->private_data_size);
+               gf_bs_write_data(bs, ptr->private_data, ptr->private_data_size);
+       } else 
+               gf_bs_write_u32(bs, 0);
+       return GF_OK;
+}
+
+GF_Err pssh_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
+
+       if (ptr->KID_count && !ptr->version) {
+               ptr->version = 1;
+       }
+
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+
+       ptr->size += 16;
+       if (ptr->version) ptr->size += 4 + 16*ptr->KID_count;
+       ptr->size += 4 + ptr->private_data ? ptr->private_data_size : 0;
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
+
+GF_Box *tenc_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_TrackEncryptionBox, GF_ISOM_BOX_TYPE_TENC);
+       return (GF_Box *)tmp;
+}
+
+void tenc_del(GF_Box *s)
+{
+       gf_free(s);
+}
+
+GF_Err tenc_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
+
+       e = gf_isom_full_box_read(s, bs);
+       if (e) return e;
+
+       ptr->IsEncrypted = gf_bs_read_int(bs, 24);
+       ptr->IV_size = gf_bs_read_u8(bs);
+       gf_bs_read_data(bs, ptr->KID, 16);
+       ptr->size -= 20;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err tenc_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox *) s;
+       if (!s) return GF_BAD_PARAM;
+       e = gf_isom_full_box_write(s, bs);
+       if (e) return e;
+
+       gf_bs_write_int(bs, ptr->IsEncrypted, 24);
+       gf_bs_write_u8(bs, ptr->IV_size);
+       gf_bs_write_data(bs, ptr->KID, 16);
+       return GF_OK;
+}
+
+GF_Err tenc_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
+       e = gf_isom_full_box_get_size(s);
+       if (e) return e;
+       ptr->size += 20;
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
+GF_Box *piff_tenc_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_PIFFTrackEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
+       tmp->internal_4cc = GF_ISOM_BOX_UUID_TENC;
+       return (GF_Box *)tmp;
+}
+
+void piff_tenc_del(GF_Box *s)
+{
+       gf_free(s);
+}
+
+GF_Err piff_tenc_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
+
+       if (ptr->size<4) return GF_ISOM_INVALID_FILE;
+       ptr->version = gf_bs_read_u8(bs);
+       ptr->flags = gf_bs_read_u24(bs);
+       ptr->size -= 4;
+
+       ptr->AlgorithmID = gf_bs_read_int(bs, 24);
+       ptr->IV_size = gf_bs_read_u8(bs);
+       gf_bs_read_data(bs, ptr->KID, 16);
+       ptr->size -= 20;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err piff_tenc_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *) s;
+       if (!s) return GF_BAD_PARAM;
+
+       e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+       gf_bs_write_u8(bs, ptr->version);
+       gf_bs_write_u24(bs, ptr->flags);
+
+       gf_bs_write_int(bs, ptr->AlgorithmID, 24);
+       gf_bs_write_u8(bs, ptr->IV_size);
+       gf_bs_write_data(bs, ptr->KID, 16);
+       return GF_OK;
+}
+
+GF_Err piff_tenc_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+       ptr->size += 24;
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
+
+GF_Box *piff_psec_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_PIFFSampleEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
+       tmp->internal_4cc = GF_ISOM_BOX_UUID_PSEC;
+       return (GF_Box *)tmp;
+}
+
+void piff_psec_del(GF_Box *s)
+{
+       GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
+       if (ptr->cenc_data) gf_free(ptr->cenc_data);
+       gf_free(s);
+}
+
+GF_Err piff_psec_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
+       if (ptr->size<4) return GF_ISOM_INVALID_FILE;
+       ptr->version = gf_bs_read_u8(bs);
+       ptr->flags = gf_bs_read_u24(bs);
+       ptr->size -= 4;
+
+       if (ptr->flags & 1) {
+               ptr->AlgorithmID = gf_bs_read_int(bs, 24);
+               ptr->IV_size = gf_bs_read_u8(bs);
+               gf_bs_read_data(bs, ptr->KID, 16);
+               ptr->size -= 20;
+       }
+       ptr->sample_count = gf_bs_read_u32(bs);
+       ptr->size -= 4;
+       ptr->cenc_data_size = (u32) ptr->size;
+       ptr->cenc_data = gf_malloc(sizeof(char)*ptr->cenc_data_size);
+       gf_bs_read_data(bs, ptr->cenc_data, ptr->cenc_data_size);
+       ptr->size = 0;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *) s;
+       if (!s) return GF_BAD_PARAM;
+
+       e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+       gf_bs_write_u8(bs, ptr->version);
+       gf_bs_write_u24(bs, ptr->flags);
+
+       if (ptr->flags & 1) {
+               gf_bs_write_int(bs, ptr->AlgorithmID, 24);
+               gf_bs_write_u8(bs, ptr->IV_size);
+               gf_bs_write_data(bs, ptr->KID, 16);
+       }
+       gf_bs_write_u32(bs, ptr->sample_count);
+       if (ptr->cenc_data && ptr->cenc_data_size) {
+               gf_bs_write_data(bs, ptr->cenc_data, ptr->cenc_data_size);
+       }
+       return GF_OK;
+}
+
+GF_Err piff_psec_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox*)s;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+       ptr->size += 4;
+       if (ptr->flags & 1) {
+               ptr->size += 20;
+       }
+       ptr->size += 4;
+       if (ptr->cenc_data && ptr->cenc_data_size) {
+               ptr->size += ptr->cenc_data_size;
+       }
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
+
+GF_Box *piff_pssh_New()
+{
+       ISOM_DECL_BOX_ALLOC(GF_PIFFProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_UUID);
+       tmp->internal_4cc = GF_ISOM_BOX_UUID_PSSH;
+       return (GF_Box *)tmp;
+}
+
+void piff_pssh_del(GF_Box *s)
+{
+       gf_free(s);
+}
+
+GF_Err piff_pssh_Read(GF_Box *s, GF_BitStream *bs)
+{
+       GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
+
+       if (ptr->size<4) return GF_ISOM_INVALID_FILE;
+       ptr->version = gf_bs_read_u8(bs);
+       ptr->flags = gf_bs_read_u24(bs);
+       ptr->size -= 4;
+
+       gf_bs_read_data(bs, ptr->SystemID, 16);
+       ptr->private_data_size = gf_bs_read_u32(bs);
+       ptr->size -= 20;
+       ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
+       gf_bs_read_data(bs, ptr->private_data, ptr->private_data_size);
+       ptr->size -= ptr->private_data_size;
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err piff_pssh_Write(GF_Box *s, GF_BitStream *bs)
+{
+       GF_Err e;
+       GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s;
+       if (!s) return GF_BAD_PARAM;
+
+       e = gf_isom_box_write_header(s, bs);
+       if (e) return e;
+       gf_bs_write_u8(bs, ptr->version);
+       gf_bs_write_u24(bs, ptr->flags);
+
+       gf_bs_write_data(bs, ptr->SystemID, 16);
+       gf_bs_write_u32(bs, ptr->private_data_size);
+       gf_bs_write_data(bs, ptr->private_data, ptr->private_data_size);
+       return GF_OK;
+}
+
+GF_Err piff_pssh_Size(GF_Box *s)
+{
+       GF_Err e;
+       GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
+       e = gf_isom_box_get_size(s);
+       if (e) return e;
+       ptr->size += 24 + ptr->private_data_size;
+       return GF_OK;
+}
+#endif //GPAC_DISABLE_ISOM_WRITE
+
+#endif /*GPAC_DISABLE_ISOM*/
diff --git a/src/isomedia/box_code_isma.c b/src/isomedia/box_code_isma.c
deleted file mode 100644 (file)
index b059065..0000000
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- *                     GPAC - Multimedia Framework C SDK
- *
- *                     Copyright (c) Cyril Concolato 2005
- *                                     All rights reserved
- *
- *  This file is part of GPAC / ISO Media File Format 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. 
- *
- */
-
-#include <gpac/internal/isomedia_dev.h>
-
-#ifndef GPAC_DISABLE_ISOM
-
-/* ProtectionInfo Box */
-GF_Box *sinf_New()
-{
-       GF_ProtectionInfoBox *tmp = (GF_ProtectionInfoBox *) gf_malloc(sizeof(GF_ProtectionInfoBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ProtectionInfoBox));
-       tmp->type = GF_ISOM_BOX_TYPE_SINF;
-       return (GF_Box *)tmp;
-}
-
-void sinf_del(GF_Box *s)
-{
-       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
-       if (ptr == NULL) return;
-       if (ptr->original_format) gf_isom_box_del((GF_Box *)ptr->original_format);
-       if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
-       if (ptr->scheme_type) gf_isom_box_del((GF_Box *)ptr->scheme_type);
-       gf_free(ptr);
-}
-
-GF_Err sinf_AddBox(GF_Box *s, GF_Box *a)
-{
-       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
-       switch (a->type) {
-       case GF_ISOM_BOX_TYPE_FRMA: 
-               if (ptr->original_format) return GF_ISOM_INVALID_FILE;
-               ptr->original_format = (GF_OriginalFormatBox*)a; 
-               break;
-       case GF_ISOM_BOX_TYPE_SCHM: 
-               if (ptr->scheme_type) return GF_ISOM_INVALID_FILE;
-               ptr->scheme_type = (GF_SchemeTypeBox*)a; 
-               break;
-       case GF_ISOM_BOX_TYPE_SCHI: 
-               if (ptr->info) return GF_ISOM_INVALID_FILE;
-               ptr->info = (GF_SchemeInformationBox*)a; 
-               break;
-       default: 
-               gf_isom_box_del(a); 
-               break;
-       }
-       return GF_OK;
-}
-
-GF_Err sinf_Read(GF_Box *s, GF_BitStream *bs)
-{
-       return gf_isom_read_box_list(s, bs, sinf_AddBox);
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err sinf_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
-       //frma
-       e = gf_isom_box_write((GF_Box *) ptr->original_format, bs);
-       if (e) return e;
-       // schm
-       e = gf_isom_box_write((GF_Box *) ptr->scheme_type, bs);
-       if (e) return e;
-       // schi
-       e = gf_isom_box_write((GF_Box *) ptr->info, bs);
-       if (e) return e;
-       return GF_OK;
-}
-
-GF_Err sinf_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_get_size(s);
-       if (e) return e;
-       e = gf_isom_box_size((GF_Box *) ptr->original_format);
-       if (e) return e;
-       ptr->size += ptr->original_format->size;
-       e = gf_isom_box_size((GF_Box *) ptr->scheme_type);
-       if (e) return e;
-       ptr->size += ptr->scheme_type->size;
-       e = gf_isom_box_size((GF_Box *) ptr->info);
-       if (e) return e;
-       ptr->size += ptr->info->size;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-/* OriginalFormat Box */
-GF_Box *frma_New()
-{
-       GF_OriginalFormatBox *tmp = (GF_OriginalFormatBox *) gf_malloc(sizeof(GF_OriginalFormatBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_OriginalFormatBox));
-       tmp->type = GF_ISOM_BOX_TYPE_FRMA;
-       return (GF_Box *)tmp;
-}
-
-void frma_del(GF_Box *s)
-{
-       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
-       if (ptr == NULL) return;
-       gf_free(ptr);
-}
-
-GF_Err frma_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
-       ptr->data_format = gf_bs_read_u32(bs);
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err frma_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
-       gf_bs_write_u32(bs, ptr->data_format);
-       return GF_OK;
-}
-
-GF_Err frma_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_get_size(s);
-       if (e) return e;
-       ptr->size += 4;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-/* SchemeType Box */
-GF_Box *schm_New()
-{
-       GF_SchemeTypeBox *tmp = (GF_SchemeTypeBox *) gf_malloc(sizeof(GF_SchemeTypeBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SchemeTypeBox));
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_SCHM;
-       return (GF_Box *)tmp;
-}
-
-void schm_del(GF_Box *s)
-{
-       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
-       if (ptr == NULL) return;
-       if (ptr->URI) gf_free(ptr->URI);
-       gf_free(ptr);
-}
-
-GF_Err schm_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       ptr->scheme_type = gf_bs_read_u32(bs);
-       ptr->scheme_version = gf_bs_read_u32(bs);
-       ptr->size -= 8;
-       if (ptr->size && (ptr->flags & 0x000001)) {
-               u32 len = (u32) (ptr->size);
-               ptr->URI = (char*)gf_malloc(sizeof(char)*len);
-               if (!ptr->URI) return GF_OUT_OF_MEM;
-               gf_bs_read_data(bs, ptr->URI, len);
-       }
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err schm_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       assert(e == GF_OK);
-       gf_bs_write_u32(bs, ptr->scheme_type);
-       gf_bs_write_u32(bs, ptr->scheme_version);
-       if (ptr->flags & 0x000001) gf_bs_write_data(bs, ptr->URI, strlen(ptr->URI)+1);
-       return GF_OK;
-}
-
-GF_Err schm_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       ptr->size += 8;
-       if (ptr->flags & 0x000001) ptr->size += strlen(ptr->URI)+1;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-/* SchemeInformation Box */
-GF_Box *schi_New()
-{
-       GF_SchemeInformationBox *tmp = (GF_SchemeInformationBox *) gf_malloc(sizeof(GF_SchemeInformationBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_SchemeInformationBox));
-       tmp->type = GF_ISOM_BOX_TYPE_SCHI;
-       return (GF_Box *)tmp;
-}
-
-void schi_del(GF_Box *s)
-{
-       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
-       if (ptr == NULL) return;
-       if (ptr->ikms) gf_isom_box_del((GF_Box *)ptr->ikms);
-       if (ptr->isfm) gf_isom_box_del((GF_Box *)ptr->isfm);
-       gf_free(ptr);
-}
-
-GF_Err schi_AddBox(GF_Box *s, GF_Box *a)
-{
-       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
-       switch (a->type) {
-       case GF_ISOM_BOX_TYPE_IKMS:
-               if (ptr->ikms) return GF_ISOM_INVALID_FILE;
-               ptr->ikms = (GF_ISMAKMSBox*)a;
-               return GF_OK;
-       case GF_ISOM_BOX_TYPE_ISFM:
-               if (ptr->isfm) return GF_ISOM_INVALID_FILE;
-               ptr->isfm = (GF_ISMASampleFormatBox*)a;
-               return GF_OK;
-       case GF_ISOM_BOX_TYPE_ODKM:
-               if (ptr->okms) return GF_ISOM_INVALID_FILE;
-               ptr->okms = (GF_OMADRMKMSBox*)a;
-               return GF_OK;
-       default:
-               gf_isom_box_del(a);
-               return GF_OK;
-       }
-}
-
-GF_Err schi_Read(GF_Box *s, GF_BitStream *bs)
-{
-       return gf_isom_read_box_list(s, bs, schi_AddBox);
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err schi_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
-
-       if (ptr->ikms) {
-               e = gf_isom_box_write((GF_Box *) ptr->ikms, bs);
-               if (e) return e;
-       }
-       if (ptr->isfm) {
-               e = gf_isom_box_write((GF_Box *) ptr->isfm, bs);
-               if (e) return e;
-       }
-       if (ptr->okms) {
-               e = gf_isom_box_write((GF_Box *) ptr->okms, bs);
-               if (e) return e;
-       }
-       return GF_OK;
-}
-
-GF_Err schi_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_get_size(s);
-       if (e) return e;
-
-       if (ptr->ikms) {
-               e = gf_isom_box_size((GF_Box *) ptr->ikms);
-               if (e) return e;
-               ptr->size += ptr->ikms->size;
-       }
-       if (ptr->isfm) {
-               e = gf_isom_box_size((GF_Box *) ptr->isfm);
-               if (e) return e;
-               ptr->size += ptr->isfm->size;
-       }
-       if (ptr->okms) {
-               e = gf_isom_box_size((GF_Box *) ptr->okms);
-               if (e) return e;
-               ptr->size += ptr->okms->size;
-       }
-       return GF_OK;
-}
-
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-/* ISMAKMS Box */
-GF_Box *iKMS_New()
-{
-       GF_ISMAKMSBox *tmp = (GF_ISMAKMSBox *) gf_malloc(sizeof(GF_ISMAKMSBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ISMAKMSBox));
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_IKMS;
-       return (GF_Box *)tmp;
-}
-
-void iKMS_del(GF_Box *s)
-{
-       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
-       if (ptr == NULL) return;
-       if (ptr->URI) gf_free(ptr->URI);
-       gf_free(ptr);
-}
-
-GF_Err iKMS_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       u32 len;
-       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
-
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       len = (u32) (ptr->size);
-       ptr->URI = (char*) gf_malloc(sizeof(char)*len);
-       if (!ptr->URI) return GF_OUT_OF_MEM;
-       gf_bs_read_data(bs, ptr->URI, len);
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err iKMS_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       gf_bs_write_data(bs, ptr->URI, strlen(ptr->URI)+1);
-       return GF_OK;
-}
-
-GF_Err iKMS_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       ptr->size += strlen(ptr->URI)+1;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-/* ISMASampleFormat Box */
-GF_Box *iSFM_New()
-{
-       GF_ISMASampleFormatBox *tmp = (GF_ISMASampleFormatBox *) gf_malloc(sizeof(GF_ISMASampleFormatBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ISMASampleFormatBox));
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_ISFM;
-       return (GF_Box *)tmp;
-}
-
-void iSFM_del(GF_Box *s)
-{
-       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
-       if (ptr == NULL) return;
-       gf_free(ptr);
-}
-
-
-GF_Err iSFM_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
-       if (ptr == NULL) return GF_BAD_PARAM;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       ptr->selective_encryption = gf_bs_read_int(bs, 1);
-       gf_bs_read_int(bs, 7);
-       ptr->key_indicator_length = gf_bs_read_u8(bs);
-       ptr->IV_length = gf_bs_read_u8(bs);
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err iSFM_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       gf_bs_write_int(bs, ptr->selective_encryption, 1);
-       gf_bs_write_int(bs, 0, 7);
-       gf_bs_write_u8(bs, ptr->key_indicator_length);
-       gf_bs_write_u8(bs, ptr->IV_length);
-       return GF_OK;
-}
-
-GF_Err iSFM_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       ptr->size += 3;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-
-/* OMADRMCommonHeader Box */
-GF_Box *ohdr_New()
-{
-       GF_OMADRMCommonHeaderBox *tmp;
-       GF_SAFEALLOC(tmp, GF_OMADRMCommonHeaderBox);
-       if (tmp == NULL) return NULL;
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_OHDR;
-       tmp->ExtendedHeaders = gf_list_new();
-       return (GF_Box *)tmp;
-}
-
-void ohdr_del(GF_Box *s)
-{
-       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
-       if (ptr == NULL) return;
-       gf_isom_box_array_del(ptr->ExtendedHeaders);
-       if (ptr->ContentID) gf_free(ptr->ContentID);
-       if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL);
-       if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders);
-       gf_free(ptr);
-}
-
-GF_Err ohdr_AddBox(GF_Box *s, GF_Box *a)
-{
-       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
-       return gf_list_add(ptr->ExtendedHeaders, a);
-}
-
-GF_Err ohdr_Read(GF_Box *s, GF_BitStream *bs)
-{
-       u16 cid_len, ri_len;
-       GF_Err e;
-       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
-       if (ptr == NULL) return GF_BAD_PARAM;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       ptr->EncryptionMethod = gf_bs_read_u8(bs);
-       ptr->PaddingScheme = gf_bs_read_u8(bs);
-       ptr->PlaintextLength = gf_bs_read_u64(bs);
-       cid_len = gf_bs_read_u16(bs);
-       ri_len = gf_bs_read_u16(bs);
-       ptr->TextualHeadersLen = gf_bs_read_u16(bs);
-       ptr->size -= 1+1+8+2+2+2;
-       if (ptr->size<cid_len+ri_len+ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE;
-
-       if (cid_len) {
-               ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len+1));
-               gf_bs_read_data(bs, ptr->ContentID, cid_len);
-               ptr->ContentID[cid_len]=0;
-       }
-
-       if (ri_len) {
-               ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len+1));
-               gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len);
-               ptr->RightsIssuerURL[ri_len]=0;
-       }
-       
-       if (ptr->TextualHeadersLen) {
-               ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1));
-               gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
-               ptr->TextualHeaders[ptr->TextualHeadersLen] = 0;
-       }
-
-       ptr->size -= cid_len+ri_len+ptr->TextualHeadersLen;
-
-       return gf_isom_read_box_list(s, bs, ohdr_AddBox);
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err ohdr_Write(GF_Box *s, GF_BitStream *bs)
-{
-       u16 cid_len, ri_len;
-       GF_Err e;
-       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       gf_bs_write_u8(bs, ptr->EncryptionMethod);
-       gf_bs_write_u8(bs, ptr->PaddingScheme);
-       gf_bs_write_u64(bs, ptr->PlaintextLength);
-       
-       cid_len = ptr->ContentID ? strlen(ptr->ContentID) : 0;
-       gf_bs_write_u16(bs, cid_len);
-       ri_len = ptr->RightsIssuerURL ? strlen(ptr->RightsIssuerURL) : 0;
-       gf_bs_write_u16(bs, ri_len);
-       gf_bs_write_u16(bs, ptr->TextualHeadersLen);
-
-       if (cid_len) gf_bs_write_data(bs, ptr->ContentID, strlen(ptr->ContentID));
-       if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, strlen(ptr->RightsIssuerURL));
-       if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
-       ptr->size -= cid_len+ri_len+ptr->TextualHeadersLen;
-       return gf_isom_box_array_write(s, ptr->ExtendedHeaders, bs);
-}
-
-GF_Err ohdr_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       ptr->size += 1+1+8+2+2+2;
-       if (ptr->ContentID) ptr->size += strlen(ptr->ContentID);
-       if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL);
-       if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen;
-       return gf_isom_box_array_size(s, ptr->ExtendedHeaders);
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-/* OMADRMGroupID Box */
-GF_Box *grpi_New()
-{
-       GF_OMADRMGroupIDBox *tmp;
-       GF_SAFEALLOC(tmp, GF_OMADRMGroupIDBox);
-       if (tmp == NULL) return NULL;
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_GRPI;
-       return (GF_Box *)tmp;
-}
-
-void grpi_del(GF_Box *s)
-{
-       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
-       if (ptr == NULL) return;
-       if (ptr->GroupID) gf_free(ptr->GroupID);
-       if (ptr->GroupKey) gf_free(ptr->GroupKey);
-       gf_free(ptr);
-}
-
-GF_Err grpi_Read(GF_Box *s, GF_BitStream *bs)
-{
-       u16 gid_len;
-       GF_Err e;
-       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s;
-       if (ptr == NULL) return GF_BAD_PARAM;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       gid_len = gf_bs_read_u16(bs);
-       ptr->GKEncryptionMethod = gf_bs_read_u8(bs);
-       ptr->GKLength = gf_bs_read_u16(bs);
-
-       ptr->size -= 1+2+2;
-       if (ptr->size<gid_len+ptr->GKLength) return GF_ISOM_INVALID_FILE;
-
-       ptr->GroupID = gf_malloc(sizeof(char)*(gid_len+1));
-       gf_bs_read_data(bs, ptr->GroupID, gid_len);
-       ptr->GroupID[gid_len]=0;
-       
-       ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength);
-       gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength);
-       ptr->size -= gid_len+ptr->GKLength;
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err grpi_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       u16 gid_len;
-       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       gid_len = ptr->GroupID ? strlen(ptr->GroupID) : 0;
-       gf_bs_write_u16(bs, gid_len);
-       gf_bs_write_u8(bs, ptr->GKEncryptionMethod);
-       gf_bs_write_u16(bs, ptr->GKLength);
-       gf_bs_write_data(bs, ptr->GroupID, gid_len);
-       gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength);
-       return GF_OK;
-}
-
-GF_Err grpi_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       ptr->size += 2+2+1 + ptr->GKLength;
-       if (ptr->GroupID) ptr->size += strlen(ptr->GroupID);
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-
-
-/* OMADRMMutableInformation Box */
-GF_Box *mdri_New()
-{
-       GF_OMADRMMutableInformationBox *tmp;
-       GF_SAFEALLOC(tmp, GF_OMADRMMutableInformationBox);
-       if (tmp == NULL) return NULL;
-       tmp->type = GF_ISOM_BOX_TYPE_MDRI;
-       tmp->boxes = gf_list_new();
-       return (GF_Box *)tmp;
-}
-
-void mdri_del(GF_Box *s)
-{
-       GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
-       if (ptr == NULL) return;
-       gf_isom_box_array_del(ptr->boxes);
-       gf_free(ptr);
-}
-
-GF_Err mdri_AddBox(GF_Box *s, GF_Box *a)
-{
-       GF_OMADRMMutableInformationBox *ptr = (GF_OMADRMMutableInformationBox *)s;
-       return gf_list_add(ptr->boxes, a);
-}
-
-GF_Err mdri_Read(GF_Box *s, GF_BitStream *bs)
-{
-       return gf_isom_read_box_list(s, bs, mdri_AddBox);
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err mdri_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
-       GF_Err e = gf_isom_box_write_header(s, bs);
-       if (e) return e;
-       return gf_isom_box_array_write(s, ptr->boxes, bs);
-}
-
-GF_Err mdri_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_OMADRMMutableInformationBox *ptr = (GF_OMADRMMutableInformationBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_box_get_size(s);
-       if (e) return e;
-
-       return gf_isom_box_array_size(s, ptr->boxes);
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-/* OMADRMTransactionTracking Box */
-GF_Box *odtt_New()
-{
-       GF_OMADRMTransactionTrackingBox *tmp;
-       GF_SAFEALLOC(tmp, GF_OMADRMTransactionTrackingBox);
-       if (tmp == NULL) return NULL;
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_ODTT;
-       return (GF_Box *)tmp;
-}
-
-void odtt_del(GF_Box *s)
-{
-       GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
-       gf_free(ptr);
-}
-
-GF_Err odtt_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s;
-       if (ptr == NULL) return GF_BAD_PARAM;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       gf_bs_read_data(bs, ptr->TransactionID, 16);
-       ptr->size -= 16;
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err odtt_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       gf_bs_write_data(bs, ptr->TransactionID, 16);
-       return GF_OK;
-}
-
-GF_Err odtt_Size(GF_Box *s)
-{
-       GF_Err e;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       s->size += 16;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-
-/* OMADRMRightsObject Box */
-GF_Box *odrb_New()
-{
-       GF_OMADRMRightsObjectBox *tmp;
-       GF_SAFEALLOC(tmp, GF_OMADRMRightsObjectBox);
-       if (tmp == NULL) return NULL;
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_ODRB;
-       return (GF_Box *)tmp;
-}
-
-void odrb_del(GF_Box *s)
-{
-       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s;
-       if (ptr->oma_ro) gf_free(ptr->oma_ro);
-       gf_free(ptr);
-}
-
-GF_Err odrb_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
-       if (ptr == NULL) return GF_BAD_PARAM;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       ptr->oma_ro_size = (u32) ptr->size;
-       ptr->oma_ro = (char*) gf_malloc(sizeof(char)*ptr->oma_ro_size);
-       gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size);
-       ptr->size = 0;
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err odrb_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size);
-       return GF_OK;
-}
-
-GF_Err odrb_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       s->size += ptr->oma_ro_size;
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-
-
-/* OMADRMKMS Box */
-GF_Box *odkm_New()
-{
-       GF_OMADRMKMSBox *tmp;
-       GF_SAFEALLOC(tmp, GF_OMADRMKMSBox);
-       if (tmp == NULL) return NULL;
-       gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_ODKM;
-       return (GF_Box *)tmp;
-}
-
-void odkm_del(GF_Box *s)
-{
-       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
-       if (ptr->hdr) gf_isom_box_del((GF_Box*)ptr->hdr);
-       if (ptr->fmt) gf_isom_box_del((GF_Box*)ptr->fmt);
-       gf_free(ptr);
-}
-
-GF_Err odkm_Add(GF_Box *s, GF_Box *a)
-{
-       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
-       switch (a->type) {
-       case GF_ISOM_BOX_TYPE_OHDR:
-               if (ptr->hdr) gf_isom_box_del((GF_Box*)ptr->hdr);
-               ptr->hdr = (GF_OMADRMCommonHeaderBox *)a;
-               return GF_OK;
-       case GF_ISOM_BOX_TYPE_ODAF:
-               if (ptr->fmt) gf_isom_box_del((GF_Box*)ptr->fmt);
-               ptr->fmt = (GF_OMADRMAUFormatBox*)a;
-               return GF_OK;
-       default:
-               gf_isom_box_del(a);
-               return GF_OK;
-       }
-}
-
-GF_Err odkm_Read(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       if (s == NULL) return GF_BAD_PARAM;
-       e = gf_isom_full_box_read(s, bs);
-       if (e) return e;
-       return gf_isom_read_box_list(s, bs, odkm_Add);
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_Err odkm_Write(GF_Box *s, GF_BitStream *bs)
-{
-       GF_Err e;
-       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_write(s, bs);
-       if (e) return e;
-       if (ptr->hdr) {
-               e = gf_isom_box_write((GF_Box*)ptr->hdr, bs);
-               if (e) return e;
-       }
-       if (ptr->fmt) {
-               e = gf_isom_box_write((GF_Box*)ptr->fmt, bs);
-               if (e) return e;
-       }
-       return GF_OK;
-}
-
-GF_Err odkm_Size(GF_Box *s)
-{
-       GF_Err e;
-       GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
-       if (!s) return GF_BAD_PARAM;
-       e = gf_isom_full_box_get_size(s);
-       if (e) return e;
-       if (ptr->hdr) {
-               e = gf_isom_box_size((GF_Box*)ptr->hdr);
-               if (e) return e;
-               ptr->size += ptr->hdr->size;
-       }
-       if (ptr->fmt) {
-               e = gf_isom_box_size((GF_Box*)ptr->fmt);
-               if (e) return e;
-               ptr->size += ptr->fmt->size;
-       }
-       return GF_OK;
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-#endif /*GPAC_DISABLE_ISOM*/
index 824e9dcc86baceedefaf28451f2484d353ba6913..94774524be00a5b757e972034c013b9cf583c087 100644 (file)
@@ -1,12 +1,13 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato / Jean Le Feuvre 2005
+ *          Authors: Cyril Concolato / Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
  *
- *  GPAC is free software you can redistribute it and/or modify
+ *  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.
 
 GF_Box *meta_New()
 {
-       GF_MetaBox *tmp = (GF_MetaBox *) gf_malloc(sizeof(GF_MetaBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_MetaBox));
+       ISOM_DECL_BOX_ALLOC(GF_MetaBox, GF_ISOM_BOX_TYPE_META);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_META;
-       tmp->other_boxes = gf_list_new();
        return (GF_Box *)tmp;
 }
 
 void meta_del(GF_Box *s)
 {
-       u32 count, i;
        GF_MetaBox *ptr = (GF_MetaBox *)s;
        if (ptr == NULL) return;
        gf_isom_box_del((GF_Box *)ptr->handler);
@@ -49,12 +45,6 @@ void meta_del(GF_Box *s)
        if (ptr->protections) gf_isom_box_del((GF_Box *)ptr->protections);
        if (ptr->item_infos) gf_isom_box_del((GF_Box *)ptr->item_infos);
        if (ptr->IPMP_control) gf_isom_box_del((GF_Box *)ptr->IPMP_control);
-       count = gf_list_count(ptr->other_boxes);
-       for (i = 0; i < count; i++) {
-               GF_Box *a = (GF_Box *)gf_list_get(ptr->other_boxes, i);
-               gf_isom_box_del(a);
-       }
-       gf_list_del(ptr->other_boxes);
        gf_free(ptr);
 }
 
@@ -90,10 +80,8 @@ GF_Err meta_AddBox(GF_Box *s, GF_Box *a)
        case GF_ISOM_BOX_TYPE_XML: 
        case GF_ISOM_BOX_TYPE_BXML: 
        case GF_ISOM_BOX_TYPE_ILST: 
-               gf_list_add(ptr->other_boxes, a); break;
        default: 
-               gf_isom_box_del(a); 
-               break;
+               return gf_isom_box_add_default(s, a); 
        }
        return GF_OK;
 }
@@ -113,14 +101,15 @@ GF_Err meta_Read(GF_Box *s, GF_BitStream *bs)
 #ifndef GPAC_DISABLE_ISOM_WRITE
 GF_Err meta_Write(GF_Box *s, GF_BitStream *bs)
 {
-       u32 count, i;
        GF_Err e;
        GF_MetaBox *ptr = (GF_MetaBox *)s;
        if (!s) return GF_BAD_PARAM;
        e = gf_isom_full_box_write(s, bs);
        if (e) return e;
-       e = gf_isom_box_write((GF_Box *) ptr->handler, bs);
-       if (e) return e;
+       if (ptr->handler) {
+               e = gf_isom_box_write((GF_Box *) ptr->handler, bs);
+               if (e) return e;
+       }
        if (ptr->primary_resource) {
                e = gf_isom_box_write((GF_Box *) ptr->primary_resource, bs);
                if (e) return e;
@@ -145,27 +134,21 @@ GF_Err meta_Write(GF_Box *s, GF_BitStream *bs)
                e = gf_isom_box_write((GF_Box *) ptr->IPMP_control, bs);
                if (e) return e;
        }
-       if ((count = gf_list_count(ptr->other_boxes))) {
-               for (i = 0; i < count; i++) {
-                       GF_Box *a = (GF_Box *)gf_list_get(ptr->other_boxes, i);
-                       e = gf_isom_box_write(a, bs);
-                       if (e) return e;
-               }
-       }
        return GF_OK;
 }
 
 GF_Err meta_Size(GF_Box *s)
 {
-       u32 i, count;
        GF_Err e;
        GF_MetaBox *ptr = (GF_MetaBox *)s;
        if (!s) return GF_BAD_PARAM;
        e = gf_isom_full_box_get_size(s);
        if (e) return e;
-       e = gf_isom_box_size((GF_Box *) ptr->handler);
-       if (e) return e;
-       ptr->size += ptr->handler->size;
+       if (ptr->handler) {
+               e = gf_isom_box_size((GF_Box *) ptr->handler);
+               if (e) return e;
+               ptr->size += ptr->handler->size;
+       }
        if (ptr->primary_resource) {
                e = gf_isom_box_size((GF_Box *) ptr->primary_resource);
                if (e) return e;
@@ -196,25 +179,14 @@ GF_Err meta_Size(GF_Box *s)
                if (e) return e;
                ptr->size += ptr->IPMP_control->size;
        }
-       if ((count = gf_list_count(ptr->other_boxes))) {
-               for (i = 0; i < count; i++) {
-                       GF_Box *a = (GF_Box *)gf_list_get(ptr->other_boxes, i);
-                       e = gf_isom_box_size(a);
-                       if (e) return e;
-                       ptr->size += a->size;
-               }
-       }
        return GF_OK;
 }
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 GF_Box *xml_New()
 {
-       GF_XMLBox *tmp = (GF_XMLBox *) gf_malloc(sizeof(GF_XMLBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_XMLBox));
+       ISOM_DECL_BOX_ALLOC(GF_XMLBox, GF_ISOM_BOX_TYPE_XML);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_XML;
        return (GF_Box *)tmp;
 }
 
@@ -266,11 +238,8 @@ GF_Err xml_Size(GF_Box *s)
 
 GF_Box *bxml_New()
 {
-       GF_BinaryXMLBox *tmp = (GF_BinaryXMLBox *) gf_malloc(sizeof(GF_BinaryXMLBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_BinaryXMLBox));
+       ISOM_DECL_BOX_ALLOC(GF_BinaryXMLBox, GF_ISOM_BOX_TYPE_BXML);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_BXML;
        return (GF_Box *)tmp;
 }
 
@@ -321,11 +290,8 @@ GF_Err bxml_Size(GF_Box *s)
 
 GF_Box *iloc_New()
 {
-       GF_ItemLocationBox *tmp = (GF_ItemLocationBox *) gf_malloc(sizeof(GF_ItemLocationBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ItemLocationBox));
+       ISOM_DECL_BOX_ALLOC(GF_ItemLocationBox, GF_ISOM_BOX_TYPE_ILOC);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_ILOC;
        tmp->location_entries = gf_list_new();
        return (GF_Box *)tmp;
 }
@@ -441,11 +407,8 @@ GF_Err iloc_Size(GF_Box *s)
 
 GF_Box *pitm_New()
 {
-       GF_PrimaryItemBox *tmp = (GF_PrimaryItemBox *) gf_malloc(sizeof(GF_PrimaryItemBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_PrimaryItemBox));
+       ISOM_DECL_BOX_ALLOC(GF_PrimaryItemBox, GF_ISOM_BOX_TYPE_PITM);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_PITM;
        return (GF_Box *)tmp;
 }
 
@@ -492,11 +455,8 @@ GF_Err pitm_Size(GF_Box *s)
 
 GF_Box *ipro_New()
 {
-       GF_ItemProtectionBox *tmp = (GF_ItemProtectionBox *) gf_malloc(sizeof(GF_ItemProtectionBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ItemProtectionBox));
+       ISOM_DECL_BOX_ALLOC(GF_ItemProtectionBox, GF_ISOM_BOX_TYPE_IPRO);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_IPRO;
        tmp->protection_information = gf_list_new();
        return (GF_Box *)tmp;
 }
@@ -519,10 +479,9 @@ GF_Err ipro_AddBox(GF_Box *s, GF_Box *a)
 {
        GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s;
        if (a->type == GF_ISOM_BOX_TYPE_SINF) 
-               gf_list_add(ptr->protection_information, a);
+               return gf_list_add(ptr->protection_information, a);
        else 
-               gf_isom_box_del(a);
-       return GF_OK;
+               return gf_isom_box_add_default(s, a);
 }
 GF_Err ipro_Read(GF_Box *s, GF_BitStream *bs)
 {
@@ -576,11 +535,8 @@ GF_Err ipro_Size(GF_Box *s)
 
 GF_Box *infe_New()
 {
-       GF_ItemInfoEntryBox *tmp = (GF_ItemInfoEntryBox *) gf_malloc(sizeof(GF_ItemInfoEntryBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ItemInfoEntryBox));
+       ISOM_DECL_BOX_ALLOC(GF_ItemInfoEntryBox, GF_ISOM_BOX_TYPE_INFE);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_INFE;
        return (GF_Box *)tmp;
 }
 
@@ -681,11 +637,8 @@ GF_Err infe_Size(GF_Box *s)
 
 GF_Box *iinf_New()
 {
-       GF_ItemInfoBox *tmp = (GF_ItemInfoBox *) gf_malloc(sizeof(GF_ItemInfoBox));
-       if (tmp == NULL) return NULL;
-       memset(tmp, 0, sizeof(GF_ItemInfoBox));
+       ISOM_DECL_BOX_ALLOC(GF_ItemInfoBox, GF_ISOM_BOX_TYPE_IINF);
        gf_isom_full_box_init((GF_Box *)tmp);
-       tmp->type = GF_ISOM_BOX_TYPE_IINF;
        tmp->item_infos = gf_list_new();
        return (GF_Box *)tmp;
 }
index c59c60225a2d69ce0d106e76608fcea8912c2e62..9d72e9272197c262fdc7834a4f34fcdfe2df3f9b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -49,6 +50,15 @@ static void DumpData(FILE *trace, char *data, u32 dataLength)
        }
 }
 
+static void DumpDataHex(FILE *trace, char *data, u32 dataLength)
+{
+       u32 i;
+       fprintf(trace, "0x");
+       for (i=0; i<dataLength; i++) {
+               fprintf(trace, "%02X", (unsigned char) data[i]);
+       }
+}
+
 GF_Err DumpBox(GF_Box *a, FILE * trace)
 {
        if (a->size > 0xFFFFFFFF) {
@@ -70,7 +80,6 @@ GF_Err DumpBox(GF_Box *a, FILE * trace)
        return GF_OK;
 }
 
-
 GF_Err gf_box_dump(void *ptr, FILE * trace)
 {
        GF_Box *a = (GF_Box *) ptr;
@@ -146,6 +155,8 @@ GF_Err gf_box_dump(void *ptr, FILE * trace)
                return stts_dump(a, trace);
        case GF_ISOM_BOX_TYPE_CTTS:
                return ctts_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_CSLG:
+               return cslg_dump(a, trace);
        case GF_ISOM_BOX_TYPE_STSH:
                return stsh_dump(a, trace);
        case GF_ISOM_BOX_TYPE_ELST:
@@ -183,7 +194,10 @@ GF_Err gf_box_dump(void *ptr, FILE * trace)
                return sbgp_dump(a, trace);
        case GF_ISOM_BOX_TYPE_SGPD: 
                return sgpd_dump(a, trace);
-
+       case GF_ISOM_BOX_TYPE_SAIZ: 
+               return saiz_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_SAIO: 
+               return saio_dump(a, trace);
 
        case GF_ISOM_BOX_TYPE_RTP_STSD:
                return ghnt_dump(a, trace);
@@ -239,7 +253,7 @@ GF_Err gf_box_dump(void *ptr, FILE * trace)
        case GF_ISOM_BOX_TYPE_FTYP: 
        case GF_ISOM_BOX_TYPE_STYP: 
         return ftyp_dump(a, trace);
-       case GF_ISOM_BOX_TYPE_FADB:
+       case GF_ISOM_BOX_TYPE_PADB:
                return padb_dump(a, trace);
 
 #ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
@@ -327,6 +341,11 @@ GF_Err gf_box_dump(void *ptr, FILE * trace)
        case GF_ISOM_BOX_TYPE_TWRP:
                return twrp_dump(a, trace);
 
+       case GF_ISOM_BOX_TYPE_PSSH:
+               return pssh_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_TENC:
+               return tenc_dump(a, trace);
+
        /* ISMA 1.0 Encryption and Authentication V 1.0 */
        case GF_ISOM_BOX_TYPE_IKMS:
                return iKMS_dump(a, trace);
@@ -387,6 +406,17 @@ GF_Err gf_box_dump(void *ptr, FILE * trace)
        case GF_ISOM_BOX_TYPE_COVR:
        case GF_ISOM_BOX_TYPE_iTunesSpecificInfo:
                return apple_tag_dump(a, trace);
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /*Adobe extensions*/
+       case GF_ISOM_BOX_TYPE_ABST:
+               return abst_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_AFRA:
+               return afra_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_ASRT:
+               return asrt_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_AFRT:
+               return afrt_dump(a, trace);
+#endif
        /*Apple extensions*/
        case GF_ISOM_BOX_TYPE_ILST:
                return ilst_dump(a, trace);
@@ -434,11 +464,22 @@ GF_Err gf_box_dump(void *ptr, FILE * trace)
        case GF_ISOM_BOX_TYPE_PCRB:
                return pcrb_dump(a, trace);
 
-       default: return defa_dump(a, trace);
+       case GF_ISOM_BOX_TYPE_UUID:
+               switch ( ((GF_UnknownUUIDBox *)a)->internal_4cc) {
+               case GF_ISOM_BOX_UUID_TENC: return piff_tenc_dump(a, trace);
+               case GF_ISOM_BOX_UUID_PSEC: return piff_psec_dump(a, trace);
+               case GF_ISOM_BOX_UUID_PSSH: return piff_pssh_dump(a, trace);
+               case GF_ISOM_BOX_UUID_TFRF: 
+               case GF_ISOM_BOX_UUID_TFXD: 
+               default:
+                       return defa_dump(a, trace);
+               }
+               
+       default: 
+               return defa_dump(a, trace);
        }
 }
 
-
 GF_Err gf_box_array_dump(GF_List *list, FILE * trace)
 {
        u32 i;
@@ -451,12 +492,19 @@ GF_Err gf_box_array_dump(GF_List *list, FILE * trace)
        return GF_OK;
 }
 
+void gf_box_dump_done(char *name, GF_Box *ptr, FILE *trace)
+{
+       if (ptr && ptr->other_boxes) {
+               gf_box_array_dump(ptr->other_boxes, trace);
+       }
+       if (name) 
+               fprintf(trace, "</%s>\n", name);
+}
 
 
 GF_EXPORT
 GF_Err gf_isom_dump(GF_ISOFile *mov, FILE * trace)
 {
-       GF_Err gf_box_dump(void *ptr, FILE * trace);
        u32 i;
        GF_Box *box;
        if (!mov || !trace) return GF_BAD_PARAM;
@@ -480,7 +528,13 @@ GF_Err gf_isom_dump(GF_ISOFile *mov, FILE * trace)
                case GF_ISOM_BOX_TYPE_STYP:
                case GF_ISOM_BOX_TYPE_SIDX:
                case GF_ISOM_BOX_TYPE_PCRB:
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+               /*Adobe specific*/
+               case GF_ISOM_BOX_TYPE_AFRA:
+               case GF_ISOM_BOX_TYPE_ABST:
 #endif
+#endif
+               case GF_ISOM_BOX_TYPE_MFRA:
                        break;
 
                default:
@@ -499,7 +553,7 @@ GF_Err gf_full_box_dump(GF_Box *a, FILE * trace)
 {
        GF_FullBox *p;
        p = (GF_FullBox *)a;
-       fprintf(trace, "<FullBoxInfo Version=\"%d\" Flags=\"%d\"/>\n", p->version, p->flags);
+       fprintf(trace, "<FullBoxInfo Version=\"%d\" Flags=\"0x%X\"/>\n", p->version, p->flags);
        return GF_OK;
 }
 
@@ -527,7 +581,10 @@ GF_Err reftype_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->trackIDCount; i++) fprintf(trace, " %d", p->trackIDs[i]);
        fprintf(trace, "\">\n");
        DumpBox(a, trace);
+
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%sTrackReferenceBox>\n", s);
+
        p->type = GF_ISOM_BOX_TYPE_REFT;
        return GF_OK;
 }
@@ -539,7 +596,7 @@ GF_Err free_dump(GF_Box *a, FILE * trace)
        p = (GF_FreeSpaceBox *)a;
        fprintf(trace, "<FreeSpaceBox size=\"%d\">\n", p->dataSize);
        DumpBox(a, trace);
-       fprintf(trace, "</FreeSpaceBox>\n");
+       gf_box_dump_done("FreeSpaceBox", a, trace);
        return GF_OK;
 }
 
@@ -550,7 +607,7 @@ GF_Err mdat_dump(GF_Box *a, FILE * trace)
        p = (GF_MediaDataBox *)a;
        fprintf(trace, "<MediaDataBox dataSize=\""LLD"\">\n", LLD_CAST p->dataSize);
        DumpBox(a, trace);
-       fprintf(trace, "</MediaDataBox>\n");
+       gf_box_dump_done("MediaDataBox", a, trace);
        return GF_OK;
 }
 
@@ -571,8 +628,7 @@ GF_Err moov_dump(GF_Box *a, FILE * trace)
 
        gf_box_array_dump(p->trackList, trace);
        if (p->udta) gf_box_dump(p->udta, trace);
-       gf_box_array_dump(p->boxes, trace);
-       fprintf(trace, "</MovieBox>\n");
+       gf_box_dump_done("MovieBox", a, trace);
        return GF_OK;
 }
 
@@ -592,7 +648,7 @@ GF_Err mvhd_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
-       fprintf(trace, "</MovieHeaderBox>");
+       gf_box_dump_done("MovieHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -611,7 +667,7 @@ GF_Err mdhd_dump(GF_Box *a, FILE * trace)
 
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</MediaHeaderBox>\n");
+       gf_box_dump_done("MediaHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -620,7 +676,7 @@ GF_Err vmhd_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<VideoMediaHeaderBox>\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</VideoMediaHeaderBox>\n");
+       gf_box_dump_done("VideoMediaHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -629,7 +685,7 @@ GF_Err smhd_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<SoundMediaHeaderBox>\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</SoundMediaHeaderBox>\n");
+       gf_box_dump_done("SoundMediaHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -648,7 +704,7 @@ GF_Err hmhd_dump(GF_Box *a, FILE * trace)
 
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</HintMediaHeaderBox>\n");
+       gf_box_dump_done("HintMediaHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -657,7 +713,7 @@ GF_Err nmhd_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<MPEGMediaHeaderBox>\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</MPEGMediaHeaderBox>\n");
+       gf_box_dump_done("MPEGMediaHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -671,6 +727,7 @@ GF_Err stbl_dump(GF_Box *a, FILE * trace)
        gf_box_dump(p->SampleDescription, trace);
        gf_box_dump(p->TimeToSample, trace);
        if (p->CompositionOffset) gf_box_dump(p->CompositionOffset, trace);
+       if (p->CompositionToDecode) gf_box_dump(p->CompositionToDecode, trace);
        if (p->SyncSample) gf_box_dump(p->SyncSample, trace);
        if (p->ShadowSync) gf_box_dump(p->ShadowSync, trace);
        gf_box_dump(p->SampleToChunk, trace);
@@ -683,8 +740,8 @@ GF_Err stbl_dump(GF_Box *a, FILE * trace)
        if (p->Fragments) gf_box_dump(p->Fragments, trace);
        if (p->sampleGroupsDescription) gf_box_array_dump(p->sampleGroupsDescription, trace);
        if (p->sampleGroups) gf_box_array_dump(p->sampleGroups, trace);
-
-       fprintf(trace, "</SampleTableBox>\n");
+       
+       gf_box_dump_done("SampleTableBox", a, trace);
        return GF_OK;
 }
 
@@ -695,7 +752,7 @@ GF_Err dinf_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<DataInformationBox>");
        DumpBox(a, trace);
        gf_box_dump(p->dref, trace);
-       fprintf(trace, "</DataInformationBox>\n");
+       gf_box_dump_done("DataInformationBox", a, trace);
        return GF_OK;
 }
 
@@ -717,7 +774,7 @@ GF_Err url_dump(GF_Box *a, FILE * trace)
        }
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</URLDataEntryBox>\n");
+       gf_box_dump_done("URLDataEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -733,7 +790,7 @@ GF_Err urn_dump(GF_Box *a, FILE * trace)
 
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</URNDataEntryBox>\n");
+       gf_box_dump_done("URNDataEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -745,7 +802,7 @@ GF_Err cprt_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<CopyrightBox LanguageCode=\"%s\" CopyrightNotice=\"%s\">\n", p->packedLanguageCode, p->notice);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</CopyrightBox>\n");
+       gf_box_dump_done("CopyrightBox", a, trace);
        return GF_OK;
 }
 
@@ -780,7 +837,7 @@ GF_Err chpl_dump(GF_Box *a, FILE * trace)
                fprintf(trace, "<Chapter name=\"%s\" startTime=\"%s\" />\n", ce->name, format_duration(ce->start_time, 1000*10000, szDur));
        }
 
-       fprintf(trace, "</ChapterListBox>\n");
+       gf_box_dump_done("ChapterListBox", a, trace);
        return GF_OK;
 }
 
@@ -795,7 +852,7 @@ GF_Err dpin_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->count; i++) {
                fprintf(trace, "<DownloadInfo rate=\"%d\" estimatedTime=\"%d\" />\n", p->rates[i], p->times[i]);
        }
-       fprintf(trace, "</ProgressiveDownloadBox>\n");
+       gf_box_dump_done("ProgressiveDownloadBox", a, trace);
        return GF_OK;
 }
 
@@ -814,7 +871,7 @@ GF_Err hdlr_dump(GF_Box *a, FILE * trace)
        fprintf(trace, ">\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</HandlerBox>\n");
+       gf_box_dump_done("HandlerBox", a, trace);
        return GF_OK;
 }
 
@@ -836,7 +893,7 @@ GF_Err iods_dump(GF_Box *a, FILE * trace)
        } else {
                fprintf(trace, "<!--WARNING: Object Descriptor not present-->\n");
        }
-       fprintf(trace, "</ObjectDescriptorBox>\n");
+       gf_box_dump_done("ObjectDescriptorBox", a, trace);
        return GF_OK;
 }
 
@@ -857,8 +914,7 @@ GF_Err trak_dump(GF_Box *a, FILE * trace)
        if (p->editBox) gf_box_dump(p->editBox, trace);
        if (p->Media) gf_box_dump(p->Media, trace);
        if (p->udta) gf_box_dump(p->udta, trace);
-       gf_box_array_dump(p->boxes, trace);
-       fprintf(trace, "</TrackBox>\n");
+       gf_box_dump_done("TrackBox", a, trace);
        return GF_OK;
 }
 
@@ -875,9 +931,9 @@ GF_Err mp4s_dump(GF_Box *a, FILE * trace)
                fprintf(trace, "<!--INVALID MP4 FILE: ESDBox not present in MPEG Sample Description or corrupted-->\n");
        }
        if (a->type == GF_ISOM_BOX_TYPE_ENCS) {
-               gf_box_dump(p->protection_info, trace);
+               gf_box_array_dump(p->protections, trace);
        }
-       fprintf(trace, "</MPEGSystemsSampleDescriptionBox>\n");
+       gf_box_dump_done("MPEGSystemsSampleDescriptionBox", a, trace);
        return GF_OK;
 }
 
@@ -901,6 +957,7 @@ GF_Err mp4v_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<%s", name);
        base_visual_entry_dump((GF_VisualSampleEntryBox *)p, trace);
        fprintf(trace, ">\n");
+       DumpBox(a, trace);
 
        if (p->esd) {
                gf_box_dump(p->esd, trace);
@@ -912,13 +969,12 @@ GF_Err mp4v_dump(GF_Box *a, FILE * trace)
                if (p->svc_config) gf_box_dump(p->svc_config, trace);
        }
        if (a->type == GF_ISOM_BOX_TYPE_ENCV) {
-               gf_box_dump(p->protection_info, trace);
+               gf_box_array_dump(p->protections, trace);
        }
        if (p->pasp) gf_box_dump(p->pasp, trace);
        if (p->rvcc) gf_box_dump(p->rvcc, trace);
 
-       DumpBox(a, trace);
-
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%s>\n", name);
        return GF_OK;
 }
@@ -946,9 +1002,9 @@ GF_Err mp4a_dump(GF_Box *a, FILE * trace)
                fprintf(trace, "<!--INVALID MP4 FILE: ESDBox not present in MPEG Sample Description or corrupted-->\n");
        }
        if (a->type == GF_ISOM_BOX_TYPE_ENCA) {
-               gf_box_dump(p->protection_info, trace);
+               gf_box_array_dump(p->protections, trace);
        }
-       fprintf(trace, "</MPEGAudioSampleDescriptionBox>\n");
+       gf_box_dump_done("MPEGAudioSampleDescriptionBox", a, trace);
        return GF_OK;
 }
 
@@ -959,7 +1015,7 @@ GF_Err gnrm_dump(GF_Box *a, FILE * trace)
        a->type = p->EntryType;
        DumpBox(a, trace);
        a->type = GF_ISOM_BOX_TYPE_GNRM;
-       fprintf(trace, "</SampleDescriptionBox>\n");
+       gf_box_dump_done("SampleDescriptionBox", a, trace);
        return GF_OK;
 }
 
@@ -967,11 +1023,11 @@ GF_Err gnrv_dump(GF_Box *a, FILE * trace)
 {
        GF_GenericVisualSampleEntryBox *p = (GF_GenericVisualSampleEntryBox *)a;
        fprintf(trace, "<VisualSampleDescriptionBox DataReferenceIndex=\"%d\" Version=\"%d\" Revision=\"%d\" Vendor=\"%d\" TemporalQuality=\"%d\" SpacialQuality=\"%d\" Width=\"%d\" Height=\"%d\" HorizontalResolution=\"%d\" VerticalResolution=\"%d\" CompressorName=\"%s\" BitDepth=\"%d\">\n",
-               p->dataReferenceIndex, p->version, p->revision, p->vendor, p->temporal_quality, p->spacial_quality, p->Width, p->Height, p->horiz_res, p->vert_res, p->compressor_name, p->bit_depth);
+               p->dataReferenceIndex, p->version, p->revision, p->vendor, p->temporal_quality, p->spatial_quality, p->Width, p->Height, p->horiz_res, p->vert_res, p->compressor_name, p->bit_depth);
        a->type = p->EntryType;
        DumpBox(a, trace);
        a->type = GF_ISOM_BOX_TYPE_GNRV;
-       fprintf(trace, "</VisualSampleDescriptionBox>\n");
+       gf_box_dump_done("VisualSampleDescriptionBox", a, trace);
        return GF_OK;
 }
 
@@ -983,7 +1039,7 @@ GF_Err gnra_dump(GF_Box *a, FILE * trace)
        a->type = p->EntryType;
        DumpBox(a, trace);
        a->type = GF_ISOM_BOX_TYPE_GNRA;
-       fprintf(trace, "</AudioSampleDescriptionBox>\n");
+       gf_box_dump_done("AudioSampleDescriptionBox", a, trace);
        return GF_OK;
 }
 
@@ -995,7 +1051,7 @@ GF_Err edts_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<EditBox>\n");
        DumpBox(a, trace);
        gf_box_dump(p->editList, trace);
-       fprintf(trace, "</EditBox>\n");
+       gf_box_dump_done("EditBox", a, trace);
        return GF_OK;
 }
 
@@ -1012,68 +1068,86 @@ GF_Err udta_dump(GF_Box *a, FILE * trace)
        i=0;
        while ((map = (GF_UserDataMap *)gf_list_enum(p->recordList, &i))) {
                fprintf(trace, "<UDTARecord Type=\"%s\">\n", gf_4cc_to_str(map->boxType));
-               gf_box_array_dump(map->boxList, trace);
+               gf_box_array_dump(map->other_boxes, trace);
                fprintf(trace, "</UDTARecord>\n");
        }
-       fprintf(trace, "</UserDataBox>\n");
+       gf_box_dump_done("UserDataBox", a, trace);
        return GF_OK;
 }
 
 GF_Err dref_dump(GF_Box *a, FILE * trace)
 {
-       GF_DataReferenceBox *p;
-
-       p = (GF_DataReferenceBox *)a;
+//     GF_DataReferenceBox *p = (GF_DataReferenceBox *)a;
        fprintf(trace, "<DataReferenceBox>\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       gf_box_array_dump(p->boxList, trace);
-       fprintf(trace, "</DataReferenceBox>\n");
+       gf_box_dump_done("DataReferenceBox", a, trace);
        return GF_OK;
 }
 
 GF_Err stsd_dump(GF_Box *a, FILE * trace)
 {
-       GF_SampleDescriptionBox *p;
-       p = (GF_SampleDescriptionBox *)a;
+//     GF_SampleDescriptionBox *p = (GF_SampleDescriptionBox *)a;
        fprintf(trace, "<SampleDescriptionBox>\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       gf_box_array_dump(p->boxList, trace);
-       fprintf(trace, "</SampleDescriptionBox>\n");
+       gf_box_dump_done("SampleDescriptionBox", a, trace);
        return GF_OK;
 }
 
 GF_Err stts_dump(GF_Box *a, FILE * trace)
 {
        GF_TimeToSampleBox *p;
-       u32 i;
+       u32 i, nb_samples;
 
        p = (GF_TimeToSampleBox *)a;
        fprintf(trace, "<TimeToSampleBox EntryCount=\"%d\">\n", p->nb_entries);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
+       nb_samples = 0;
        for (i=0; i<p->nb_entries; i++) {
                fprintf(trace, "<TimeToSampleEntry SampleDelta=\"%d\" SampleCount=\"%d\"/>\n", p->entries[i].sampleDelta, p->entries[i].sampleCount);
+               nb_samples += p->entries[i].sampleCount;
        }
-       fprintf(trace, "</TimeToSampleBox>\n");
+       fprintf(trace, "<!-- counted %d samples in STTS entries -->\n", nb_samples);
+       gf_box_dump_done("TimeToSampleBox", a, trace);
        return GF_OK;
 }
 
 GF_Err ctts_dump(GF_Box *a, FILE * trace)
 {
        GF_CompositionOffsetBox *p;
-       u32 i;
+       u32 i, nb_samples;
        p = (GF_CompositionOffsetBox *)a;
        fprintf(trace, "<CompositionOffsetBox EntryCount=\"%d\">\n", p->nb_entries);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
+       nb_samples = 0;
        for (i=0; i<p->nb_entries;i++) {
                fprintf(trace, "<CompositionOffsetEntry CompositionOffset=\"%d\" SampleCount=\"%d\"/>\n", p->entries[i].decodingOffset, p->entries[i].sampleCount);
+               nb_samples += p->entries[i].sampleCount;
        }
-       fprintf(trace, "</CompositionOffsetBox>\n");
+       fprintf(trace, "<!-- counted %d samples in CTTS entries -->\n", nb_samples);
+       gf_box_dump_done("CompositionOffsetBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err cslg_dump(GF_Box *a, FILE * trace)
+{
+       GF_CompositionToDecodeBox *p;
+
+       p = (GF_CompositionToDecodeBox *)a;
+       fprintf(trace, "<CompositionToDecodeBox>\n");
+       DumpBox(a, trace);
+       gf_full_box_dump(a, trace);
+       fprintf(trace, "<CompositionToDTSShift=\"%d\"/>\n", p->compositionToDTSShift);
+       fprintf(trace, "<LeastDecodeToDisplayDelta=\"%d\"/>\n", p->leastDecodeToDisplayDelta);
+       fprintf(trace, "<GreatestDecodeToDisplayDelta=\"%d\"/>\n", p->greatestDecodeToDisplayDelta);
+       fprintf(trace, "<CompositionStartTime=\"%d\"/>\n", p->compositionStartTime);
+       fprintf(trace, "<CompositionEndTime=\"%d\"/>\n", p->compositionEndTime);
+       gf_box_dump_done("CompositionToDecodeBox", a, trace);
        return GF_OK;
 }
 
@@ -1091,7 +1165,7 @@ GF_Err stsh_dump(GF_Box *a, FILE * trace)
        while ((t = (GF_StshEntry *)gf_list_enum(p->entries, &i))) {
                fprintf(trace, "<SyncShadowEntry ShadowedSample=\"%d\" SyncSample=\"%d\"/>\n", t->shadowedSampleNumber, t->syncSampleNumber);
        }
-       fprintf(trace, "</SyncShadowBox>\n");
+       gf_box_dump_done("SyncShadowBox", a, trace);
        return GF_OK;
 }
 
@@ -1110,24 +1184,31 @@ GF_Err elst_dump(GF_Box *a, FILE * trace)
        while ((t = (GF_EdtsEntry *)gf_list_enum(p->entryList, &i))) {
                fprintf(trace, "<EditListEntry Duration=\""LLD"\" MediaTime=\""LLD"\" MediaRate=\"%u\"/>\n", LLD_CAST t->segmentDuration, LLD_CAST t->mediaTime, t->mediaRate);
        }
-       fprintf(trace, "</EditListBox>\n");
+       gf_box_dump_done("EditListBox", a, trace);
        return GF_OK;
 }
 
 GF_Err stsc_dump(GF_Box *a, FILE * trace)
 {
        GF_SampleToChunkBox *p;
-       u32 i;
+       u32 i, nb_samples;
 
        p = (GF_SampleToChunkBox *)a;
        fprintf(trace, "<SampleToChunkBox EntryCount=\"%d\">\n", p->nb_entries);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
+       nb_samples = 0;
        for (i=0; i<p->nb_entries; i++) {
                fprintf(trace, "<SampleToChunkEntry FirstChunk=\"%d\" SamplesPerChunk=\"%d\" SampleDescriptionIndex=\"%d\"/>\n", p->entries[i].firstChunk, p->entries[i].samplesPerChunk, p->entries[i].sampleDescriptionIndex);
+               if (i+1<p->nb_entries) {
+                       nb_samples += (p->entries[i+1].firstChunk - p->entries[i].firstChunk) * p->entries[i].samplesPerChunk;
+               } else {
+                       nb_samples += p->entries[i].samplesPerChunk;
+               }
        }
-       fprintf(trace, "</SampleToChunkBox>\n");
+       fprintf(trace, "<!-- counted %d samples in STSC entries (could be less than sample count) -->\n", nb_samples);
+       gf_box_dump_done("SampleToChunkBox", a, trace);
        return GF_OK;
 }
 
@@ -1159,6 +1240,7 @@ GF_Err stsz_dump(GF_Box *a, FILE * trace)
                        }
                }
        }
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%sBox>\n", (a->type == GF_ISOM_BOX_TYPE_STSZ) ? "SampleSize" : "CompactSampleSize");
        return GF_OK;
 }
@@ -1180,7 +1262,7 @@ GF_Err stco_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, "<ChunkEntry offset=\"%d\"/>\n", p->offsets[i]);
                }
        }
-       fprintf(trace, "</ChunkOffsetBox>\n");
+       gf_box_dump_done("ChunkOffsetBox", a, trace);
        return GF_OK;
 }
 
@@ -1201,7 +1283,7 @@ GF_Err stss_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, "<SyncSampleEntry sampleNumber=\"%d\"/>\n", p->sampleNumbers[i]);
                }
        }
-       fprintf(trace, "</SyncSampleBox>\n");
+       gf_box_dump_done("SyncSampleBox", a, trace);
        return GF_OK;
 }
 
@@ -1222,7 +1304,7 @@ GF_Err stdp_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, "<DegradationPriorityEntry DegradationPriority=\"%d\"/>\n", p->priorities[i]);
                }
        }
-       fprintf(trace, "</DegradationPriorityBox>\n");
+       gf_box_dump_done("DegradationPriorityBox", a, trace);
        return GF_OK;
 }
 
@@ -1263,7 +1345,7 @@ GF_Err sdtp_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, " />\n");
                }
        }
-       fprintf(trace, "</SampleDependencyTypeBox>\n");
+       gf_box_dump_done("SampleDependencyTypeBox", a, trace);
        return GF_OK;
 }
 
@@ -1283,7 +1365,7 @@ GF_Err co64_dump(GF_Box *a, FILE * trace)
                for (i=0; i<p->nb_entries; i++)
                        fprintf(trace, "<ChunkOffsetEntry offset=\""LLD"\"/>\n", LLD_CAST p->offsets[i]);
        }
-       fprintf(trace, "</ChunkLargeOffsetBox>\n");
+       gf_box_dump_done("ChunkLargeOffsetBox", a, trace);
        return GF_OK;
 }
 
@@ -1305,7 +1387,7 @@ GF_Err esds_dump(GF_Box *a, FILE * trace)
        } else {
                fprintf(trace, "<!--INVALID MP4 FILE: ESD not present in MPEG Sample Description or corrupted-->\n");
        }
-       fprintf(trace, "</MPEG4ESDescriptorBox>\n");
+       gf_box_dump_done("MPEG4ESDescriptorBox", a, trace);
        return GF_OK;
 }
 
@@ -1320,7 +1402,7 @@ GF_Err minf_dump(GF_Box *a, FILE * trace)
        gf_box_dump(p->InfoHeader, trace);
        gf_box_dump(p->dataInformation, trace);
        gf_box_dump(p->sampleTable, trace);
-       fprintf(trace, "</MediaInformationBox>\n");
+       gf_box_dump_done("MediaInformationBox", a, trace);
        return GF_OK;
 }
 
@@ -1352,33 +1434,28 @@ GF_Err tkhd_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
-       fprintf(trace, "</TrackHeaderBox>\n");
+       gf_box_dump_done("TrackHeaderBox", a, trace);
        return GF_OK;
 }
 
 GF_Err tref_dump(GF_Box *a, FILE * trace)
 {
-       GF_TrackReferenceBox *p;
-
-       p = (GF_TrackReferenceBox *)a;
+//     GF_TrackReferenceBox *p = (GF_TrackReferenceBox *)a;
        fprintf(trace, "<TrackReferenceBox>\n");
        DumpBox(a, trace);
-       gf_box_array_dump(p->boxList, trace);
-       fprintf(trace, "</TrackReferenceBox>\n");
+       gf_box_dump_done("TrackReferenceBox", a, trace);
        return GF_OK;
 }
 
 GF_Err mdia_dump(GF_Box *a, FILE * trace)
 {
-       GF_MediaBox *p;
-
-       p = (GF_MediaBox *)a;
+       GF_MediaBox *p = (GF_MediaBox *)a;
        fprintf(trace, "<MediaBox>\n");
        DumpBox(a, trace);
        gf_box_dump(p->mediaHeader, trace);
        gf_box_dump(p->handler, trace);
        gf_box_dump(p->information, trace);
-       fprintf(trace, "</MediaBox>\n");
+       gf_box_dump_done("MediaBox", a, trace);
        return GF_OK;
 }
 
@@ -1408,6 +1485,7 @@ GF_Err ftyp_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->altCount; i++) {
                fprintf(trace, "<BrandEntry AlternateBrand=\"%s\"/>\n", gf_4cc_to_str(p->altBrand[i]));
        }
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%s>\n",(a->type == GF_ISOM_BOX_TYPE_FTYP ? "FileTypeBox" : "SegmentTypeBox"));
        return GF_OK;
 }
@@ -1423,7 +1501,7 @@ GF_Err padb_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->SampleCount; i+=1) {
                fprintf(trace, "<PaddingBitsEntry PaddingBits=\"%d\"/>\n", p->padbits[i]);
        }
-       fprintf(trace, "</PaddingBitsBox>\n");
+       gf_box_dump_done("PaddingBitsBox", a, trace);
        return GF_OK;
 }
 
@@ -1446,7 +1524,7 @@ GF_Err stsf_dump(GF_Box *a, FILE * trace)
                fprintf(trace, "</SampleFragmentEntry>\n");
        }
 
-       fprintf(trace, "</SampleFragmentBox>\n");
+       gf_box_dump_done("SampleFragmentBox", a, trace);
        return GF_OK;
 }
 
@@ -1473,6 +1551,7 @@ GF_Err gppa_dump(GF_Box *a, FILE * trace)
        } else {
                fprintf(trace, "<!--INVALID 3GPP FILE: Config not present in Sample Description-->\n");
        }
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%sBox>\n", szName);
        return GF_OK;
 }
@@ -1495,6 +1574,7 @@ GF_Err gppv_dump(GF_Box *a, FILE * trace)
        } else {
                fprintf(trace, "<!--INVALID 3GPP FILE: Config not present in Sample Description-->\n");
        }
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%sBox>\n", szName);
        return GF_OK;
 }
@@ -1510,29 +1590,29 @@ GF_Err gppc_dump(GF_Box *a, FILE * trace)
                fprintf(trace, " FramesPerSample=\"%d\" SupportedModes=\"%x\" ModeRotating=\"%d\"", p->cfg.frames_per_sample, p->cfg.AMR_mode_set, p->cfg.AMR_mode_change_period);
                fprintf(trace, ">\n");
                DumpBox(a, trace);
-               fprintf(trace, "</AMRConfigurationBox>\n");
+               gf_box_dump_done("AMRConfigurationBox", a, trace);
                break;
        case GF_ISOM_SUBTYPE_3GP_EVRC:
                fprintf(trace, "<EVRCConfigurationBox Vendor=\"%s\" Version=\"%d\" FramesPerSample=\"%d\" >\n", name, p->cfg.decoder_version, p->cfg.frames_per_sample);
                DumpBox(a, trace);
-               fprintf(trace, "</EVRCConfigurationBox>\n");
+               gf_box_dump_done("EVRCConfigurationBox", a, trace);
                break;
        case GF_ISOM_SUBTYPE_3GP_QCELP:
                fprintf(trace, "<QCELPConfigurationBox Vendor=\"%s\" Version=\"%d\" FramesPerSample=\"%d\" >\n", name, p->cfg.decoder_version, p->cfg.frames_per_sample);
                DumpBox(a, trace);
-               fprintf(trace, "</QCELPConfigurationBox>\n");
+               gf_box_dump_done("QCELPConfigurationBox", a, trace);
                break;
        case GF_ISOM_SUBTYPE_3GP_SMV:
                fprintf(trace, "<SMVConfigurationBox Vendor=\"%s\" Version=\"%d\" FramesPerSample=\"%d\" >\n", name, p->cfg.decoder_version, p->cfg.frames_per_sample);
                DumpBox(a, trace);
-               fprintf(trace, "</SMVConfigurationBox>\n");
+               gf_box_dump_done("SMVConfigurationBox", a, trace);
                break;
        case GF_ISOM_SUBTYPE_3GP_H263:
                fprintf(trace, "<H263ConfigurationBox Vendor=\"%s\" Version=\"%d\"", name, p->cfg.decoder_version);
                fprintf(trace, " Profile=\"%d\" Level=\"%d\"", p->cfg.H263_profile, p->cfg.H263_level);
                fprintf(trace, ">\n");
                DumpBox(a, trace);
-               fprintf(trace, "</H263ConfigurationBox>\n");
+               gf_box_dump_done("H263ConfigurationBox", a, trace);
                break;
        default:
                break;
@@ -1553,25 +1633,49 @@ GF_Err avcc_dump(GF_Box *a, FILE * trace)
 
        if (p->type==GF_ISOM_BOX_TYPE_SVCC) 
                fprintf(trace, " complete_representation=\"%d\"", p->config->complete_representation);
+
+       if (p->type==GF_ISOM_BOX_TYPE_AVCC) {
+               switch (p->config->AVCProfileIndication) {
+               case 100:
+               case 110:
+               case 122:
+               case 144:
+                       fprintf(trace, " chroma_format=\"%d\" luma_bit_depth=\"%d\" chroma_bit_depth=\"%d\"", p->config->chroma_format, p->config->luma_bit_depth, p->config->chroma_bit_depth);
+                       break;
+               }
+       }
+
        fprintf(trace, ">\n");
 
        count = gf_list_count(p->config->sequenceParameterSets);
        for (i=0; i<count; i++) {
                GF_AVCConfigSlot *c = (GF_AVCConfigSlot *)gf_list_get(p->config->sequenceParameterSets, i);
-               fprintf(trace, "<sequenceParameterSet size=\"%d\" content=\"", c->size);
+               fprintf(trace, "<SequenceParameterSet size=\"%d\" content=\"", c->size);
                DumpData(trace, c->data, c->size);
                fprintf(trace, "\"/>\n");
        }
        count = gf_list_count(p->config->pictureParameterSets);
        for (i=0; i<count; i++) {
                GF_AVCConfigSlot *c = (GF_AVCConfigSlot *)gf_list_get(p->config->pictureParameterSets, i);
-               fprintf(trace, "<pictureParameterSet size=\"%d\" content=\"", c->size);
+               fprintf(trace, "<PictureParameterSet size=\"%d\" content=\"", c->size);
                DumpData(trace, c->data, c->size);
                fprintf(trace, "\"/>\n");
        }
+
+       if (p->config->sequenceParameterSetExtensions) {
+               count = gf_list_count(p->config->sequenceParameterSetExtensions);
+               for (i=0; i<count; i++) {
+                       GF_AVCConfigSlot *c = (GF_AVCConfigSlot *)gf_list_get(p->config->sequenceParameterSetExtensions, i);
+                       fprintf(trace, "<SequenceParameterSetExtensions size=\"%d\" content=\"", c->size);
+                       DumpData(trace, c->data, c->size);
+                       fprintf(trace, "\"/>\n");
+               }
+       }
+
        fprintf(trace, "</%sDecoderConfigurationRecord>\n", name);
 
        DumpBox(a, trace);
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%sConfigurationBox>\n", name);
        return GF_OK;
 }
@@ -1592,7 +1696,7 @@ GF_Err m4ds_dump(GF_Box *a, FILE * trace)
 #endif
        }
        DumpBox(a, trace);
-       fprintf(trace, "</MPEG4ExtensionDescriptorsBox>\n");
+       gf_box_dump_done("MPEG4ExtensionDescriptorsBox", a, trace);
        return GF_OK;
 }
 
@@ -1601,7 +1705,7 @@ GF_Err btrt_dump(GF_Box *a, FILE * trace)
        GF_MPEG4BitRateBox *p = (GF_MPEG4BitRateBox*)a;
        fprintf(trace, "<MPEG4BitRateBox BufferSizeDB=\"%d\" avgBitRate=\"%d\" maxBitRate=\"%d\">\n", p->bufferSizeDB, p->avgBitrate, p->maxBitrate);
        DumpBox(a, trace);
-       fprintf(trace, "</MPEG4BitRateBox>\n");
+       gf_box_dump_done("MPEG4BitRateBox", a, trace);
        return GF_OK;
 }
 
@@ -1614,7 +1718,7 @@ GF_Err ftab_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->entry_count; i++) {
                fprintf(trace, "<FontRecord ID=\"%d\" name=\"%s\"/>\n", p->fonts[i].fontID, p->fonts[i].fontName ? p->fonts[i].fontName : "NULL");
        }
-       fprintf(trace, "</FontTableBox>\n");
+       gf_box_dump_done("FontTableBox", a, trace);
        return GF_OK;
 }
 
@@ -1657,12 +1761,12 @@ GF_Err tx3g_dump(GF_Box *a, FILE * trace)
 
        fprintf(trace, "<DefaultBox>\n");
        gpp_dump_box(trace, &p->default_box);
-       fprintf(trace, "</DefaultBox>\n");
+       gf_box_dump_done("DefaultBox", a, trace);
        fprintf(trace, "<DefaultStyle>\n");
        gpp_dump_style(trace, &p->default_style);
        fprintf(trace, "</DefaultStyle>\n");
        gf_box_dump(p->font_table, trace);
-       fprintf(trace, "</Tx3gSampleEntryBox>\n");
+       gf_box_dump_done("Tx3gSampleEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -1680,8 +1784,8 @@ GF_Err text_dump(GF_Box *a, FILE * trace)
 
        fprintf(trace, "<DefaultBox>\n");
        gpp_dump_box(trace, &p->default_box);
-       fprintf(trace, "</DefaultBox>\n");
-       fprintf(trace, "</TextSampleEntryBox>\n");
+       gf_box_dump_done("DefaultBox", a, trace);
+       gf_box_dump_done("TextSampleEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -1692,7 +1796,7 @@ GF_Err styl_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<TextStyleBox>\n");
        DumpBox(a, trace);
        for (i=0; i<p->entry_count; i++) gpp_dump_style(trace, &p->styles[i]);
-       fprintf(trace, "</TextStyleBox>\n");
+       gf_box_dump_done("TextStyleBox", a, trace);
        return GF_OK;
 }
 GF_Err hlit_dump(GF_Box *a, FILE * trace)
@@ -1700,17 +1804,17 @@ GF_Err hlit_dump(GF_Box *a, FILE * trace)
        GF_TextHighlightBox*p = (GF_TextHighlightBox*)a;
        fprintf(trace, "<TextHighlightBox startcharoffset=\"%d\" endcharoffset=\"%d\">\n", p->startcharoffset, p->endcharoffset);
        DumpBox(a, trace);
-       fprintf(trace, "</TextHighlightBox>\n");
+       gf_box_dump_done("TextHighlightBox", a, trace);
        return GF_OK;
 }
 GF_Err hclr_dump(GF_Box *a, FILE * trace)
 {
        GF_TextHighlightColorBox*p = (GF_TextHighlightColorBox*)a;
-       fprintf(trace, "<TextHighlightBox ");
+       fprintf(trace, "<TextHighlightColorBox ");
        gpp_dump_rgba8(trace, "highlight_color", p->hil_color);
        fprintf(trace, ">\n");
        DumpBox(a, trace);
-       fprintf(trace, "</TextHighlightBox>\n");
+       gf_box_dump_done("TextHighlightColorBox", a, trace);
        return GF_OK;
 }
 
@@ -1723,7 +1827,7 @@ GF_Err krok_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->nb_entries; i++) {
                fprintf(trace, "<KaraokeRecord highlight_endtime=\"%d\" start_charoffset=\"%d\" end_charoffset=\"%d\"/>\n", p->records[i].highlight_endtime, p->records[i].start_charoffset, p->records[i].end_charoffset);
        }
-       fprintf(trace, "</TextKaraokeBox>\n");
+       gf_box_dump_done("TextKaraokeBox", a, trace);
        return GF_OK;
 }
 GF_Err dlay_dump(GF_Box *a, FILE * trace)
@@ -1731,7 +1835,7 @@ GF_Err dlay_dump(GF_Box *a, FILE * trace)
        GF_TextScrollDelayBox*p = (GF_TextScrollDelayBox*)a;
        fprintf(trace, "<TextScrollDelayBox scroll_delay=\"%d\">\n", p->scroll_delay);
        DumpBox(a, trace);
-       fprintf(trace, "</TextScrollDelayBox>\n");
+       gf_box_dump_done("TextScrollDelayBox", a, trace);
        return GF_OK;
 }
 GF_Err href_dump(GF_Box *a, FILE * trace)
@@ -1739,7 +1843,7 @@ GF_Err href_dump(GF_Box *a, FILE * trace)
        GF_TextHyperTextBox*p = (GF_TextHyperTextBox*)a;
        fprintf(trace, "<TextHyperTextBox startcharoffset=\"%d\" startcharoffset=\"%d\" URL=\"%s\" altString=\"%s\">\n", p->startcharoffset, p->endcharoffset, p->URL ? p->URL : "NULL", p->URL_hint ? p->URL_hint : "NULL");
        DumpBox(a, trace);
-       fprintf(trace, "</TextHyperTextBox>\n");
+       gf_box_dump_done("TextHyperTextBox", a, trace);
        return GF_OK;
 }
 GF_Err tbox_dump(GF_Box *a, FILE * trace)
@@ -1748,7 +1852,7 @@ GF_Err tbox_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<TextBoxBox>\n");
        gpp_dump_box(trace, &p->box);
        DumpBox(a, trace);
-       fprintf(trace, "</TextBoxBox>\n");
+       gf_box_dump_done("TextBoxBox", a, trace);
        return GF_OK;
 }
 GF_Err blnk_dump(GF_Box *a, FILE * trace)
@@ -1756,7 +1860,7 @@ GF_Err blnk_dump(GF_Box *a, FILE * trace)
        GF_TextBlinkBox*p = (GF_TextBlinkBox*)a;
        fprintf(trace, "<TextBlinkBox start_charoffset=\"%d\" end_charoffset=\"%d\">\n", p->startcharoffset, p->endcharoffset);
        DumpBox(a, trace);
-       fprintf(trace, "</TextBlinkBox>\n");
+       gf_box_dump_done("TextBlinkBox", a, trace);
        return GF_OK;
 }
 GF_Err twrp_dump(GF_Box *a, FILE * trace)
@@ -1764,7 +1868,7 @@ GF_Err twrp_dump(GF_Box *a, FILE * trace)
        GF_TextWrapBox*p = (GF_TextWrapBox*)a;
        fprintf(trace, "<TextWrapBox wrap_flag=\"%s\">\n", p->wrap_flag ? ( (p->wrap_flag>1) ? "Reserved" : "Automatic" ) : "No Wrap");
        DumpBox(a, trace);
-       fprintf(trace, "</TextWrapBox>\n");
+       gf_box_dump_done("TextWrapBox", a, trace);
        return GF_OK;
 }
 
@@ -1784,9 +1888,7 @@ GF_Err meta_dump(GF_Box *a, FILE * trace)
        if (p->protections) gf_box_dump(p->protections, trace);
        if (p->item_infos) gf_box_dump(p->item_infos, trace);
        if (p->IPMP_control) gf_box_dump(p->IPMP_control, trace);
-
-       gf_box_array_dump(p->other_boxes, trace);
-       fprintf(trace, "</MetaBox>\n");
+       gf_box_dump_done("MetaBox", a, trace);
        return GF_OK;
 }
 
@@ -1800,7 +1902,7 @@ GF_Err xml_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<![CDATA[\n");
        gf_fwrite(p->xml, p->xml_length, 1, trace);
        fprintf(trace, "]]>\n");
-       fprintf(trace, "</XMLBox>\n");
+       gf_box_dump_done("XMLBox", a, trace);
        return GF_OK;
 }
 
@@ -1811,7 +1913,7 @@ GF_Err bxml_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<BinaryXMLBox binarySize=\"%d\">\n", p->data_length);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</BinaryXMLBox>\n");
+       gf_box_dump_done("BinaryXMLBox", a, trace);
        return GF_OK;
 }
 
@@ -1822,7 +1924,7 @@ GF_Err pitm_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<PrimaryItemBox item_ID=\"%d\">\n", p->item_ID);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</PrimaryItemBox>\n");
+       gf_box_dump_done("PrimaryItemBox", a, trace);
        return GF_OK;
 }
 
@@ -1833,7 +1935,7 @@ GF_Err ipro_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
        gf_box_array_dump(p->protection_information, trace);
-       fprintf(trace, "</ItemProtectionBox>\n");
+       gf_box_dump_done("ItemProtectionBox", a, trace);
        return GF_OK;
 }
 
@@ -1843,7 +1945,7 @@ GF_Err infe_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<ItemInfoEntryBox item_ID=\"%d\" item_protection_index=\"%d\" item_name=\"%s\" content_type=\"%s\" content_encoding=\"%s\">\n", p->item_ID, p->item_protection_index, p->item_name, p->content_type, p->content_encoding);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</ItemInfoEntryBox>\n");
+       gf_box_dump_done("ItemInfoEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -1854,7 +1956,7 @@ GF_Err iinf_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
        gf_box_array_dump(p->item_infos, trace);
-       fprintf(trace, "</ItemInfoBox>\n");
+       gf_box_dump_done("ItemInfoBox", a, trace);
        return GF_OK;
 }
 
@@ -1875,31 +1977,26 @@ GF_Err iloc_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, "<ItemExtentEntry extent_offset=\""LLD"\" extent_length=\""LLD"\" />\n", LLD_CAST iee->extent_offset, LLD_CAST iee->extent_length);
                }
        }
-       fprintf(trace, "</ItemLocationBox>\n");
+       gf_box_dump_done("ItemLocationBox", a, trace);
        return GF_OK;
 }
 
 
 GF_Err hinf_dump(GF_Box *a, FILE * trace)
 {
-       GF_HintInfoBox *p;
-
-       p = (GF_HintInfoBox *)a;
+//     GF_HintInfoBox *p  = (GF_HintInfoBox *)a;
        fprintf(trace, "<HintInfoBox>\n");
        DumpBox(a, trace);
-       gf_box_array_dump(p->boxList, trace);
-       fprintf(trace, "</HintInfoBox>\n");
+       gf_box_dump_done("HintInfoBox", a, trace);
        return GF_OK;
 }
 
 GF_Err trpy_dump(GF_Box *a, FILE * trace)
 {
-       GF_TRPYBox *p;
-
-       p = (GF_TRPYBox *)a;
+       GF_TRPYBox *p = (GF_TRPYBox *)a;
        fprintf(trace, "<LargeTotalRTPBytesBox RTPBytesSent=\""LLD"\">\n", LLD_CAST p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</LargeTotalRTPBytesBox>\n");
+       gf_box_dump_done("LargeTotalRTPBytesBox", a, trace);
        return GF_OK;
 }
 
@@ -1910,7 +2007,7 @@ GF_Err totl_dump(GF_Box *a, FILE * trace)
        p = (GF_TOTLBox *)a;
        fprintf(trace, "<TotalRTPBytesBox RTPBytesSent=\"%d\">\n", p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</TotalRTPBytesBox>\n");
+       gf_box_dump_done("TotalRTPBytesBox", a, trace);
        return GF_OK;
 }
 
@@ -1921,7 +2018,7 @@ GF_Err nump_dump(GF_Box *a, FILE * trace)
        p = (GF_NUMPBox *)a;
        fprintf(trace, "<LargeTotalPacketBox PacketsSent=\""LLD"\">\n", LLD_CAST p->nbPackets);
        DumpBox(a, trace);
-       fprintf(trace, "</LargeTotalPacketBox>\n");
+       gf_box_dump_done("LargeTotalPacketBox", a, trace);
        return GF_OK;
 }
 
@@ -1932,7 +2029,7 @@ GF_Err npck_dump(GF_Box *a, FILE * trace)
        p = (GF_NPCKBox *)a;
        fprintf(trace, "<TotalPacketBox packetsSent=\"%d\">\n", p->nbPackets);
        DumpBox(a, trace);
-       fprintf(trace, "</TotalPacketBox>\n");
+       gf_box_dump_done("TotalPacketBox", a, trace);
        return GF_OK;
 }
 
@@ -1943,7 +2040,7 @@ GF_Err tpyl_dump(GF_Box *a, FILE * trace)
        p = (GF_NTYLBox *)a;
        fprintf(trace, "<LargeTotalMediaBytesBox BytesSent=\""LLD"\">\n", LLD_CAST p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</LargeTotalMediaBytesBox>\n");
+       gf_box_dump_done("LargeTotalMediaBytesBox", a, trace);
        return GF_OK;
 }
 
@@ -1954,7 +2051,7 @@ GF_Err tpay_dump(GF_Box *a, FILE * trace)
        p = (GF_TPAYBox *)a;
        fprintf(trace, "<TotalMediaBytesBox BytesSent=\"%d\">\n", p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</TotalMediaBytesBox>\n");
+       gf_box_dump_done("TotalMediaBytesBox", a, trace);
        return GF_OK;
 }
 
@@ -1964,7 +2061,7 @@ GF_Err maxr_dump(GF_Box *a, FILE * trace)
        p = (GF_MAXRBox *)a;
        fprintf(trace, "<MaxDataRateBox MaxDataRate=\"%d\" Granularity=\"%d\">\n", p->maxDataRate, p->granularity);
        DumpBox(a, trace);
-       fprintf(trace, "</MaxDataRateBox>\n");
+       gf_box_dump_done("MaxDataRateBox", a, trace);
        return GF_OK;
 }
 
@@ -1975,7 +2072,7 @@ GF_Err dmed_dump(GF_Box *a, FILE * trace)
        p = (GF_DMEDBox *)a;
        fprintf(trace, "<BytesFromMediaTrackBox BytesSent=\""LLD"\">\n", LLD_CAST p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</BytesFromMediaTrackBox>\n");
+       gf_box_dump_done("BytesFromMediaTrackBox", a, trace);
        return GF_OK;
 }
 
@@ -1986,7 +2083,7 @@ GF_Err dimm_dump(GF_Box *a, FILE * trace)
        p = (GF_DIMMBox *)a;
        fprintf(trace, "<ImmediateDataBytesBox BytesSent=\""LLD"\">\n", LLD_CAST p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</ImmediateDataBytesBox>\n");
+       gf_box_dump_done("ImmediateDataBytesBox", a, trace);
        return GF_OK;
 }
 
@@ -1997,7 +2094,7 @@ GF_Err drep_dump(GF_Box *a, FILE * trace)
        p = (GF_DREPBox *)a;
        fprintf(trace, "<RepeatedDataBytesBox RepeatedBytes=\""LLD"\">\n", LLD_CAST p->nbBytes);
        DumpBox(a, trace);
-       fprintf(trace, "</RepeatedDataBytesBox>\n");
+       gf_box_dump_done("RepeatedDataBytesBox", a, trace);
        return GF_OK;
 }
 
@@ -2008,7 +2105,7 @@ GF_Err tmin_dump(GF_Box *a, FILE * trace)
        p = (GF_TMINBox *)a;
        fprintf(trace, "<MinTransmissionTimeBox MinimumTransmitTime=\"%d\">\n", p->minTime);
        DumpBox(a, trace);
-       fprintf(trace, "</MinTransmissionTimeBox>\n");
+       gf_box_dump_done("MinTransmissionTimeBox", a, trace);
        return GF_OK;
 }
 
@@ -2019,7 +2116,7 @@ GF_Err tmax_dump(GF_Box *a, FILE * trace)
        p = (GF_TMAXBox *)a;
        fprintf(trace, "<MaxTransmissionTimeBox MaximumTransmitTime=\"%d\">\n", p->maxTime);
        DumpBox(a, trace);
-       fprintf(trace, "</MaxTransmissionTimeBox>\n");
+       gf_box_dump_done("MaxTransmissionTimeBox", a, trace);
        return GF_OK;
 }
 
@@ -2030,7 +2127,7 @@ GF_Err pmax_dump(GF_Box *a, FILE * trace)
        p = (GF_PMAXBox *)a;
        fprintf(trace, "<MaxPacketSizeBox MaximumSize=\"%d\">\n", p->maxSize);
        DumpBox(a, trace);
-       fprintf(trace, "</MaxPacketSizeBox>\n");
+       gf_box_dump_done("MaxPacketSizeBox", a, trace);
        return GF_OK;
 }
 
@@ -2041,7 +2138,7 @@ GF_Err dmax_dump(GF_Box *a, FILE * trace)
        p = (GF_DMAXBox *)a;
        fprintf(trace, "<MaxPacketDurationBox MaximumDuration=\"%d\">\n", p->maxDur);
        DumpBox(a, trace);
-       fprintf(trace, "</MaxPacketDurationBox>\n");
+       gf_box_dump_done("MaxPacketDurationBox", a, trace);
        return GF_OK;
 }
 
@@ -2052,7 +2149,7 @@ GF_Err payt_dump(GF_Box *a, FILE * trace)
        p = (GF_PAYTBox *)a;
        fprintf(trace, "<PayloadTypeBox PayloadID=\"%d\" PayloadString=\"%s\">\n", p->payloadCode, p->payloadString);
        DumpBox(a, trace);
-       fprintf(trace, "</PayloadTypeBox>\n");
+       gf_box_dump_done("PayloadTypeBox", a, trace);
        return GF_OK;
 }
 
@@ -2063,7 +2160,7 @@ GF_Err name_dump(GF_Box *a, FILE * trace)
        p = (GF_NameBox *)a;
        fprintf(trace, "<NameBox Name=\"%s\">\n", p->string);
        DumpBox(a, trace);
-       fprintf(trace, "</NameBox>\n");
+       gf_box_dump_done("NameBox", a, trace);
        return GF_OK;
 }
 
@@ -2074,7 +2171,7 @@ GF_Err rely_dump(GF_Box *a, FILE * trace)
        p = (GF_RelyHintBox *)a;
        fprintf(trace, "<RelyTransmissionBox Prefered=\"%d\" required=\"%d\">\n", p->prefered, p->required);
        DumpBox(a, trace);
-       fprintf(trace, "</RelyTransmissionBox>\n");
+       gf_box_dump_done("RelyTransmissionBox", a, trace);
        return GF_OK;
 }
 
@@ -2085,7 +2182,7 @@ GF_Err snro_dump(GF_Box *a, FILE * trace)
        p = (GF_SeqOffHintEntryBox *)a;
        fprintf(trace, "<PacketSequenceOffsetBox SeqNumOffset=\"%d\">\n", p->SeqOffset);
        DumpBox(a, trace);
-       fprintf(trace, "</PacketSequenceOffsetBox>\n");
+       gf_box_dump_done("PacketSequenceOffsetBox", a, trace);
        return GF_OK;
 }
 
@@ -2096,7 +2193,7 @@ GF_Err tims_dump(GF_Box *a, FILE * trace)
        p = (GF_TSHintEntryBox *)a;
        fprintf(trace, "<RTPTimeScaleBox TimeScale=\"%d\">\n", p->timeScale);
        DumpBox(a, trace);
-       fprintf(trace, "</RTPTimeScaleBox>\n");
+       gf_box_dump_done("RTPTimeScaleBox", a, trace);
        return GF_OK;
 }
 
@@ -2107,7 +2204,7 @@ GF_Err tsro_dump(GF_Box *a, FILE * trace)
        p = (GF_TimeOffHintEntryBox *)a;
        fprintf(trace, "<TimeStampOffsetBox TimeStampOffset=\"%d\">\n", p->TimeOffset);
        DumpBox(a, trace);
-       fprintf(trace, "</TimeStampOffsetBox>\n");
+       gf_box_dump_done("TimeStampOffsetBox", a, trace);
        return GF_OK;
 }
 
@@ -2122,7 +2219,7 @@ GF_Err ghnt_dump(GF_Box *a, FILE * trace)
 
        DumpBox(a, trace);
        gf_box_array_dump(p->HintDataTable, trace);
-       fprintf(trace, "</GenericHintSampleEntryBox>\n");
+       gf_box_dump_done("GenericHintSampleEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -2138,17 +2235,17 @@ GF_Err hnti_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
 
        i=0;
-       while ((ptr = (GF_Box *)gf_list_enum(p->boxList, &i))) {
+       while ((ptr = (GF_Box *)gf_list_enum(p->other_boxes, &i))) {
                if (ptr->type !=GF_ISOM_BOX_TYPE_RTP) {
                        gf_box_dump(ptr, trace);
                } else {
                        rtp = (GF_RTPBox *)ptr;
                        fprintf(trace, "<RTPInfoBox subType=\"%s\">\n", gf_4cc_to_str(rtp->subType));
                        fprintf(trace, "<!-- sdp text: %s -->\n", rtp->sdpText);
-                       fprintf(trace, "</RTPInfoBox>\n");
+                       gf_box_dump_done("RTPInfoBox", a, trace);
                }
        }
-       fprintf(trace, "</HintTrackInfoBox>\n");
+       gf_box_dump_done("HintTrackInfoBox", NULL, trace);
        return GF_OK;
 }
 
@@ -2160,7 +2257,7 @@ GF_Err sdp_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<SDPBox>\n");
        DumpBox(a, trace);
        fprintf(trace, "<!-- sdp text: %s -->\n", p->sdpText);
-       fprintf(trace, "</SDPBox>\n");
+       gf_box_dump_done("SDPBox", a, trace);
        return GF_OK;
 }
 
@@ -2171,7 +2268,7 @@ GF_Err rtpo_dump(GF_Box *a, FILE * trace)
        p = (GF_RTPOBox *)a;
        fprintf(trace, "<RTPTimeOffsetBox PacketTimeOffset=\"%d\">\n", p->timeOffset);
        DumpBox(a, trace);
-       fprintf(trace, "</RTPTimeOffsetBox>\n");
+       gf_box_dump_done("RTPTimeOffsetBox", a, trace);
        return GF_OK;
 }
 
@@ -2188,7 +2285,7 @@ GF_Err mvex_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        if (p->mehd) gf_box_dump(p->mehd, trace);
        gf_box_array_dump(p->TrackExList, trace);
-       fprintf(trace, "</MovieExtendsBox>\n");
+       gf_box_dump_done("MovieExtendsBox", a, trace);
        return GF_OK;
 }
 
@@ -2198,7 +2295,7 @@ GF_Err mehd_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<MovieExtendsHeaderBox fragmentDuration=\""LLD"\" >\n", LLD_CAST p->fragment_duration);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</MovieExtendsHeaderBox>\n");
+       gf_box_dump_done("MovieExtendsHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -2216,7 +2313,7 @@ GF_Err trex_dump(GF_Box *a, FILE * trace)
        fprintf(trace, ">\n");
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</TrackExtendsBox>\n");
+       gf_box_dump_done("TrackExtendsBox", a, trace);
        return GF_OK;
 }
 
@@ -2230,7 +2327,7 @@ GF_Err moof_dump(GF_Box *a, FILE * trace)
 
        if (p->mfhd) gf_box_dump(p->mfhd, trace);
        gf_box_array_dump(p->TrackList, trace);
-       fprintf(trace, "</MovieFragmentBox>\n");
+       gf_box_dump_done("MovieFragmentBox", a, trace);
        return GF_OK;
 }
 
@@ -2242,7 +2339,7 @@ GF_Err mfhd_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<MovieFragmentHeaderBox FragmentSequenceNumber=\"%d\">\n", p->sequence_number);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</MovieFragmentHeaderBox>\n");
+       gf_box_dump_done("MovieFragmentHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -2260,7 +2357,8 @@ GF_Err traf_dump(GF_Box *a, FILE * trace)
        if (p->sampleGroupsDescription) gf_box_array_dump(p->sampleGroupsDescription, trace);
        if (p->sampleGroups) gf_box_array_dump(p->sampleGroups, trace);
        gf_box_array_dump(p->TrackRuns, trace);
-       fprintf(trace, "</TrackFragmentBox>\n");
+       if (p->piff_sample_encryption) gf_box_dump(p->piff_sample_encryption, trace);
+       gf_box_dump_done("TrackFragmentBox", a, trace);
        return GF_OK;
 }
 
@@ -2271,9 +2369,8 @@ GF_Err tfhd_dump(GF_Box *a, FILE * trace)
        p = (GF_TrackFragmentHeaderBox *)a;
        fprintf(trace, "<TrackFragmentHeaderBox TrackID=\"%d\"", p->trackID);
 
-       if (p->flags & GF_ISOM_TRAF_BASE_OFFSET) {
-               fprintf(trace, " BaseDataOffset=\""LLD"\"", LLD_CAST p->base_data_offset);
-       }
+       fprintf(trace, " BaseDataOffset=\"%s\"", (p->flags & GF_ISOM_MOOF_BASE_OFFSET) ? "moof" : ((p->flags & GF_ISOM_TRAF_BASE_OFFSET) ? "traf" : "file") );
+
        if (p->flags & GF_ISOM_TRAF_SAMPLE_DESC)
                fprintf(trace, " SampleDescriptionIndex=\"%d\"", p->sample_desc_index);
        if (p->flags & GF_ISOM_TRAF_SAMPLE_DUR)
@@ -2285,11 +2382,12 @@ GF_Err tfhd_dump(GF_Box *a, FILE * trace)
                fprintf(trace, " SampleSync=\"%d\"", GF_ISOM_GET_FRAG_SYNC(p->def_sample_flags));
                fprintf(trace, " SampleDegradationPriority=\"%d\"", GF_ISOM_GET_FRAG_DEG(p->def_sample_flags));
        }
+
        fprintf(trace, ">\n");
 
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</TrackFragmentHeaderBox>\n");
+       gf_box_dump_done("TrackFragmentHeaderBox", a, trace);
        return GF_OK;
 }
 
@@ -2333,7 +2431,7 @@ GF_Err trun_dump(GF_Box *a, FILE * trace)
        } else {
                fprintf(trace, "<!-- all default values used -->\n");
        }
-       fprintf(trace, "</TrackRunBox>\n");
+       gf_box_dump_done("TrackRunBox", a, trace);
        return GF_OK;
 }
 
@@ -2537,7 +2635,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum
                return GF_BAD_PARAM;
        }
 
-       txt = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0);
+       txt = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, 0);
        switch (txt->type) {
        case GF_ISOM_BOX_TYPE_TX3G:
                break;
@@ -2556,9 +2654,9 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum
 #endif
        fprintf(dump, "<TextStreamHeader width=\"%d\" height=\"%d\" layer=\"%d\" translation_x=\"%d\" translation_y=\"%d\">\n", trak->Header->width >> 16 , trak->Header->height >> 16, trak->Header->layer, trak->Header->matrix[6] >> 16, trak->Header->matrix[7] >> 16);
 
-       nb_descs = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       nb_descs = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        for (i=0; i<nb_descs; i++) {
-               GF_Tx3gSampleEntryBox *txt = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, i);
+               GF_Tx3gSampleEntryBox *txt = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, i);
 
                fprintf(dump, "<TextSampleDescription horizontalJustification=\"");
                switch (txt->horizontal_justification) {
@@ -2818,6 +2916,8 @@ static GF_Err gf_isom_dump_srt_track(GF_ISOFile *the_file, u32 track, FILE *dump
                                end = next->DTS;
                                gf_isom_sample_del(&next);
                        }
+               } else {
+                       end = gf_isom_get_media_duration(the_file, track) ;
                }
                cur_frame++;
                fprintf(dump, "%d\n", cur_frame);
@@ -2830,7 +2930,7 @@ static GF_Err gf_isom_dump_srt_track(GF_ISOFile *the_file, u32 track, FILE *dump
                txt = gf_isom_parse_texte_sample(bs);
                gf_bs_del(bs);
 
-               txtd = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, di-1);
+               txtd = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, di-1);
 
                if (!txt->len) {
                        fprintf(dump, "\n");
@@ -3034,7 +3134,7 @@ GF_Err sinf_dump(GF_Box *a, FILE * trace)
        gf_box_dump(p->original_format, trace);
        gf_box_dump(p->scheme_type, trace);
        gf_box_dump(p->info, trace);
-       fprintf(trace, "</ProtectionInfoBox>\n");
+       gf_box_dump_done("ProtectionInfoBox", a, trace);
        return GF_OK;
 }
 
@@ -3044,7 +3144,7 @@ GF_Err frma_dump(GF_Box *a, FILE * trace)
        p = (GF_OriginalFormatBox *)a;
        fprintf(trace, "<OriginalFormatBox data_format=\"%s\">\n", gf_4cc_to_str(p->data_format));
        DumpBox(a, trace);
-       fprintf(trace, "</OriginalFormatBox>\n");
+       gf_box_dump_done("OriginalFormatBox", a, trace);
        return GF_OK;
 }
 
@@ -3058,7 +3158,7 @@ GF_Err schm_dump(GF_Box *a, FILE * trace)
 
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</SchemeTypeBox>\n");
+       gf_box_dump_done("SchemeTypeBox", a, trace);
        return GF_OK;
 }
 
@@ -3071,7 +3171,8 @@ GF_Err schi_dump(GF_Box *a, FILE * trace)
        if (p->ikms) gf_box_dump(p->ikms, trace);
        if (p->isfm) gf_box_dump(p->isfm, trace);
        if (p->okms) gf_box_dump(p->okms, trace);
-       fprintf(trace, "</SchemeInformationBox>\n");
+       if (p->tenc) gf_box_dump(p->tenc, trace);
+       gf_box_dump_done("SchemeInformationBox", a, trace);
        return GF_OK;
 }
 
@@ -3083,7 +3184,7 @@ GF_Err iKMS_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
-       fprintf(trace, "</ISMAKMSBox>\n");
+       gf_box_dump_done("ISMAKMSBox", a, trace);
        return GF_OK;
 
 }
@@ -3097,6 +3198,7 @@ GF_Err iSFM_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
 
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%s>\n", name);
        return GF_OK;
 }
@@ -3238,7 +3340,7 @@ static GF_Err apple_tag_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, " IsGapeless=\"%s\" ", itune->data->data[0] ? "yes" : "no");
                        break;
                default:
-                       if (strcmp(name, "Unknown")) {
+                       if (strcmp(name, "Unknown") && itune->data->data) {
                                if (itune->data && itune->data->data[0]) {
                                        fprintf(trace, " value=\"%s\" ", itune->data->data);
                                } else {
@@ -3254,10 +3356,121 @@ static GF_Err apple_tag_dump(GF_Box *a, FILE * trace)
        if (itune->data)
                gf_full_box_dump((GF_Box *)itune->data, trace);
        DumpBox(a, trace);
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%sBox>\n", name);
        return GF_OK;
 }
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+
+GF_Err abst_dump(GF_Box *a, FILE * trace)
+{
+       u32 i;
+       GF_AdobeBootstrapInfoBox *p = (GF_AdobeBootstrapInfoBox*)a;
+       fprintf(trace, "<AdobeBootstrapBox BootstrapinfoVersion=\"%u\" Profile=\"%u\" Live=\"%u\" Update=\"%u\" TimeScale=\"%u\" CurrentMediaTime=\""LLU"\" SmpteTimeCodeOffset=\""LLU"\" ",
+               p->bootstrapinfo_version, p->profile, p->live, p->update, p->time_scale, p->current_media_time, p->smpte_time_code_offset);
+       if (p->movie_identifier)
+               fprintf(trace, "MovieIdentifier=\"%s\" ", p->movie_identifier);
+       if (p->drm_data)
+               fprintf(trace, "DrmData=\"%s\" ", p->drm_data);
+       if (p->meta_data)
+               fprintf(trace, "MetaData=\"%s\" ", p->meta_data);
+       fprintf(trace, ">\n");
+       DumpBox(a, trace);
+       gf_full_box_dump(a, trace);
+
+       for (i=0; i<p->server_entry_count; i++) {
+               char *str = (char*)gf_list_get(p->server_entry_table, i);
+               fprintf(trace, "<ServerEntry>%s</ServerEntry>\n", str);
+       }
+
+       for (i=0; i<p->quality_entry_count; i++) {
+               char *str = (char*)gf_list_get(p->quality_entry_table, i);
+               fprintf(trace, "<QualityEntry>%s</QualityEntry>\n", str);
+       }
+
+       for (i=0; i<p->segment_run_table_count; i++)
+               gf_box_dump(gf_list_get(p->segment_run_table_entries, i), trace);
+
+       for (i=0; i<p->fragment_run_table_count; i++)
+               gf_box_dump(gf_list_get(p->fragment_run_table_entries, i), trace);
+
+       gf_box_dump_done("AdobeBootstrapBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err afra_dump(GF_Box *a, FILE * trace)
+{
+       u32 i;
+       GF_AdobeFragRandomAccessBox *p = (GF_AdobeFragRandomAccessBox*)a;
+       fprintf(trace, "<AdobeFragmentRandomAccessBox LongIDs=\"%u\" LongOffsets=\"%u\" TimeScale=\"%u\">\n", p->long_ids, p->long_offsets, p->time_scale);
+       DumpBox(a, trace);
+       gf_full_box_dump(a, trace);
+
+       for (i=0; i<p->entry_count; i++) {
+               GF_AfraEntry *ae = (GF_AfraEntry *)gf_list_get(p->local_access_entries, i);
+               fprintf(trace, "<LocalAccessEntry Time=\""LLU"\" Offset=\""LLU"\"/>\n", ae->time, ae->offset);
+       }
+
+       for (i=0; i<p->global_entry_count; i++) {
+               GF_GlobalAfraEntry *gae = (GF_GlobalAfraEntry *)gf_list_get(p->global_access_entries, i);
+               fprintf(trace, "<GlobalAccessEntry Time=\""LLU"\" Segment=\"%u\" Fragment=\"%u\" AfraOffset=\""LLU"\" OffsetFromAfra=\""LLU"\"/>\n",
+                               gae->time, gae->segment, gae->fragment, gae->afra_offset, gae->offset_from_afra);
+       }
+
+       gf_box_dump_done("AdobeFragmentRandomAccessBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err afrt_dump(GF_Box *a, FILE * trace)
+{
+       u32 i;
+       GF_AdobeFragmentRunTableBox *p = (GF_AdobeFragmentRunTableBox*)a;
+       fprintf(trace, "<AdobeFragmentRunTableBox TimeScale=\"%u\">\n", p->timescale);
+       DumpBox(a, trace);
+       gf_full_box_dump(a, trace);
+
+       for (i=0; i<p->quality_entry_count; i++) {
+               char *str = (char*)gf_list_get(p->quality_segment_url_modifiers, i);
+               fprintf(trace, "<QualityEntry>%s</QualityEntry>\n", str);
+       }
+
+       for (i=0; i<p->fragment_run_entry_count; i++) {
+               GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(p->fragment_run_entry_table, i);
+               fprintf(trace, "<FragmentRunEntry FirstFragment=\"%u\" FirstFragmentTimestamp=\""LLU"\" FirstFragmentDuration=\"%u\"", fre->first_fragment, fre->first_fragment_timestamp, fre->fragment_duration);
+               if (!fre->fragment_duration)
+                       fprintf(trace, " DiscontinuityIndicator=\"%u\"", fre->discontinuity_indicator);
+               fprintf(trace, "/>\n");
+       }
+
+       gf_box_dump_done("AdobeFragmentRunTableBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err asrt_dump(GF_Box *a, FILE * trace)
+{
+       u32 i;
+       GF_AdobeSegmentRunTableBox *p = (GF_AdobeSegmentRunTableBox*)a;
+       fprintf(trace, "<AdobeSegmentRunTableBox>\n");
+       DumpBox(a, trace);
+       gf_full_box_dump(a, trace);
+       
+       for (i=0; i<p->quality_entry_count; i++) {
+               char *str = (char*)gf_list_get(p->quality_segment_url_modifiers, i);
+               fprintf(trace, "<QualityEntry>%s</QualityEntry>\n", str);
+       }
+
+       for (i=0; i<p->segment_run_entry_count; i++) {
+               GF_AdobeSegmentRunEntry *sre = (GF_AdobeSegmentRunEntry *)gf_list_get(p->segment_run_entry_table, i);
+               fprintf(trace, "<SegmentRunEntry FirstSegment=\"%u\" FragmentsPerSegment=\"%u\"/>\n", sre->first_segment, sre->fragment_per_segment);
+       }
+
+       gf_box_dump_done("AdobeSegmentRunTableBox", a, trace);
+       return GF_OK;
+}
+
+#endif /*GPAC_DISABLE_ISOM_ADOBE*/
+
 GF_Err ilst_dump(GF_Box *a, FILE * trace)
 {
        u32 i;
@@ -3269,11 +3482,11 @@ GF_Err ilst_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
 
        i=0;
-       while ( (tag = gf_list_enum(ptr->tags, &i))) {
+       while ( (tag = gf_list_enum(ptr->other_boxes, &i))) {
                e = apple_tag_dump(tag, trace);
                if(e) return e;
        }
-       fprintf(trace, "</ItemListBox>\n");
+       gf_box_dump_done("ItemListBox", NULL, trace);
        return GF_OK;
 }
 
@@ -3319,8 +3532,7 @@ GF_Err ohdr_dump(GF_Box *a, FILE * trace)
 
        fprintf(trace, ">\n");
        gf_full_box_dump((GF_Box *)a, trace);
-       gf_box_array_dump(ptr->ExtendedHeaders, trace);
-       fprintf(trace, "</OMADRMCommonHeaderBox>\n");
+       gf_box_dump_done("OMADRMCommonHeaderBox", a, trace);
        return GF_OK;
 }
 GF_Err grpi_dump(GF_Box *a, FILE * trace)
@@ -3330,16 +3542,15 @@ GF_Err grpi_dump(GF_Box *a, FILE * trace)
        DumpData(trace, ptr->GroupKey, ptr->GKLength);
        fprintf(trace, ">\n");
        gf_full_box_dump((GF_Box *)a, trace);
-       fprintf(trace, "</OMADRMGroupIDBox>\n");
+       gf_box_dump_done("OMADRMGroupIDBox", a, trace);
        return GF_OK;
 }
 GF_Err mdri_dump(GF_Box *a, FILE * trace)
 {
-       GF_OMADRMMutableInformationBox *ptr = (GF_OMADRMMutableInformationBox*)a;
+       //GF_OMADRMMutableInformationBox *ptr = (GF_OMADRMMutableInformationBox*)a;
        fprintf(trace, "<OMADRMMutableInformationBox>\n");
        gf_box_dump((GF_Box *)a, trace);
-       gf_box_array_dump(ptr->boxes, trace);
-       fprintf(trace, "</OMADRMMutableInformationBox>\n");
+       gf_box_dump_done("OMADRMMutableInformationBox", a, trace);
        return GF_OK;
 }
 GF_Err odtt_dump(GF_Box *a, FILE * trace)
@@ -3349,7 +3560,7 @@ GF_Err odtt_dump(GF_Box *a, FILE * trace)
        DumpData(trace, ptr->TransactionID, 16);
        fprintf(trace, "\">\n");
        gf_full_box_dump((GF_Box *)a, trace);
-       fprintf(trace, "</OMADRMTransactionTrackingBox>\n");
+       gf_box_dump_done("OMADRMTransactionTrackingBox", a, trace);
        return GF_OK;
 }
 GF_Err odrb_dump(GF_Box *a, FILE * trace)
@@ -3359,7 +3570,7 @@ GF_Err odrb_dump(GF_Box *a, FILE * trace)
        DumpData(trace, ptr->oma_ro, ptr->oma_ro_size);
        fprintf(trace, "\">\n");
        gf_full_box_dump((GF_Box *)a, trace);
-       fprintf(trace, "</OMADRMRightsObjectBox>\n");
+       gf_box_dump_done("OMADRMRightsObjectBox", a, trace);
        return GF_OK;
 }
 GF_Err odkm_dump(GF_Box *a, FILE * trace)
@@ -3369,7 +3580,7 @@ GF_Err odkm_dump(GF_Box *a, FILE * trace)
        gf_full_box_dump((GF_Box *)a, trace);
        if (ptr->hdr) gf_box_dump((GF_Box *)ptr->hdr, trace);
        if (ptr->fmt) gf_box_dump((GF_Box *)ptr->fmt, trace);
-       fprintf(trace, "</OMADRMKMSBox>\n");
+       gf_box_dump_done("OMADRMKMSBox", a, trace);
        return GF_OK;
 }
 
@@ -3379,7 +3590,7 @@ GF_Err pasp_dump(GF_Box *a, FILE * trace)
        GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)a;
        fprintf(trace, "<PixelAspectRatioBox hSpacing=\"%d\" vSpacing=\"%d\" >\n", ptr->hSpacing, ptr->vSpacing);
        DumpBox((GF_Box *)a, trace);
-       fprintf(trace, "</PixelAspectRatioBox>\n");
+       gf_box_dump_done("PixelAspectRatioBox", a, trace);
        return GF_OK;
 }
 
@@ -3395,7 +3606,7 @@ GF_Err tsel_dump(GF_Box *a, FILE * trace)
        }
        fprintf(trace, "\">\n");
        gf_full_box_dump((GF_Box *)a, trace);
-       fprintf(trace, "</TrackSelectionBox>\n");
+       gf_box_dump_done("TrackSelectionBox", a, trace);
        return GF_OK;
 }
 
@@ -3416,8 +3627,9 @@ GF_Err metx_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
 
        if (ptr->bitrate) gf_box_dump(ptr->bitrate, trace);
-       if (ptr->protection_info) gf_box_dump(ptr->protection_info, trace);
+       gf_box_array_dump(ptr->protections, trace);
 
+       gf_box_dump_done(NULL, a, trace);
        fprintf(trace, "</%s>\n", name);
        return GF_OK;
 }
@@ -3432,8 +3644,8 @@ GF_Err dims_dump(GF_Box *a, FILE * trace)
        if (p->config) gf_box_dump(p->config, trace);
        if (p->scripts) gf_box_dump(p->scripts, trace);
        if (p->bitrate) gf_box_dump(p->bitrate, trace);
-       if (p->protection_info) gf_box_dump(p->protection_info, trace);
-       fprintf(trace, "</DIMSSampleEntryBox>\n");
+       gf_box_array_dump(p->protections, trace);
+       gf_box_dump_done("DIMSSampleEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -3443,7 +3655,7 @@ GF_Err diST_dump(GF_Box *a, FILE * trace)
 
        fprintf(trace, "<DIMSScriptTypesBox types=\"%s\">\n", p->content_script_types);
        DumpBox(a, trace);
-       fprintf(trace, "</DIMSScriptTypesBox>\n");
+       gf_box_dump_done("DIMSScriptTypesBox", a, trace);
        return GF_OK;
 }
 GF_Err dimC_dump(GF_Box *a, FILE * trace)
@@ -3453,7 +3665,7 @@ GF_Err dimC_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<DIMSSceneConfigBox profile=\"%d\" level=\"%d\" pathComponents=\"%d\" useFullRequestHosts=\"%d\" streamType=\"%d\" containsRedundant=\"%d\" textEncoding=\"%s\" contentEncoding=\"%s\" >\n",
                p->profile, p->level, p->pathComponents, p->fullRequestHost, p->streamType, p->containsRedundant, p->textEncoding, p->contentEncoding);
        DumpBox(a, trace);
-       fprintf(trace, "</DIMSSceneConfigBox>\n");
+       gf_box_dump_done("DIMSSceneConfigBox", a, trace);
        return GF_OK;
 }
 
@@ -3462,22 +3674,43 @@ GF_Err dac3_dump(GF_Box *a, FILE * trace)
 {
        GF_AC3ConfigBox *p = (GF_AC3ConfigBox *)a;
 
-       fprintf(trace, "<AC3SpecificBox fscod=\"%d\" bsid=\"%d\" bsmod=\"%d\" acmod=\"%d\" lfon=\"%d\" bit_rate_code=\"%d\">\n",
-               p->cfg.fscod, p->cfg.bsid, p->cfg.bsmod, p->cfg.acmod, p->cfg.lfon, p->cfg.brcode);
-       DumpBox(a, trace);
-       fprintf(trace, "</AC3SpecificBox>\n");
+       if (p->cfg.is_ec3) {
+               u32 i;
+               fprintf(trace, "<EC3SpecificBox nb_streams=\"%d\" data_rate=\"%d\">\n", p->cfg.nb_streams, p->cfg.brcode);
+               for (i=0; i<p->cfg.nb_streams; i++) {
+                       fprintf(trace, "<EC3StreamConfig fscod=\"%d\" bsid=\"%d\" bsmod=\"%d\" acmod=\"%d\" lfon=\"%d\" num_sub_dep=\"%d\" chan_loc=\"%d\"/>\n",
+                               p->cfg.streams[i].fscod, p->cfg.streams[i].bsid, p->cfg.streams[i].bsmod, p->cfg.streams[i].acmod, p->cfg.streams[i].lfon, p->cfg.streams[i].nb_dep_sub, p->cfg.streams[i].chan_loc);
+               }
+               a->type = GF_ISOM_BOX_TYPE_DEC3;
+               DumpBox(a, trace);
+               a->type = GF_ISOM_BOX_TYPE_DAC3;
+               gf_box_dump_done("EC3SpecificBox", a, trace);
+       } else {
+               fprintf(trace, "<AC3SpecificBox fscod=\"%d\" bsid=\"%d\" bsmod=\"%d\" acmod=\"%d\" lfon=\"%d\" bit_rate_code=\"%d\">\n",
+                       p->cfg.streams[0].fscod, p->cfg.streams[0].bsid, p->cfg.streams[0].bsmod, p->cfg.streams[0].acmod, p->cfg.streams[0].lfon, p->cfg.brcode);
+               DumpBox(a, trace);
+               gf_box_dump_done("AC3SpecificBox", a, trace);
+       }
        return GF_OK;
 }
 
 GF_Err ac3_dump(GF_Box *a, FILE * trace)
 {
        GF_AC3SampleEntryBox *p = (GF_AC3SampleEntryBox *)a;
-       fprintf(trace, "<AC3SampleEntry");
+       if (p->is_ec3)
+               fprintf(trace, "<EC3SampleEntryBox");
+       else
+               fprintf(trace, "<AC3SampleEntryBox");
        base_audio_entry_dump((GF_AudioSampleEntryBox *)p, trace);
        fprintf(trace, ">\n");
+
+       if (p->is_ec3)
+               a->type = GF_ISOM_BOX_TYPE_EC3;
        DumpBox(a, trace);
+       if (p->is_ec3)
+               a->type = GF_ISOM_BOX_TYPE_AC3;
        gf_box_dump(p->info, trace);
-       fprintf(trace, "</AC3SampleEntry>\n");
+       gf_box_dump_done(p->is_ec3 ? "EC3SampleEntryBox" : "AC3SampleEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -3489,19 +3722,19 @@ GF_Err lsrc_dump(GF_Box *a, FILE * trace)
        dump_data(trace, "LASeRHeader", p->hdr, p->hdr_size);
        fprintf(trace, ">");
        DumpBox(a, trace);
-       fprintf(trace, "</LASeRConfigurationBox>");
+       gf_box_dump_done("LASeRConfigurationBox", a, trace);
        return GF_OK;
 }
 
 GF_Err lsr1_dump(GF_Box *a, FILE * trace)
 {
        GF_LASeRSampleEntryBox *p = (GF_LASeRSampleEntryBox*)a;
-       fprintf(trace, "<LASeRSampleEntry DataReferenceIndex=\"%d\">\n", p->dataReferenceIndex);
+       fprintf(trace, "<LASeRSampleEntryBox DataReferenceIndex=\"%d\">\n", p->dataReferenceIndex);
        DumpBox(a, trace);
        if (p->lsr_config) gf_box_dump(p->lsr_config, trace);
        if (p->bitrate) gf_box_dump(p->bitrate, trace);
        if (p->descr) gf_box_dump(p->descr, trace);
-       fprintf(trace, "</LASeRSampleEntry>\n");
+       gf_box_dump_done("LASeRSampleEntryBox", a, trace);
        return GF_OK;
 }
 
@@ -3517,7 +3750,7 @@ GF_Err sidx_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->nb_refs; i++) {
                fprintf(trace, "<Reference type=\"%d\" size=\"%d\" duration=\"%d\" startsWithSAP=\"%d\" SAP_type=\"%d\" SAPDeltaTime=\"%d\"/>\n", p->refs[i].reference_type, p->refs[i].reference_size, p->refs[i].subsegment_duration, p->refs[i].starts_with_SAP, p->refs[i].SAP_type, p->refs[i].SAP_delta_time);
        }
-       fprintf(trace, "</SegmentIndexBox>\n");
+       gf_box_dump_done("SegmentIndexBox", a, trace);
        return GF_OK;
 }
 
@@ -3531,7 +3764,7 @@ GF_Err pcrb_dump(GF_Box *a, FILE * trace)
        for (i=0; i<p->subsegment_count; i++) {
                fprintf(trace, "<PCRInfo PCR=\""LLU"\" />\n", p->pcr_values[i]);
        }
-       fprintf(trace, "</MPEG2TSPCRInfoBox>\n");
+       gf_box_dump_done("MPEG2TSPCRInfoBox", a, trace);
        return GF_OK;
 }
 
@@ -3539,7 +3772,7 @@ GF_Err subs_dump(GF_Box *a, FILE * trace)
 {
        u32 entry_count, i, j;
        u16 subsample_count;
-       GF_SampleEntry *pSamp;
+       GF_SubSampleInfoEntry *pSamp;
        GF_SubSampleEntry *pSubSamp;
        GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) a;
 
@@ -3550,7 +3783,7 @@ GF_Err subs_dump(GF_Box *a, FILE * trace)
        DumpBox(a, trace);
 
        for (i=0; i<entry_count; i++) {
-               pSamp = (GF_SampleEntry*) gf_list_get(ptr->Samples, i);
+               pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
 
                subsample_count = gf_list_count(pSamp->SubSamples);
 
@@ -3563,7 +3796,7 @@ GF_Err subs_dump(GF_Box *a, FILE * trace)
                fprintf(trace, "</SampleEntry>\n");
        } 
 
-       fprintf(trace, "</SubSampleInformationBox>\n");
+       gf_box_dump_done("SubSampleInformationBox", a, trace);
        return GF_OK;
 }
 
@@ -3576,7 +3809,7 @@ GF_Err tfdt_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "<TrackFragmentBaseMediaDecodeTimeBox baseMediaDecodeTime=\""LLD"\">\n", ptr->baseMediaDecodeTime);
        DumpBox(a, trace);
        gf_full_box_dump(a, trace);
-       fprintf(trace, "</TrackFragmentBaseMediaDecodeTimeBox>\n");
+       gf_box_dump_done("TrackFragmentBaseMediaDecodeTimeBox", a, trace);
        return GF_OK;
 }
 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
@@ -3590,7 +3823,7 @@ GF_Err rvcc_dump(GF_Box *a, FILE * trace)
        if (! ptr->predefined_rvc_config) fprintf(trace, " rvc_meta_idx=\"%d\"", ptr->rvc_meta_idx);
        fprintf(trace, ">\n");
        DumpBox(a, trace);
-       fprintf(trace, "</RVCConfigurationBox>\n");
+       gf_box_dump_done("RVCConfigurationBox", a, trace);
        return GF_OK;
 }
 
@@ -3608,7 +3841,7 @@ GF_Err sbgp_dump(GF_Box *a, FILE * trace)
        for (i=0; i<ptr->entry_count; i++) {
                fprintf(trace, "<SampleGroupBoxEntry sample_count=\"%d\" group_description_index=\"%d\"/>\n", ptr->sample_entries[i].sample_count, ptr->sample_entries[i].group_description_index );
        }
-       fprintf(trace, "</SampleGroupBox>\n");
+       gf_box_dump_done("SampleGroupBox", a, trace);
        return GF_OK;
 }
 
@@ -3640,7 +3873,172 @@ GF_Err sgpd_dump(GF_Box *a, FILE * trace)
                        fprintf(trace, "\"/>\n");
                }
        }
-       fprintf(trace, "</SampleGroupDescriptionBox>\n");
+       gf_box_dump_done("SampleGroupDescriptionBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err saiz_dump(GF_Box *a, FILE * trace)
+{
+       u32 i;
+       GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<SampleAuxiliaryInfoSizeBox default_sample_info_size=\"%d\" sample_count=\"%d\"", ptr->default_sample_info_size, ptr->sample_count);
+       if (ptr->flags & 1) fprintf(trace, " aux_info_type=\"%d\" aux_info_type_parameter=\"%d\"", ptr->aux_info_type, ptr->aux_info_type_parameter);
+       fprintf(trace, ">\n");
+       DumpBox(a, trace);
+       gf_full_box_dump((GF_Box *)a, trace);
+       if (ptr->default_sample_info_size==0) {
+               for (i=0; i<ptr->sample_count; i++) {
+                       fprintf(trace, "<SAISize size=\"%d\" />\n", ptr->sample_info_size[i]);
+               }
+       }
+       gf_box_dump_done("SampleAuxiliaryInfoSizeBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err saio_dump(GF_Box *a, FILE * trace)
+{
+       u32 i;
+       GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<SampleAuxiliaryInfoOffsetBox entry_count=\"%d\"", ptr->entry_count);
+       if (ptr->flags & 1) fprintf(trace, " aux_info_type=\"%d\" aux_info_type_parameter=\"%d\"", ptr->aux_info_type, ptr->aux_info_type_parameter);
+       fprintf(trace, ">\n");
+       DumpBox(a, trace);
+       gf_full_box_dump((GF_Box *)a, trace);
+
+       if (ptr->single_offset) {
+               fprintf(trace, "<SAIChunkOffset offset=\""LLD"\"/>\n", ptr->single_offset);
+       } else if (ptr->version==0) {
+               for (i=0; i<ptr->entry_count; i++) {
+                       fprintf(trace, "<SAIChunkOffset offset=\"%d\"/>\n", ptr->offsets[i]);
+               }
+       } else {
+               for (i=0; i<ptr->entry_count; i++) {
+                       fprintf(trace, "<SAIChunkOffset offset=\""LLD"\"/>\n", ptr->offsets_large[i]);
+               }
+       }
+       gf_box_dump_done("SampleAuxiliaryInfoOffsetBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err pssh_dump(GF_Box *a, FILE * trace)
+{
+       GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<ProtectionSystemHeaderBox SystemID=\"");
+       DumpData(trace, ptr->SystemID, 16);
+       fprintf(trace, "\">\n");
+       DumpBox(a, trace);
+       gf_full_box_dump((GF_Box *)a, trace);
+
+       if (ptr->KID_count) {
+               u32 i;
+               for (i=0; i<ptr->KID_count; i++) {
+                       fprintf(trace, " <PSSHKey KID=\"");
+                       DumpData(trace, ptr->KIDs[i], 16);
+                       fprintf(trace, "\"/>\n");
+               }
+       }
+       if (ptr->private_data_size) {
+               fprintf(trace, " <PSSHData size=\"%d\" value=\"", ptr->private_data_size);
+               DumpData(trace, ptr->private_data, ptr->private_data_size);
+               fprintf(trace, "\"/>\n");
+       }
+       gf_box_dump_done("ProtectionSystemHeaderBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err tenc_dump(GF_Box *a, FILE * trace)
+{
+       GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<TrackEncryptionBox isEncrypted=\"%d\" IV_size=\"%d\" KID=\"", ptr->IsEncrypted, ptr->IV_size);
+       DumpData(trace, ptr->KID, 16);
+       fprintf(trace, "\">\n");
+       DumpBox(a, trace);
+       gf_full_box_dump((GF_Box *)a, trace);
+       gf_box_dump_done("TrackEncryptionBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err piff_pssh_dump(GF_Box *a, FILE * trace)
+{
+       GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<PIFFProtectionSystemHeaderBox SystemID=\"");
+       DumpDataHex(trace, ptr->SystemID, 16);
+       fprintf(trace, "\" PrivateData=\"");
+       DumpDataHex(trace, ptr->private_data, ptr->private_data_size);
+       fprintf(trace, "\">\n");
+       DumpBox(a, trace);
+       fprintf(trace, "<FullBoxInfo Version=\"%d\" Flags=\"%d\"/>\n", ptr->version, ptr->flags);
+       gf_box_dump_done("PIFFProtectionSystemHeaderBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err piff_tenc_dump(GF_Box *a, FILE * trace)
+{
+       GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<PIFFTrackEncryptionBox AlgorithmID=\"%d\" IV_size=\"%d\" KID=\"", ptr->AlgorithmID, ptr->IV_size);
+       DumpData(trace, ptr->KID, 16);
+       fprintf(trace, "\">\n");
+       DumpBox(a, trace);
+       fprintf(trace, "<FullBoxInfo Version=\"%d\" Flags=\"%d\"/>\n", ptr->version, ptr->flags);
+       gf_box_dump_done("PIFFTrackEncryptionBox", a, trace);
+       return GF_OK;
+}
+
+GF_Err piff_psec_dump(GF_Box *a, FILE * trace)
+{
+       u32 IV_size = 0;
+       GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *) a;
+       if (!a) return GF_BAD_PARAM;
+
+       fprintf(trace, "<PIFFSampleEncryptionBox sampleCount=\"%d\"", ptr->sample_count);
+       if (ptr->flags & 1) {
+               fprintf(trace, " default_AlgorithmID=\"%d\" IV_size=\"%d\" KID=\"", ptr->AlgorithmID, ptr->IV_size);
+               DumpData(trace, ptr->KID, 16);
+               fprintf(trace, "\"");
+               IV_size = 0;
+       }
+       fprintf(trace, ">\n");
+       DumpBox(a, trace);
+       if (ptr->cenc_data) {
+               u32 i, j;
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
+               for (i=0; i<ptr->sample_count; i++) {
+                       GF_CENCSampleInfo *cenc_sample = gf_isom_cenc_get_sample(ptr->traf->trex->track, ptr->traf, i+1);
+
+                       if (cenc_sample) {
+                               fprintf(trace, "<PIFFSampleEncryptionEntry IV=\"");
+                               DumpDataHex(trace, cenc_sample->IV, IV_size);
+                               fprintf(trace, "\" SubsampleCount=\"%d\"", cenc_sample->subsample_count);
+                               if (cenc_sample->is_alt_info) {
+                                       fprintf(trace, " AlgorithmID=\"%d\" IV_size=\"%d\" KID=\"", cenc_sample->algo_id, cenc_sample->IV_size);
+                                       DumpDataHex(trace, cenc_sample->keyID, 16);
+                                       fprintf(trace, "\"");
+                               }
+                               fprintf(trace, ">\n");
+                               
+                               for (j=0; j<cenc_sample->subsample_count; j++) {
+                                       fprintf(trace, "<PIFFSubSampleEncryptionEntry NumClearBytes=\"%d\" NumEncryptedBytes=\"%d\"/>\n", cenc_sample->subsamples[j].bytes_clear_data, cenc_sample->subsamples[j].bytes_encrypted_data);
+                               }
+                               fprintf(trace, "</PIFFSampleEncryptionEntry>\n");
+       
+                               gf_isom_cenc_sample_del(cenc_sample);
+                       }
+               }
+#endif //      GPAC_DISABLE_ISOM_FRAGMENTS
+       }
+       gf_box_dump_done("PIFFSampleEncryptionBox", a, trace);
        return GF_OK;
 }
 
index 5af31e276005391d814341b8c8bd809b19a9360e..ac7c77438a626f4c6953db3a8b3010fe98f8b7de 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -51,10 +52,32 @@ GF_Err gf_isom_parse_root_box(GF_Box **outBox, GF_BitStream *bs, u64 *bytesExpec
        return ret;
 }
 
+u32 gf_isom_solve_uuid_box(char *UUID)
+{
+       u32 i;
+       char strUUID[33], strChar[3];
+       strUUID[0] = 0;
+       for (i=0; i<16; i++) {
+               sprintf(strChar, "%02X", (unsigned char) UUID[i]);
+               strcat(strUUID, strChar);
+       }
+       if (!strnicmp(strUUID, "8974dbce7be74c5184f97148f9882554", 32)) 
+               return GF_ISOM_BOX_UUID_TENC;
+       if (!strnicmp(strUUID, "D4807EF2CA3946958E5426CB9E46A79F", 32)) 
+               return GF_ISOM_BOX_UUID_TFRF;
+       if (!strnicmp(strUUID, "6D1D9B0542D544E680E2141DAFF757B2", 32)) 
+               return GF_ISOM_BOX_UUID_TFXD;
+       if (!strnicmp(strUUID, "A2394F525A9B4F14A2446C427C648DF4", 32)) 
+               return GF_ISOM_BOX_UUID_PSEC;
+       if (!strnicmp(strUUID, "D08A4F1810F34A82B6C832D8ABA183D3", 32)) 
+               return GF_ISOM_BOX_UUID_PSSH;
+       return 0;
+}
+
 
 GF_Err gf_isom_parse_box_ex(GF_Box **outBox, GF_BitStream *bs, u32 parent_type)
 {
-       u32 type, hdr_size;
+       u32 type, uuid_type, hdr_size;
        u64 size, start, end;
        char uuid[16];
        GF_Err e;
@@ -65,6 +88,7 @@ GF_Err gf_isom_parse_box_ex(GF_Box **outBox, GF_BitStream *bs, u32 parent_type)
 
        start = gf_bs_get_position(bs);
 
+       uuid_type = 0;
        size = (u64) gf_bs_read_u32(bs);
        hdr_size = 4;
        /*fix for some boxes found in some old hinted files*/
@@ -99,6 +123,7 @@ proceed_box:
        if (type == GF_ISOM_BOX_TYPE_UUID ) {
                gf_bs_read_data(bs, uuid, 16);
                hdr_size += 16;
+               uuid_type = gf_isom_solve_uuid_box(uuid);
        }
        
        //handle large box
@@ -119,12 +144,15 @@ proceed_box:
                ((GF_TrackReferenceTypeBox*)newBox)->reference_type = type;
        } else {
                //OK, create the box based on the type
-               newBox = gf_isom_box_new(type);
+               newBox = gf_isom_box_new(uuid_type ? uuid_type : type);
                if (!newBox) return GF_OUT_OF_MEM;
        }
 
        //OK, init and read this box
-       if (type==GF_ISOM_BOX_TYPE_UUID) memcpy(((GF_UUIDBox *)newBox)->uuid, uuid, 16);
+       if (type==GF_ISOM_BOX_TYPE_UUID) {
+               memcpy(((GF_UUIDBox *)newBox)->uuid, uuid, 16);
+               ((GF_UnknownUUIDBox *)newBox)->internal_4cc = uuid_type;
+       }
 
        if (!newBox->type) newBox->type = type; 
 
@@ -181,6 +209,7 @@ GF_Err gf_isom_full_box_read(GF_Box *ptr, GF_BitStream *bs)
        return GF_OK;
 }
 
+/*
 void gf_isom_full_box_init(GF_Box *a)
 {
        GF_FullBox *ptr = (GF_FullBox *)a;
@@ -188,19 +217,19 @@ void gf_isom_full_box_init(GF_Box *a)
        ptr->flags = 0;
        ptr->version = 0;
 }
+*/
 
-
-void gf_isom_box_array_del(GF_List *boxList)
+void gf_isom_box_array_del(GF_List *other_boxes)
 {
        u32 count, i;
        GF_Box *a;
-       if (!boxList) return;
-       count = gf_list_count(boxList); 
+       if (!other_boxes) return;
+       count = gf_list_count(other_boxes); 
        for (i = 0; i < count; i++) {
-               a = (GF_Box *)gf_list_get(boxList, i);
+               a = (GF_Box *)gf_list_get(other_boxes, i);
                if (a) gf_isom_box_del(a);
        }
-       gf_list_del(boxList);
+       gf_list_del(other_boxes);
 }
 
 GF_Err gf_isom_read_box_list_ex(GF_Box *parent, GF_BitStream *bs, GF_Err (*add_box)(GF_Box *par, GF_Box *b), u32 parent_type)
@@ -372,6 +401,7 @@ GF_Box *gf_isom_box_new(u32 boxType)
        case GF_ISOM_BOX_TYPE_STSD: return stsd_New();
        case GF_ISOM_BOX_TYPE_STTS: return stts_New();
        case GF_ISOM_BOX_TYPE_CTTS: return ctts_New();
+       case GF_ISOM_BOX_TYPE_CSLG: return cslg_New();
        case GF_ISOM_BOX_TYPE_STSH: return stsh_New();
        case GF_ISOM_BOX_TYPE_ELST: return elst_New();
        case GF_ISOM_BOX_TYPE_STSC: return stsc_New();
@@ -396,12 +426,16 @@ GF_Box *gf_isom_box_new(u32 boxType)
         a = ftyp_New();
         if (a) a->type = boxType;
         return a;
-       case GF_ISOM_BOX_TYPE_FADB: return padb_New();
+       case GF_ISOM_BOX_TYPE_PADB: return padb_New();
        case GF_ISOM_BOX_TYPE_VOID: return void_New();
        case GF_ISOM_BOX_TYPE_STSF: return stsf_New();
        case GF_ISOM_BOX_TYPE_PDIN: return pdin_New();
        case GF_ISOM_BOX_TYPE_SBGP: return sbgp_New();
        case GF_ISOM_BOX_TYPE_SGPD: return sgpd_New();
+       case GF_ISOM_BOX_TYPE_SAIZ: return saiz_New();
+       case GF_ISOM_BOX_TYPE_SAIO: return saio_New();
+       case GF_ISOM_BOX_TYPE_PSSH: return pssh_New();
+       case GF_ISOM_BOX_TYPE_TENC: return tenc_New();
 
 #ifndef GPAC_DISABLE_ISOM_HINTING
        case GF_ISOM_BOX_TYPE_RTP_STSD:
@@ -508,7 +542,22 @@ GF_Box *gf_isom_box_new(u32 boxType)
        case GF_ISOM_BOX_TYPE_ENCA: return enca_New();
        case GF_ISOM_BOX_TYPE_ENCV: return encv_New();
        case GF_ISOM_BOX_TYPE_ENCS: return encs_New();
-       case GF_ISOM_BOX_TYPE_UUID: return uuid_New();
+
+       case GF_ISOM_BOX_UUID_TENC: return piff_tenc_New();
+       case GF_ISOM_BOX_UUID_PSEC: return piff_psec_New();
+       case GF_ISOM_BOX_UUID_PSSH: return piff_pssh_New();
+       case GF_ISOM_BOX_UUID_TFRF: 
+       case GF_ISOM_BOX_UUID_TFXD: 
+       case GF_ISOM_BOX_TYPE_UUID: 
+               return uuid_New();
+
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /* Adobe extensions */
+       case GF_ISOM_BOX_TYPE_ABST: return abst_New();
+       case GF_ISOM_BOX_TYPE_AFRA: return afra_New();
+       case GF_ISOM_BOX_TYPE_ASRT: return asrt_New();
+       case GF_ISOM_BOX_TYPE_AFRT: return afrt_New();
+#endif
 
        /* Apple extensions */
        case GF_ISOM_BOX_TYPE_ILST: return ilst_New();
@@ -561,8 +610,12 @@ GF_Box *gf_isom_box_new(u32 boxType)
        case GF_ISOM_BOX_TYPE_METT:
                return metx_New(boxType);
 
-       case GF_ISOM_BOX_TYPE_AC3: return ac3_New();
-       case GF_ISOM_BOX_TYPE_DAC3: return dac3_New();
+       case GF_ISOM_BOX_TYPE_AC3: 
+       case GF_ISOM_BOX_TYPE_EC3: 
+               return ac3_New(boxType);
+       case GF_ISOM_BOX_TYPE_DAC3: 
+       case GF_ISOM_BOX_TYPE_DEC3: 
+               return dac3_New(boxType);
        
        case GF_ISOM_BOX_TYPE_LSRC: return lsrc_New();
        case GF_ISOM_BOX_TYPE_LSR1: return lsr1_New();
@@ -582,11 +635,24 @@ GF_Box *gf_isom_box_new(u32 boxType)
        }
 }
 
+GF_EXPORT
+GF_Err gf_isom_box_add_default(GF_Box *a, GF_Box *subbox)
+{
+       if (!a->other_boxes) {
+               a->other_boxes = gf_list_new();
+               if (!a->other_boxes) return GF_OUT_OF_MEM;
+       }
+       return gf_list_add(a->other_boxes, subbox);
+}
 
 GF_EXPORT
 void gf_isom_box_del(GF_Box *a)
 {
        if (!a) return;
+       if (a->other_boxes) {
+               gf_isom_box_array_del(a->other_boxes);
+               a->other_boxes = NULL;
+       }
        switch (a->type) {
        case GF_ISOM_BOX_TYPE_REFT:
                reftype_del(a);
@@ -632,6 +698,7 @@ void gf_isom_box_del(GF_Box *a)
        case GF_ISOM_BOX_TYPE_STSD: stsd_del(a); return;
        case GF_ISOM_BOX_TYPE_STTS: stts_del(a); return;
        case GF_ISOM_BOX_TYPE_CTTS: ctts_del(a); return;
+       case GF_ISOM_BOX_TYPE_CSLG: cslg_del(a); return;
        case GF_ISOM_BOX_TYPE_STSH: stsh_del(a); return;
        case GF_ISOM_BOX_TYPE_ELST: elst_del(a); return;
        case GF_ISOM_BOX_TYPE_STSC: stsc_del(a); return;
@@ -653,12 +720,16 @@ void gf_isom_box_del(GF_Box *a)
        case GF_ISOM_BOX_TYPE_STYP: 
         ftyp_del(a); 
         return;
-       case GF_ISOM_BOX_TYPE_FADB: padb_del(a); return;
+       case GF_ISOM_BOX_TYPE_PADB: padb_del(a); return;
        case GF_ISOM_BOX_TYPE_VOID: void_del(a); return;
        case GF_ISOM_BOX_TYPE_STSF: stsf_del(a); return;
        case GF_ISOM_BOX_TYPE_PDIN: pdin_del(a); return;
        case GF_ISOM_BOX_TYPE_SBGP: sbgp_del(a); return;
        case GF_ISOM_BOX_TYPE_SGPD: sgpd_del(a); return;
+       case GF_ISOM_BOX_TYPE_SAIZ: saiz_del(a); return;
+       case GF_ISOM_BOX_TYPE_SAIO: saio_del(a); return;
+       case GF_ISOM_BOX_TYPE_PSSH: pssh_del(a); return;
+       case GF_ISOM_BOX_TYPE_TENC: tenc_del(a); return;
 
 
 #ifndef GPAC_DISABLE_ISOM_HINTING
@@ -762,13 +833,39 @@ void gf_isom_box_del(GF_Box *a)
        case GF_ISOM_BOX_TYPE_ENCA: 
        case GF_ISOM_BOX_TYPE_ENCV:
        case GF_ISOM_BOX_TYPE_ENCS:
-               a->type = ((GF_SampleEntryBox *)a)->protection_info->original_format->data_format;
-               gf_isom_box_del(a); 
+               {
+                       GF_ProtectionInfoBox *sinf = gf_list_get(((GF_SampleEntryBox *)a)->protections, 0);
+                       a->type = sinf->original_format->data_format;
+                       gf_isom_box_del(a); 
+               }
                return;
        case GF_ISOM_BOX_TYPE_UUID:
-               uuid_del(a);
+               switch (((GF_UnknownUUIDBox *)a)->internal_4cc) {
+               case GF_ISOM_BOX_UUID_TENC: 
+                       piff_tenc_del(a);
+                       return; 
+               case GF_ISOM_BOX_UUID_PSEC: 
+                       piff_psec_del(a);
+                       return; 
+               case GF_ISOM_BOX_UUID_PSSH: 
+                       piff_pssh_del(a);
+                       return; 
+               case GF_ISOM_BOX_UUID_TFRF: 
+               case GF_ISOM_BOX_UUID_TFXD: 
+               default:
+                       uuid_del(a);
+                       return;
+               }
                return;
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /* Adobe extensions */
+       case GF_ISOM_BOX_TYPE_ABST: abst_del(a); return;
+       case GF_ISOM_BOX_TYPE_AFRA: afra_del(a); return;
+       case GF_ISOM_BOX_TYPE_ASRT: asrt_del(a); return;
+       case GF_ISOM_BOX_TYPE_AFRT: afrt_del(a); return;
+#endif
+
        /* Apple extensions */
        case GF_ISOM_BOX_TYPE_ILST: ilst_del(a); return;
        
@@ -874,6 +971,7 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_STSD: return stsd_Read(a, bs);
        case GF_ISOM_BOX_TYPE_STTS: return stts_Read(a, bs);
        case GF_ISOM_BOX_TYPE_CTTS: return ctts_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_CSLG: return cslg_Read(a, bs);
        case GF_ISOM_BOX_TYPE_STSH: return stsh_Read(a, bs);
        case GF_ISOM_BOX_TYPE_ELST: return elst_Read(a, bs);
        case GF_ISOM_BOX_TYPE_STSC: return stsc_Read(a, bs);
@@ -894,12 +992,16 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_FTYP: 
        case GF_ISOM_BOX_TYPE_STYP: 
         return ftyp_Read(a, bs);
-       case GF_ISOM_BOX_TYPE_FADB: return padb_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_PADB: return padb_Read(a, bs);
        case GF_ISOM_BOX_TYPE_VOID: return void_Read(a, bs);
        case GF_ISOM_BOX_TYPE_STSF: return stsf_Read(a, bs);
        case GF_ISOM_BOX_TYPE_PDIN: return pdin_Read(a, bs);
        case GF_ISOM_BOX_TYPE_SBGP: return sbgp_Read(a, bs);
        case GF_ISOM_BOX_TYPE_SGPD: return sgpd_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_SAIZ: return saiz_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_SAIO: return saio_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_PSSH: return pssh_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_TENC: return tenc_Read(a, bs);
 
 #ifndef GPAC_DISABLE_ISOM_HINTING
        case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_Read(a, bs);
@@ -1001,8 +1103,25 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_ENCA: return mp4a_Read(a, bs);
        case GF_ISOM_BOX_TYPE_ENCV: return mp4v_Read(a, bs);
        case GF_ISOM_BOX_TYPE_ENCS: return mp4s_Read(a, bs);
-       case GF_ISOM_BOX_TYPE_UUID: return uuid_Read(a, bs);
-       
+       case GF_ISOM_BOX_TYPE_UUID: 
+               switch (((GF_UnknownUUIDBox *)a)->internal_4cc) {
+               case GF_ISOM_BOX_UUID_TENC: return piff_tenc_Read(a, bs); 
+               case GF_ISOM_BOX_UUID_PSEC: return piff_psec_Read(a, bs);
+               case GF_ISOM_BOX_UUID_PSSH: return piff_pssh_Read(a, bs);
+               case GF_ISOM_BOX_UUID_TFRF: 
+               case GF_ISOM_BOX_UUID_TFXD: 
+               default:
+                       return uuid_Read(a, bs);
+               }
+
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /* Adobe extensions */
+       case GF_ISOM_BOX_TYPE_ABST: return abst_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_AFRA: return afra_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_ASRT: return asrt_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_AFRT: return afrt_Read(a, bs);
+#endif
+
        /* Apple extensions */
        case GF_ISOM_BOX_TYPE_ILST: return ilst_Read(a, bs);
 
@@ -1069,8 +1188,7 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
 
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
-GF_EXPORT
-GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
+GF_Err gf_isom_box_write_listing(GF_Box *a, GF_BitStream *bs)
 {
        switch (a->type) {
        case GF_ISOM_BOX_TYPE_REFT:
@@ -1111,6 +1229,7 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_STSD: return stsd_Write(a, bs);
        case GF_ISOM_BOX_TYPE_STTS: return stts_Write(a, bs);
        case GF_ISOM_BOX_TYPE_CTTS: return ctts_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_CSLG: return cslg_Write(a, bs);
        case GF_ISOM_BOX_TYPE_STSH: return stsh_Write(a, bs);
        case GF_ISOM_BOX_TYPE_ELST: return elst_Write(a, bs);
        case GF_ISOM_BOX_TYPE_STSC: return stsc_Write(a, bs);
@@ -1130,12 +1249,16 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_FTYP: 
        case GF_ISOM_BOX_TYPE_STYP: 
         return ftyp_Write(a, bs);
-       case GF_ISOM_BOX_TYPE_FADB: return padb_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_PADB: return padb_Write(a, bs);
        case GF_ISOM_BOX_TYPE_VOID: return void_Write(a, bs);
        case GF_ISOM_BOX_TYPE_STSF: return stsf_Write(a, bs);
        case GF_ISOM_BOX_TYPE_PDIN: return pdin_Write(a, bs);
        case GF_ISOM_BOX_TYPE_SBGP: return sbgp_Write(a, bs);
        case GF_ISOM_BOX_TYPE_SGPD: return sgpd_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_SAIZ: return saiz_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_SAIO: return saio_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_PSSH: return pssh_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_TENC: return tenc_Write(a, bs);
 
 #ifndef GPAC_DISABLE_ISOM_HINTING
        case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_Write(a, bs);
@@ -1237,7 +1360,24 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_ENCA: return mp4a_Write(a, bs);
        case GF_ISOM_BOX_TYPE_ENCV: return mp4v_Write(a, bs);
        case GF_ISOM_BOX_TYPE_ENCS: return mp4s_Write(a, bs);
-       case GF_ISOM_BOX_TYPE_UUID: return uuid_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_UUID: 
+               switch ( ((GF_UnknownUUIDBox *)a)->internal_4cc) {
+               case GF_ISOM_BOX_UUID_TENC: return piff_tenc_Write(a, bs);
+               case GF_ISOM_BOX_UUID_PSEC: return piff_psec_Write(a, bs);
+               case GF_ISOM_BOX_UUID_PSSH: return piff_pssh_Write(a, bs);
+               case GF_ISOM_BOX_UUID_TFRF: 
+               case GF_ISOM_BOX_UUID_TFXD: 
+               default:
+                       return uuid_Write(a, bs);
+               }
+
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /* Adobe extensions */
+       case GF_ISOM_BOX_TYPE_ABST: return abst_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_AFRA: return afra_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_ASRT: return asrt_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_AFRT: return afrt_Write(a, bs);
+#endif
 
        /* Apple extensions */
        case GF_ISOM_BOX_TYPE_ILST: return ilst_Write(a, bs);
@@ -1303,9 +1443,18 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
        }
 }
 
-
 GF_EXPORT
-GF_Err gf_isom_box_size(GF_Box *a)
+GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
+{
+       GF_Err e = gf_isom_box_write_listing(a, bs);
+       if (e) return e;
+       if (a->other_boxes) {
+               return gf_isom_box_array_write(a, a->other_boxes, bs);
+       }
+       return GF_OK;
+}
+
+static GF_Err gf_isom_box_size_listing(GF_Box *a)
 {
        switch (a->type) {
        case GF_ISOM_BOX_TYPE_REFT:
@@ -1346,6 +1495,7 @@ GF_Err gf_isom_box_size(GF_Box *a)
        case GF_ISOM_BOX_TYPE_STSD: return stsd_Size(a);
        case GF_ISOM_BOX_TYPE_STTS: return stts_Size(a);
        case GF_ISOM_BOX_TYPE_CTTS: return ctts_Size(a);
+       case GF_ISOM_BOX_TYPE_CSLG: return cslg_Size(a);
        case GF_ISOM_BOX_TYPE_STSH: return stsh_Size(a);
        case GF_ISOM_BOX_TYPE_ELST: return elst_Size(a);
        case GF_ISOM_BOX_TYPE_STSC: return stsc_Size(a);
@@ -1364,12 +1514,16 @@ GF_Err gf_isom_box_size(GF_Box *a)
        case GF_ISOM_BOX_TYPE_FTYP: 
        case GF_ISOM_BOX_TYPE_STYP: 
         return ftyp_Size(a);
-       case GF_ISOM_BOX_TYPE_FADB: return padb_Size(a);
+       case GF_ISOM_BOX_TYPE_PADB: return padb_Size(a);
        case GF_ISOM_BOX_TYPE_VOID: return void_Size(a);
        case GF_ISOM_BOX_TYPE_STSF: return stsf_Size(a);
        case GF_ISOM_BOX_TYPE_PDIN: return pdin_Size(a);
        case GF_ISOM_BOX_TYPE_SBGP: return sbgp_Size(a);
        case GF_ISOM_BOX_TYPE_SGPD: return sgpd_Size(a);
+       case GF_ISOM_BOX_TYPE_SAIZ: return saiz_Size(a);
+       case GF_ISOM_BOX_TYPE_SAIO: return saio_Size(a);
+       case GF_ISOM_BOX_TYPE_PSSH: return pssh_Size(a);
+       case GF_ISOM_BOX_TYPE_TENC: return tenc_Size(a);
 
 #ifndef GPAC_DISABLE_ISOM_HINTING
        case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_Size(a);
@@ -1471,7 +1625,24 @@ GF_Err gf_isom_box_size(GF_Box *a)
        case GF_ISOM_BOX_TYPE_ENCA: return mp4a_Size(a);
        case GF_ISOM_BOX_TYPE_ENCV: return mp4v_Size(a);
        case GF_ISOM_BOX_TYPE_ENCS: return mp4s_Size(a);
-       case GF_ISOM_BOX_TYPE_UUID: return uuid_Size(a);
+       case GF_ISOM_BOX_TYPE_UUID:
+               switch ( ((GF_UnknownUUIDBox *)a)->internal_4cc) {
+               case GF_ISOM_BOX_UUID_TENC: return piff_tenc_Size(a);
+               case GF_ISOM_BOX_UUID_PSEC: return piff_psec_Size(a);
+               case GF_ISOM_BOX_UUID_PSSH: return piff_pssh_Size(a);
+               case GF_ISOM_BOX_UUID_TFRF: 
+               case GF_ISOM_BOX_UUID_TFXD: 
+               default:
+                       return uuid_Size(a);
+               }
+
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /* Adobe extensions */
+       case GF_ISOM_BOX_TYPE_ABST: return abst_Size(a);
+       case GF_ISOM_BOX_TYPE_AFRA: return afra_Size(a);
+       case GF_ISOM_BOX_TYPE_ASRT: return asrt_Size(a);
+       case GF_ISOM_BOX_TYPE_AFRT: return afrt_Size(a);
+#endif
 
        /* Apple extensions */
        case GF_ISOM_BOX_TYPE_ILST: return ilst_Size(a);
@@ -1536,6 +1707,18 @@ GF_Err gf_isom_box_size(GF_Box *a)
        }
 }
 
+GF_EXPORT
+GF_Err gf_isom_box_size(GF_Box *a)
+{
+       GF_Err e = gf_isom_box_size_listing(a);
+       if (e) return e;
+       if (a->other_boxes) {
+               e = gf_isom_box_array_size(a, a->other_boxes);
+               if (e) return e;
+       }
+       return GF_OK;
+}
+
 #endif /*GPAC_DISABLE_ISOM_WRITE*/ 
 
 #endif /*GPAC_DISABLE_ISOM*/
index ed3e29b445fb0cadd213950b097a4a8caa504e54..68bc03cc59b624042ade1f5cb068d748aa4802c5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
 
 #ifndef GPAC_DISABLE_ISOM
 
+
+static u32 default_write_buffering_size = 0;
+
+GF_EXPORT
+GF_Err gf_isom_set_output_buffering(GF_ISOFile *movie, u32 size)
+{
+       if (!movie) {
+               default_write_buffering_size = size;
+               return GF_OK;
+       }
+       if (!movie->editFileMap) return GF_BAD_PARAM;
+       return gf_bs_set_output_buffering(movie->editFileMap->bs, size);
+}
+
+
 void gf_isom_datamap_del(GF_DataMap *ptr)
 {
        if (!ptr) return;
@@ -52,7 +68,7 @@ void gf_isom_datamap_close(GF_MediaInformationBox *minf)
        GF_DataEntryBox *ent;
        if (!minf || !minf->dataHandler) return;
 
-       ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->boxList, minf->dataEntryIndex - 1);
+       ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->other_boxes, minf->dataEntryIndex - 1);
 
        //if ent NULL, the data entry was not used (should never happen)
        if (ent == NULL) return;
@@ -166,10 +182,10 @@ GF_Err gf_isom_datamap_open(GF_MediaBox *mdia, u32 dataRefIndex, u8 Edit)
 
        minf = mdia->information;
 
-       if (dataRefIndex > gf_list_count(minf->dataInformation->dref->boxList))
+       if (dataRefIndex > gf_list_count(minf->dataInformation->dref->other_boxes))
                return GF_BAD_PARAM;
 
-       ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->boxList, dataRefIndex - 1);
+       ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->other_boxes, dataRefIndex - 1);
        if (ent == NULL) return GF_ISOM_INVALID_MEDIA;
 
        //if the current dataEntry is the desired one, and not self contained, return
@@ -296,6 +312,11 @@ GF_DataMap *gf_isom_fdm_new_temp(const char *sPath)
                gf_free(tmp);
                return NULL;
        }
+
+       if (default_write_buffering_size) {
+               gf_bs_set_output_buffering(tmp->bs, default_write_buffering_size);
+       }
+
        return (GF_DataMap *)tmp;
 }
 
@@ -327,12 +348,22 @@ GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode)
                break;
        ///we open the file in READ/WRITE mode, in case 
        case GF_ISOM_DATA_MAP_WRITE:
+               if (!strcmp(sPath, "std")) {
+                       tmp->stream = stdout;
+                       tmp->is_stdout = 1;
+               }
+
                if (!tmp->stream) tmp->stream = gf_f64_open(sPath, "w+b");
                if (!tmp->stream) tmp->stream = gf_f64_open(sPath, "wb");
                bs_mode = GF_BITSTREAM_WRITE;
                break;
        ///we open the file in CAT mode, in case 
        case GF_ISOM_DATA_MAP_CAT:
+               if (!strcmp(sPath, "std")) {
+                       tmp->stream = stdout;
+                       tmp->is_stdout = 1;
+               }
+
                if (!tmp->stream) tmp->stream = gf_f64_open(sPath, "a+b");
                if (tmp->stream) gf_f64_seek(tmp->stream, 0, SEEK_END);
                bs_mode = GF_BITSTREAM_WRITE;
@@ -351,6 +382,9 @@ GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode)
                gf_free(tmp);
                return NULL;
        }
+       if (default_write_buffering_size) {
+               gf_bs_set_output_buffering(tmp->bs, default_write_buffering_size);
+       }
        return (GF_DataMap *)tmp;
 }
 
@@ -358,7 +392,7 @@ void gf_isom_fdm_del(GF_FileDataMap *ptr)
 {
        if (!ptr || (ptr->type != GF_ISOM_DATA_FILE)) return;
        if (ptr->bs) gf_bs_del(ptr->bs);
-       if (ptr->stream) fclose(ptr->stream);
+       if (ptr->stream && !ptr->is_stdout) fclose(ptr->stream);
 
 #ifndef GPAC_DISABLE_ISOM_WRITE
        if (ptr->temp_file) {
diff --git a/src/isomedia/drm_sample.c b/src/isomedia/drm_sample.c
new file mode 100644 (file)
index 0000000..f94ed33
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ *                     GPAC - Multimedia Framework C SDK
+ *
+ *          Authors: Cyril Concolato / Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
+ *                                     All rights reserved
+ *
+ *  This file is part of GPAC / ISO Media File Format 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. 
+ *
+ */
+
+#include <gpac/internal/isomedia_dev.h>
+
+#ifndef GPAC_DISABLE_ISOM
+
+GF_ISMASample *gf_isom_ismacryp_new_sample()
+{
+       GF_ISMASample *tmp = (GF_ISMASample *) gf_malloc(sizeof(GF_ISMASample));
+       if (!tmp) return NULL;
+       memset(tmp, 0, sizeof(GF_ISMASample));
+       return tmp;
+}
+GF_EXPORT
+void gf_isom_ismacryp_delete_sample(GF_ISMASample *samp)
+{
+       if (!samp) return;
+       if (samp->data && samp->dataLength) gf_free(samp->data);
+       if (samp->key_indicator) gf_free(samp->key_indicator);
+       gf_free(samp);
+}
+
+
+GF_ISMASample *gf_isom_ismacryp_sample_from_data(char *data, u32 dataLength, Bool use_selective_encryption, u8 KI_length, u8 IV_length)
+{
+       GF_ISMASample *s;
+       GF_BitStream *bs;
+       /*empty text sample*/
+       if (!data || !dataLength) {
+               return gf_isom_ismacryp_new_sample();
+       }
+       
+       s = gf_isom_ismacryp_new_sample();
+               
+       /*empty sample*/
+       if (!data || !dataLength) return s;
+
+       bs = gf_bs_new(data, dataLength, GF_BITSTREAM_READ);
+
+       s->dataLength = dataLength;
+       s->IV_length = IV_length;
+       s->KI_length = KI_length;
+
+       if (use_selective_encryption) {
+               s->flags = GF_ISOM_ISMA_USE_SEL_ENC;
+               if (s->dataLength < 1) goto exit;
+               if (gf_bs_read_int(bs, 1)) s->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
+               gf_bs_read_int(bs, 7);
+               s->dataLength -= 1;
+       } else {
+               s->flags = GF_ISOM_ISMA_IS_ENCRYPTED;
+       }
+       if (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) {
+               if (IV_length != 0) {
+                       if (s->dataLength < IV_length) goto exit;
+                       s->IV = gf_bs_read_long_int(bs, 8*IV_length);
+                       s->dataLength -= IV_length;
+               }
+               if (KI_length) {
+                       if (s->dataLength < KI_length) goto exit;
+                       s->key_indicator = (u8 *)gf_malloc(KI_length);
+                       gf_bs_read_data(bs, (char*)s->key_indicator, KI_length);
+                       s->dataLength -= KI_length;
+               }
+       }
+       s->data = (char*)gf_malloc(sizeof(char)*s->dataLength);
+       gf_bs_read_data(bs, s->data, s->dataLength);
+       gf_bs_del(bs);
+       return s;
+
+exit:
+       gf_isom_ismacryp_delete_sample(s);
+       return NULL;
+}
+
+GF_Err gf_isom_ismacryp_sample_to_sample(GF_ISMASample *s, GF_ISOSample *dest)
+{
+       GF_BitStream *bs;
+       if (!s || !dest) return GF_BAD_PARAM;
+
+       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+
+       if (s->flags & GF_ISOM_ISMA_USE_SEL_ENC) {
+               gf_bs_write_int(bs, (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) ? 1 : 0, 1);
+               gf_bs_write_int(bs, 0, 7);
+       } 
+       if (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) {
+               if (s->IV_length) gf_bs_write_long_int(bs, (s64) s->IV, 8*s->IV_length);
+               if (s->KI_length) gf_bs_write_data(bs, (char*)s->key_indicator, s->KI_length);
+       }
+       gf_bs_write_data(bs, s->data, s->dataLength);
+       if (dest->data) gf_free(dest->data);
+       dest->data = NULL;
+       dest->dataLength = 0;
+       gf_bs_get_content(bs, &dest->data, &dest->dataLength);
+       gf_bs_del(bs);
+       return GF_OK;
+}
+
+static GF_ProtectionInfoBox *gf_isom_get_sinf_entry(GF_TrackBox *trak, u32 sampleDescriptionIndex, u32 scheme_type, GF_SampleEntryBox **out_sea)
+{
+       u32 i=0;
+       GF_SampleEntryBox *sea;
+       GF_ProtectionInfoBox *sinf;
+
+       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
+       if (!sea) return NULL;
+
+       i = 0;
+       while ((sinf = gf_list_enum(sea->protections, &i))) {
+               if (sinf->original_format && sinf->scheme_type && sinf->info) {
+                       if (!scheme_type || (sinf->scheme_type->scheme_type == scheme_type)) {
+                               if (out_sea)
+                                       *out_sea = sea;
+                               return sinf;
+                       }
+               }
+       }
+       return NULL;
+}
+
+GF_EXPORT
+GF_ISMASample *gf_isom_get_ismacryp_sample(GF_ISOFile *the_file, u32 trackNumber, GF_ISOSample *samp, u32 sampleDescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_ISMASampleFormatBox *fmt;
+       GF_ProtectionInfoBox *sinf;
+
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return NULL;
+
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, 0, NULL);
+       if (!sinf) return NULL;
+
+       /*ISMA*/
+       if (sinf->scheme_type->scheme_type == GF_ISOM_ISMACRYP_SCHEME) {
+               fmt = sinf->info->isfm;
+               if (!fmt) return NULL;
+               return gf_isom_ismacryp_sample_from_data(samp->data, samp->dataLength, sinf->info->isfm->selective_encryption, sinf->info->isfm->key_indicator_length, sinf->info->isfm->IV_length);
+       }
+       /*OMA*/
+       else if (sinf->scheme_type->scheme_type == GF_4CC('o','d','k','m') ) {
+               if (!sinf->info->okms) return NULL;
+               fmt = sinf->info->okms->fmt;
+
+               if (fmt) {
+                       return gf_isom_ismacryp_sample_from_data(samp->data, samp->dataLength, fmt->selective_encryption, fmt->key_indicator_length, fmt->IV_length);
+               }
+               /*OMA default: no selective encryption, one key, 128 bit IV*/
+               return gf_isom_ismacryp_sample_from_data(samp->data, samp->dataLength, 0, 0, 128);
+       }
+       return NULL;
+}
+
+
+GF_EXPORT
+u32 gf_isom_is_media_encrypted(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_ProtectionInfoBox *sinf;
+
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return 0;
+
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, 0, NULL);
+       if (!sinf) return 0;
+
+       /*non-encrypted or non-ISMA*/
+       if (!sinf || !sinf->scheme_type) return 0;
+       return sinf->scheme_type->scheme_type;
+}
+
+GF_EXPORT
+Bool gf_isom_is_ismacryp_media(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_ProtectionInfoBox *sinf;
+
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return 0;
+
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, GF_ISOM_ISMACRYP_SCHEME, NULL);
+       if (!sinf) return 0;
+
+       /*non-encrypted or non-ISMA*/
+       if (!sinf->info || !sinf->info->ikms || !sinf->info->isfm ) 
+               return 0;
+
+       return 1;
+}
+
+GF_EXPORT
+Bool gf_isom_is_omadrm_media(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_ProtectionInfoBox *sinf;
+
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return 0;
+
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, GF_ISOM_OMADRM_SCHEME, NULL);
+       if (!sinf) return 0;
+
+       /*non-encrypted or non-OMA*/
+       if (!sinf->info || !sinf->info->okms || !sinf->info->okms->hdr) 
+               return 0;
+
+       return 1;
+}
+
+/*retrieves ISMACryp info for the given track & SDI*/
+GF_EXPORT
+GF_Err gf_isom_get_ismacryp_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat, u32 *outSchemeType, u32 *outSchemeVersion, const char **outSchemeURI, const char **outKMS_URI, Bool *outSelectiveEncryption, u32 *outIVLength, u32 *outKeyIndicationLength)
+{
+       GF_TrackBox *trak;
+       GF_ProtectionInfoBox *sinf;
+       
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return GF_BAD_PARAM;
+
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, GF_ISOM_ISMACRYP_SCHEME, NULL);
+       if (!sinf) return 0;
+
+       if (outOriginalFormat) {
+               *outOriginalFormat = sinf->original_format->data_format;
+               if (IsMP4Description(sinf->original_format->data_format)) *outOriginalFormat = GF_ISOM_SUBTYPE_MPEG4;
+       }
+       if (outSchemeType) *outSchemeType = sinf->scheme_type->scheme_type;
+       if (outSchemeVersion) *outSchemeVersion = sinf->scheme_type->scheme_version;
+       if (outSchemeURI) *outSchemeURI = sinf->scheme_type->URI;
+
+       if (sinf->info && sinf->info->ikms) {
+               if (outKMS_URI) *outKMS_URI = sinf->info->ikms->URI;
+       } else {
+               if (outKMS_URI) *outKMS_URI = NULL;
+       }
+       if (sinf->info && sinf->info->isfm) {
+               if (outSelectiveEncryption) *outSelectiveEncryption = sinf->info->isfm->selective_encryption;
+               if (outIVLength) *outIVLength = sinf->info->isfm->IV_length;
+               if (outKeyIndicationLength) *outKeyIndicationLength = sinf->info->isfm->key_indicator_length;
+       } else {
+               if (outSelectiveEncryption) *outSelectiveEncryption = 0;
+               if (outIVLength) *outIVLength = 0;
+               if (outKeyIndicationLength) *outKeyIndicationLength = 0;
+       }
+       return GF_OK;
+}
+
+
+/*retrieves ISMACryp info for the given track & SDI*/
+GF_EXPORT
+GF_Err gf_isom_get_omadrm_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat,
+                                                          u32 *outSchemeType, u32 *outSchemeVersion,
+                                                          const char **outContentID, const char **outRightsIssuerURL, const char **outTextualHeaders, u32 *outTextualHeadersLen, u64 *outPlaintextLength, u32 *outEncryptionType, Bool *outSelectiveEncryption, u32 *outIVLength, u32 *outKeyIndicationLength)
+{
+       GF_TrackBox *trak;
+       GF_ProtectionInfoBox *sinf;
+       
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return GF_BAD_PARAM;
+
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, GF_ISOM_OMADRM_SCHEME, NULL);
+       if (!sinf) return 0;
+
+       if (!sinf->info || !sinf->info->okms || !sinf->info->okms->hdr) return GF_NON_COMPLIANT_BITSTREAM;
+
+       if (outOriginalFormat) {
+               *outOriginalFormat = sinf->original_format->data_format;
+               if (IsMP4Description(sinf->original_format->data_format)) *outOriginalFormat = GF_ISOM_SUBTYPE_MPEG4;
+       }
+       if (outSchemeType) *outSchemeType = sinf->scheme_type->scheme_type;
+       if (outSchemeVersion) *outSchemeVersion = sinf->scheme_type->scheme_version;
+       if (outContentID) *outContentID = sinf->info->okms->hdr->ContentID;
+       if (outRightsIssuerURL) *outRightsIssuerURL = sinf->info->okms->hdr->RightsIssuerURL;
+       if (outTextualHeaders) {
+               *outTextualHeaders = sinf->info->okms->hdr->TextualHeaders;
+               if (outTextualHeadersLen) *outTextualHeadersLen = sinf->info->okms->hdr->TextualHeadersLen;
+       }
+       if (outPlaintextLength) *outPlaintextLength = sinf->info->okms->hdr->PlaintextLength;
+       if (outEncryptionType) *outEncryptionType = sinf->info->okms->hdr->EncryptionMethod;
+
+       if (sinf->info && sinf->info->okms && sinf->info->okms->fmt) {
+               if (outSelectiveEncryption) *outSelectiveEncryption = sinf->info->okms->fmt->selective_encryption;
+               if (outIVLength) *outIVLength = sinf->info->okms->fmt->IV_length;
+               if (outKeyIndicationLength) *outKeyIndicationLength = sinf->info->okms->fmt->key_indicator_length;
+       } else {
+               if (outSelectiveEncryption) *outSelectiveEncryption = 0;
+               if (outIVLength) *outIVLength = 0;
+               if (outKeyIndicationLength) *outKeyIndicationLength = 0;
+       }
+       return GF_OK;
+}
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+GF_Err gf_isom_remove_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
+{
+       GF_TrackBox *trak;
+       GF_Err e;
+       GF_SampleEntryBox *sea;
+       GF_ProtectionInfoBox *sinf;
+
+       e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
+       if (e) return e;
+       
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak || !trak->Media || !sampleDescriptionIndex) return GF_BAD_PARAM;
+
+       sea = NULL;
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, GF_ISOM_ISMACRYP_SCHEME, &sea);
+       if (!sinf) return 0;
+
+       sea->type = sinf->original_format->data_format;
+       gf_isom_box_array_del(sea->protections);
+       sea->protections = gf_list_new();
+       if (sea->type == GF_4CC('2','6','4','b')) sea->type = GF_ISOM_BOX_TYPE_AVC1;
+       return GF_OK;
+}
+
+GF_EXPORT
+GF_Err gf_isom_change_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, char *scheme_uri, char *kms_uri)
+{
+       GF_TrackBox *trak;
+       GF_Err e;
+       GF_SampleEntryBox *sea;
+       GF_ProtectionInfoBox *sinf;
+
+       e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
+       if (e) return e;
+       
+       trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak || !trak->Media || !sampleDescriptionIndex) return GF_BAD_PARAM;
+
+       sea = NULL;
+       sinf = gf_isom_get_sinf_entry(trak, sampleDescriptionIndex, GF_ISOM_ISMACRYP_SCHEME, &sea);
+       if (!sinf) return 0;
+
+       if (scheme_uri) {
+               gf_free(sinf->scheme_type->URI);
+               sinf->scheme_type->URI = gf_strdup(scheme_uri);
+       }
+       if (kms_uri) {
+               gf_free(sinf->info->ikms->URI);
+               sinf->info->ikms->URI = gf_strdup(kms_uri);
+       }
+       return GF_OK;
+}
+
+
+GF_Err gf_isom_set_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 desc_index, u32 scheme_type, 
+                                                  u32 scheme_version, char *scheme_uri, char *kms_URI,
+                                                  Bool selective_encryption, u32 KI_length, u32 IV_length)
+{
+       u32 original_format;
+       GF_Err e;
+       GF_SampleEntryBox *sea;
+       GF_ProtectionInfoBox *sinf;
+       GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return GF_BAD_PARAM;
+
+       e = Media_GetSampleDesc(trak->Media, desc_index, &sea, NULL);
+       if (e) return e;
+
+       /* Replacing the Media Type */
+       switch (sea->type) {
+       case GF_ISOM_BOX_TYPE_MP4A:
+       case GF_ISOM_BOX_TYPE_DAMR:
+       case GF_ISOM_BOX_TYPE_DEVC:
+       case GF_ISOM_BOX_TYPE_DQCP:
+       case GF_ISOM_BOX_TYPE_DSMV:
+       case GF_ISOM_BOX_TYPE_AC3:
+               original_format = sea->type;
+               sea->type = GF_ISOM_BOX_TYPE_ENCA;
+               break;
+       case GF_ISOM_BOX_TYPE_MP4V:
+       case GF_ISOM_BOX_TYPE_D263:
+               original_format = sea->type;
+               sea->type = GF_ISOM_BOX_TYPE_ENCV;
+               break;
+       /*special case for AVC1*/
+       case GF_ISOM_BOX_TYPE_AVC1:
+       case GF_ISOM_BOX_TYPE_AVC2:
+       case GF_ISOM_BOX_TYPE_SVC1:
+               original_format = GF_4CC('2','6','4','b');
+               sea->type = GF_ISOM_BOX_TYPE_ENCV;
+               break;
+       case GF_ISOM_BOX_TYPE_MP4S:
+       case GF_ISOM_BOX_TYPE_LSR1:
+               original_format = sea->type;
+               sea->type = GF_ISOM_BOX_TYPE_ENCS;
+               break;
+       default:
+               return GF_BAD_PARAM;
+       }
+       
+       sinf = (GF_ProtectionInfoBox *)sinf_New();
+       gf_list_add(sea->protections, sinf);
+
+       sinf->scheme_type = (GF_SchemeTypeBox *)schm_New();
+       sinf->scheme_type->scheme_type = scheme_type;
+       sinf->scheme_type->scheme_version = scheme_version;
+       if (scheme_uri) {
+               sinf->scheme_type->flags |= 0x000001;
+               sinf->scheme_type->URI = gf_strdup(scheme_uri);
+       }
+       sinf->original_format = (GF_OriginalFormatBox *)frma_New();
+       sinf->original_format->data_format = original_format;
+       sinf->info = (GF_SchemeInformationBox *)schi_New();
+
+       sinf->info->ikms = (GF_ISMAKMSBox *)iKMS_New();
+       sinf->info->ikms->URI = gf_strdup(kms_URI);
+
+       sinf->info->isfm = (GF_ISMASampleFormatBox *)iSFM_New();
+       sinf->info->isfm->selective_encryption = selective_encryption;
+       sinf->info->isfm->key_indicator_length = KI_length;
+       sinf->info->isfm->IV_length = IV_length;
+       return GF_OK;
+}
+
+GF_Err gf_isom_set_oma_protection(GF_ISOFile *the_file, u32 trackNumber, u32 desc_index,
+                                                  char *contentID, char *kms_URI, u32 encryption_type, u64 plainTextLength, char *textual_headers, u32 textual_headers_len,
+                                                  Bool selective_encryption, u32 KI_length, u32 IV_length)
+{
+       u32 original_format;
+       GF_ProtectionInfoBox *sinf;
+       GF_Err e;
+       GF_SampleEntryBox *sea;
+       GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber);
+       if (!trak) return GF_BAD_PARAM;
+
+       e = Media_GetSampleDesc(trak->Media, desc_index, &sea, NULL);
+       if (e) return e;
+
+       /* Replacing the Media Type */
+       switch (sea->type) {
+       case GF_ISOM_BOX_TYPE_MP4A:
+       case GF_ISOM_BOX_TYPE_DAMR:
+       case GF_ISOM_BOX_TYPE_DEVC:
+       case GF_ISOM_BOX_TYPE_DQCP:
+       case GF_ISOM_BOX_TYPE_DSMV:
+               original_format = sea->type;
+               sea->type = GF_ISOM_BOX_TYPE_ENCA;
+               break;
+       case GF_ISOM_BOX_TYPE_MP4V:
+       case GF_ISOM_BOX_TYPE_AVC1:
+       case GF_ISOM_BOX_TYPE_AVC2:
+       case GF_ISOM_BOX_TYPE_SVC1:
+       case GF_ISOM_BOX_TYPE_D263:
+               original_format = sea->type;
+               sea->type = GF_ISOM_BOX_TYPE_ENCV;
+               break;
+       case GF_ISOM_BOX_TYPE_MP4S:
+       case GF_ISOM_BOX_TYPE_LSR1:
+               original_format = sea->type;
+               sea->type = GF_ISOM_BOX_TYPE_ENCS;
+               break;
+       default:
+               return GF_BAD_PARAM;
+       }
+       
+       sinf = (GF_ProtectionInfoBox *)sinf_New();
+       gf_list_add(sea->protections, sinf);
+       sinf->scheme_type = (GF_SchemeTypeBox *)schm_New();
+       sinf->scheme_type->scheme_type = GF_4CC('o','d','k','m');
+       sinf->scheme_type->scheme_version = 0x00000200;
+
+       sinf->original_format = (GF_OriginalFormatBox *)frma_New();
+       sinf->original_format->data_format = original_format;
+       sinf->info = (GF_SchemeInformationBox *)schi_New();
+
+       sinf->info->okms = (GF_OMADRMKMSBox *)odkm_New();
+       sinf->info->okms->fmt = (GF_OMADRMAUFormatBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_ODAF);
+       sinf->info->okms->fmt->selective_encryption = selective_encryption;
+       sinf->info->okms->fmt->key_indicator_length = KI_length;
+       sinf->info->okms->fmt->IV_length = IV_length;
+
+       sinf->info->okms->hdr = (GF_OMADRMCommonHeaderBox*)ohdr_New();
+       sinf->info->okms->hdr->EncryptionMethod = encryption_type;
+       sinf->info->okms->hdr->PaddingScheme = (encryption_type==0x01) ? 1 : 0;
+       sinf->info->okms->hdr->PlaintextLength = plainTextLength;
+       if (contentID) sinf->info->okms->hdr->ContentID = gf_strdup(contentID);
+       if (kms_URI) sinf->info->okms->hdr->RightsIssuerURL = gf_strdup(kms_URI);
+       if (textual_headers) {
+               sinf->info->okms->hdr->TextualHeaders = gf_malloc(sizeof(char)*textual_headers_len);
+               memcpy(sinf->info->okms->hdr->TextualHeaders, textual_headers, sizeof(char)*textual_headers_len);
+               sinf->info->okms->hdr->TextualHeadersLen = textual_headers_len;
+       }
+       return GF_OK;
+}
+
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
+
+
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
+
+
+void gf_isom_cenc_sample_del(GF_CENCSampleInfo *samp)
+{
+       if (samp->subsamples) gf_free(samp->subsamples);
+       gf_free(samp);
+}
+
+static GF_Err gf_isom_cenc_parse_sample(GF_CENCSampleInfo *cenc_sample, GF_BitStream *bs, u32 sample_number, Bool use_subsample)
+{
+       u32 i=0, k;
+       if ((cenc_sample->IV_size!=0) && (cenc_sample->IV_size!=8) && (cenc_sample->IV_size!=16) ) return GF_ISOM_INVALID_FILE;
+
+       while (gf_bs_available(bs)) {
+               i++;
+               if (i == sample_number) {
+                       gf_bs_read_data(bs, cenc_sample->IV, cenc_sample->IV_size);
+
+                       if (use_subsample) {
+                               cenc_sample->subsample_count = gf_bs_read_u16(bs);
+                               cenc_sample->subsamples = gf_malloc(sizeof(GF_CENCSubSampleEntry)* cenc_sample->subsample_count);
+                               for (k=0; k<cenc_sample->subsample_count; k++) {
+                                       cenc_sample->subsamples[k].bytes_clear_data = gf_bs_read_u16(bs);
+                                       cenc_sample->subsamples[k].bytes_encrypted_data = gf_bs_read_u32(bs);
+                               }
+                       }
+                       return GF_OK;
+               } else {
+                       gf_bs_skip_bytes(bs, cenc_sample->IV_size);
+                       if (use_subsample) {
+                               u32 subcount = gf_bs_read_u16(bs);
+                               gf_bs_skip_bytes(bs, subcount * 6);
+                       }
+               }
+       }
+       return GF_ISOM_INVALID_FILE;
+}
+
+GF_CENCSampleInfo *gf_isom_cenc_get_sample(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u32 sample_number)
+{
+       GF_Err e;
+       Bool use_subsample = 0;
+       GF_CENCSampleInfo *cenc_sample;
+       GF_ProtectionInfoBox *sinf;
+       GF_SampleEntryBox *sentry;
+       u32 sample_desc_idx;
+       GF_BitStream *bs;
+
+       if (!sample_number) return NULL;
+
+       sample_desc_idx = traf->tfhd->sample_desc_index;
+       if (!sample_desc_idx) sample_desc_idx = traf->trex->def_sample_desc_index;
+
+       sentry = gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, sample_desc_idx - 1);
+       sinf = sentry ? gf_list_get(sentry->protections, 0) : NULL;
+
+       /*PIFF*/
+       if (sinf && sinf->scheme_type && sinf->info->piff_tenc) {
+               /*TODO !!*/
+               if (!traf->piff_sample_encryption) return NULL;
+
+               GF_SAFEALLOC(cenc_sample, GF_CENCSampleInfo);
+               memcpy(cenc_sample->keyID, sinf->info->piff_tenc->KID, 16);
+               cenc_sample->IV_size = sinf->info->piff_tenc->IV_size;
+               cenc_sample->algo_id = sinf->info->piff_tenc->AlgorithmID;
+               
+               if (traf->piff_sample_encryption->flags & 1) {
+                       memcpy(cenc_sample->keyID, traf->piff_sample_encryption->KID, 16);
+                       cenc_sample->IV_size = traf->piff_sample_encryption->IV_size;
+                       cenc_sample->algo_id = traf->piff_sample_encryption->AlgorithmID;
+                       cenc_sample->is_alt_info = 1;
+               }
+
+               use_subsample = (traf->piff_sample_encryption->flags & 2) ? 1 : 0;
+
+               bs = gf_bs_new(traf->piff_sample_encryption->cenc_data, traf->piff_sample_encryption->cenc_data_size, GF_BITSTREAM_READ);
+               e = gf_isom_cenc_parse_sample(cenc_sample, bs, sample_number, use_subsample);
+               gf_bs_del(bs);
+               if (e) {
+                       gf_isom_cenc_sample_del(cenc_sample);
+                       return NULL;
+               }
+               return cenc_sample;
+       }
+       return NULL;
+}
+
+#endif //      GPAC_DISABLE_ISOM_FRAGMENTS
+
+
+#endif /*GPAC_DISABLE_ISOM*/
diff --git a/src/isomedia/generic_subtitle.c b/src/isomedia/generic_subtitle.c
new file mode 100644 (file)
index 0000000..80b28a8
--- /dev/null
@@ -0,0 +1,322 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Cyril Concolato\r
+ *                     Copyright (c) Telecom ParisTech 2012 \r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / ISO Media File Format sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#include <gpac/internal/isomedia_dev.h>\r
+#include <gpac/constants.h>\r
+\r
+#ifndef GPAC_DISABLE_ISOM\r
+\r
+#ifndef GPAC_DISABLE_ISOM_WRITE\r
+\r
+GF_Err gf_isom_update_generic_subtitle_description( GF_ISOFile                          *movie, \r
+                                                    u32                                 trackNumber, \r
+                                                    u32                                 descriptionIndex, \r
+                                                    GF_GenericSubtitleSampleDescriptor  *desc)\r
+{\r
+       GF_TrackBox *trak;\r
+       GF_Err      e;\r
+\r
+       if (!descriptionIndex || !desc) return GF_BAD_PARAM;\r
+       e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);\r
+       if (e) return e;\r
+       \r
+       trak = gf_isom_get_track_from_file(movie, trackNumber);\r
+       if (!trak || !trak->Media) return GF_BAD_PARAM;\r
+\r
+       switch (trak->Media->handler->handlerType) {\r
+       case GF_ISOM_MEDIA_SUBM:\r
+               break;\r
+       default:\r
+               return GF_BAD_PARAM;\r
+       }\r
+\r
+       //GF_GenericSubtitleSampleEntryBox *gsub;\r
+       //gsub = (GF_GenericSubtitleSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, descriptionIndex - 1);\r
+       //if (!gsub) return GF_BAD_PARAM;\r
+       //switch (txt->type) {\r
+       //case GF_ISOM_BOX_TYPE_METX:\r
+       //case GF_ISOM_BOX_TYPE_METT:\r
+       //      break;\r
+       //default:\r
+       //      return GF_BAD_PARAM;\r
+       //}\r
+\r
+       trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();\r
+\r
+       return e;\r
+}\r
+\r
+GF_Err gf_isom_new_generic_subtitle_description(GF_ISOFile  *movie, \r
+                                                u32         trackNumber, \r
+                                                char        *content_encoding, \r
+                                                char        *xml_schema_loc, \r
+                                                char        *mime_type_or_namespace, \r
+                                                Bool        is_xml, \r
+                                                char        *URLname,\r
+                                                char        *URNname,\r
+                                                u32         *outDescriptionIndex)\r
+{\r
+       GF_TrackBox                 *trak;\r
+       GF_Err                      e;\r
+       u32                         dataRefIndex;\r
+       GF_MetaDataSampleEntryBox   *metasd;\r
+\r
+       e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);\r
+       if (e) return e;\r
+       \r
+       trak = gf_isom_get_track_from_file(movie, trackNumber);\r
+       if (!trak || !trak->Media) return GF_BAD_PARAM;\r
+\r
+       switch (trak->Media->handler->handlerType) {\r
+       case GF_ISOM_MEDIA_SUBM:\r
+               break;\r
+       default:\r
+               return GF_BAD_PARAM;\r
+       }\r
+\r
+       //get or create the data ref\r
+       e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);\r
+       if (e) return e;\r
+       if (!dataRefIndex) {\r
+               e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);\r
+               if (e) return e;\r
+       }\r
+       trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();\r
+\r
+       metasd = (GF_MetaDataSampleEntryBox *) gf_isom_box_new((is_xml ? GF_ISOM_BOX_TYPE_METX : GF_ISOM_BOX_TYPE_METT));\r
+       metasd->dataReferenceIndex = dataRefIndex;\r
+       gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, metasd);\r
+       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);\r
+\r
+    metasd->content_encoding = gf_strdup(content_encoding);\r
+    metasd->xml_schema_loc = gf_strdup(xml_schema_loc);\r
+    metasd->mime_type_or_namespace = gf_strdup(mime_type_or_namespace);\r
+       return e;\r
+}\r
+\r
+\r
+/* blindly adds text to a sample following 3GPP Timed Text style */\r
+GF_Err gf_isom_generic_subtitle_sample_add_text(GF_GenericSubtitleSample *samp, char *text_data, u32 text_len)\r
+{\r
+       if (!samp) return GF_BAD_PARAM;\r
+       if (!text_len) return GF_OK;\r
+       samp->text = (char*)gf_realloc(samp->text, sizeof(char) * (samp->len + text_len) );\r
+       memcpy(samp->text + samp->len, text_data, sizeof(char) * text_len);\r
+       samp->len += text_len;\r
+       return GF_OK;\r
+}\r
+\r
+/* \r
+ * Writing the generic sample structure into a sample buffer \r
+ * 2 options: \r
+ * - putting the text or XML in the sample directly\r
+ * - or using a meta box to structure the sample data\r
+*/\r
+GF_ISOSample *gf_isom_generic_subtitle_to_sample(GF_GenericSubtitleSample *samp)\r
+{\r
+       GF_ISOSample *res;\r
+       GF_BitStream *bs;\r
+       if (!samp) return NULL;\r
+\r
+       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);\r
+       //gf_bs_write_u16(bs, samp->len);\r
+\r
+       if (samp->len) gf_bs_write_data(bs, samp->text, samp->len);\r
+    else     gf_bs_write_data(bs, "", 1);\r
+\r
+       res = gf_isom_sample_new();\r
+       if (!res) {\r
+               gf_bs_del(bs);\r
+               return NULL;\r
+       }\r
+       gf_bs_get_content(bs, &res->data, &res->dataLength);\r
+       gf_bs_del(bs);\r
+       res->IsRAP = 1;\r
+       return res;\r
+}\r
+\r
+//GF_Err gf_isom_generic_subtitle_has_similar_description(GF_ISOFile                          *movie, \r
+//                                                        u32                                 trackNumber, \r
+//                                                        GF_GenericSubtitleSampleDescriptor  *desc, \r
+//                                                        u32                                 *outDescIdx, \r
+//                                                        Bool                                *same_box)\r
+//{\r
+//     GF_TrackBox             *trak;\r
+//     GF_Err                  e;\r
+//     u32                     i;\r
+//    u32                     j;\r
+//    u32                     count;\r
+//     GF_Tx3gSampleEntryBox   *txt;\r
+//\r
+//     *same_box   = 0;\r
+//     *outDescIdx = 0;\r
+//\r
+//     if (!desc) return GF_BAD_PARAM;\r
+//     e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);\r
+//     if (e) return GF_BAD_PARAM;\r
+//     \r
+//     trak = gf_isom_get_track_from_file(movie, trackNumber);\r
+//     if (!trak || !trak->Media) return GF_BAD_PARAM;\r
+//\r
+//     switch (trak->Media->handler->handlerType) {\r
+//     case GF_ISOM_MEDIA_SUBT:\r
+//             break;\r
+//     default:\r
+//             return GF_BAD_PARAM;\r
+//     }\r
+//\r
+//     return GF_OK;\r
+//}\r
+\r
+#endif /*GPAC_DISABLE_ISOM_WRITE*/\r
+\r
+GF_GenericSubtitleSample *gf_isom_new_generic_subtitle_sample()\r
+{\r
+       GF_GenericSubtitleSample *res;\r
+       GF_SAFEALLOC(res, GF_GenericSubtitleSample);\r
+       if (!res) return NULL;\r
+       return res;\r
+}\r
+\r
+GF_Err gf_isom_generic_subtitle_reset(GF_GenericSubtitleSample *samp)\r
+{\r
+       if (!samp) return GF_BAD_PARAM;\r
+       if (samp->text) gf_free(samp->text);\r
+       samp->text = NULL;\r
+       samp->len = 0;\r
+       return GF_OK;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_isom_delete_generic_subtitle_sample(GF_GenericSubtitleSample * samp)\r
+{\r
+       gf_isom_generic_subtitle_reset(samp);\r
+       gf_free(samp);\r
+}\r
+\r
+GF_EXPORT\r
+GF_GenericSubtitleSample *gf_isom_parse_generic_subtitle_sample(GF_BitStream *bs)\r
+{\r
+       GF_GenericSubtitleSample *s = gf_isom_new_generic_subtitle_sample();\r
+       \r
+       /*empty sample*/\r
+       if (!bs || !gf_bs_available(bs)) return s;\r
+\r
+       s->len = gf_bs_read_u16(bs);\r
+       if (s->len) {\r
+               /*2 extra bytes for UTF-16 term char just in case (we don't know if a BOM marker is present or \r
+               not since this may be a sample carried over RTP*/\r
+               s->text = (char *) gf_malloc(sizeof(char)*(s->len+2) );\r
+               s->text[s->len] = 0; \r
+        s->text[s->len+1] = 0;\r
+               gf_bs_read_data(bs, s->text, s->len);\r
+       }\r
+       return s;\r
+}\r
+\r
+GF_GenericSubtitleSample *gf_isom_parse_generic_subtitle_sample_from_data(char *data, u32 dataLength)\r
+{\r
+       GF_GenericSubtitleSample *s;\r
+       GF_BitStream *bs;\r
+       /*empty text sample*/\r
+       if (!data || !dataLength) {\r
+               return gf_isom_new_generic_subtitle_sample();\r
+       }\r
+       \r
+       bs = gf_bs_new(data, dataLength, GF_BITSTREAM_READ);\r
+       s = gf_isom_parse_generic_subtitle_sample(bs);\r
+       gf_bs_del(bs);\r
+       return s;\r
+}\r
+\r
+\r
+/*out-of-band sample desc (128 and 255 reserved in RFC)*/\r
+#define SAMPLE_INDEX_OFFSET            129\r
+\r
+GF_Err gf_isom_rewrite_generic_subtitle_sample(GF_ISOSample *samp, u32 sampleDescriptionIndex, u32 sample_dur)\r
+{\r
+       //GF_BitStream *bs;\r
+       //u32 pay_start, txt_size;\r
+       //Bool is_utf_16 = 0;\r
+       //if (!samp || !samp->data || !samp->dataLength) return GF_OK;\r
+\r
+       //bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ);\r
+       //txt_size = gf_bs_read_u16(bs);\r
+       //gf_bs_del(bs);\r
+\r
+       ///*remove BOM*/\r
+       //pay_start = 2;\r
+       //if (txt_size>2) {\r
+       //      /*seems 3GP only accepts BE UTF-16 (no LE, no UTF32)*/\r
+       //      if (((u8) samp->data[2]==(u8) 0xFE) && ((u8)samp->data[3]==(u8) 0xFF)) {\r
+       //              is_utf_16 = 1;\r
+       //              pay_start = 4;\r
+       //              txt_size -= 2;\r
+       //      }\r
+       //}\r
+\r
+       ///*rewrite as TTU(1)*/\r
+       //bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);\r
+       //gf_bs_write_int(bs, is_utf_16, 1);\r
+       //gf_bs_write_int(bs, 0, 4);\r
+       //gf_bs_write_int(bs, 1, 3);\r
+       //gf_bs_write_u16(bs, 8 + samp->dataLength - pay_start);\r
+       //gf_bs_write_u8(bs, sampleDescriptionIndex + SAMPLE_INDEX_OFFSET);\r
+       //gf_bs_write_u24(bs, sample_dur);\r
+       ///*write text size*/\r
+       //gf_bs_write_u16(bs, txt_size);\r
+       //if (txt_size) gf_bs_write_data(bs, samp->data + pay_start, samp->dataLength - pay_start);\r
+\r
+       //gf_free(samp->data);\r
+       //samp->data = NULL;\r
+       //gf_bs_get_content(bs, &samp->data, &samp->dataLength);\r
+       //gf_bs_del(bs);\r
+       return GF_OK;\r
+}\r
+\r
+\r
+//GF_Err gf_isom_text_get_encoded_tx3g(GF_ISOFile *file, u32 track, u32 sidx, u32 sidx_offset, char **tx3g, u32 *tx3g_size)\r
+//{\r
+//     GF_BitStream *bs;\r
+//     GF_TrackBox *trak;\r
+//     GF_Tx3gSampleEntryBox *a;\r
+//     \r
+//     trak = gf_isom_get_track_from_file(file, track);\r
+//     if (!trak) return GF_BAD_PARAM;\r
+//\r
+//     a = (GF_Tx3gSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sidx-1);\r
+//     if (!a) return GF_BAD_PARAM;\r
+//     if ((a->type != GF_ISOM_BOX_TYPE_TX3G) && (a->type != GF_ISOM_BOX_TYPE_TEXT)) return GF_BAD_PARAM;\r
+//     \r
+//     bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);\r
+//     gf_isom_write_tx3g(a, bs, sidx, sidx_offset);\r
+//     *tx3g = NULL;\r
+//     *tx3g_size = 0;\r
+//     gf_bs_get_content(bs, tx3g, tx3g_size);\r
+//     gf_bs_del(bs);\r
+//     return GF_OK;\r
+//}\r
+\r
+#endif /*GPAC_DISABLE_ISOM*/\r
index 3eeba725d4671a6a8cbef7bcafdef12b19dd9112..f70366c88d591847f30a7f6476c868ab871e9b37 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -41,7 +42,7 @@ u32 GetHintFormat(GF_TrackBox *trak)
 {
        GF_HintMediaHeaderBox *hmhd = (GF_HintMediaHeaderBox *)trak->Media->information->InfoHeader;
        if (!hmhd->subType) {
-               GF_Box *a = (GF_Box *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0);
+               GF_Box *a = (GF_Box *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, 0);
                if (a) hmhd->subType = a->type;
        }
        return hmhd->subType;
@@ -192,7 +193,7 @@ GF_Err gf_isom_new_hint_description(GF_ISOFile *the_file, u32 trackNumber, s32 H
        //add the entry to our table...
        e = stsd_AddBox(trak->Media->information->sampleTable->SampleDescription, (GF_Box *) hdesc);
        if (e) return e;
-       *HintDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       *HintDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
 
        //RTP needs a default timeScale... use the media one.
        if (CheckHintFormat(trak, GF_ISOM_HINT_RTP)) {
@@ -228,7 +229,7 @@ GF_Err gf_isom_rtp_set_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 Hint
        if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM;
 
        //OK, create a new HintSampleDesc
-       hdesc = (GF_HintSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, HintDescriptionIndex - 1);
+       hdesc = (GF_HintSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, HintDescriptionIndex - 1);
        count = gf_list_count(hdesc->HintDataTable);
 
        for (i=0; i< count; i++) {
@@ -257,7 +258,7 @@ GF_Err gf_isom_rtp_set_time_offset(GF_ISOFile *the_file, u32 trackNumber, u32 Hi
        if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM;
 
        //OK, create a new HintSampleDesc
-       hdesc = (GF_HintSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, HintDescriptionIndex - 1);
+       hdesc = (GF_HintSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, HintDescriptionIndex - 1);
        count = gf_list_count(hdesc->HintDataTable);
 
        for (i=0; i< count; i++) {
@@ -286,7 +287,7 @@ GF_Err gf_isom_rtp_set_time_sequence_offset(GF_ISOFile *the_file, u32 trackNumbe
        if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM;
 
        //OK, create a new HintSampleDesc
-       hdesc = (GF_HintSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, HintDescriptionIndex - 1);
+       hdesc = (GF_HintSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, HintDescriptionIndex - 1);
        count = gf_list_count(hdesc->HintDataTable);
 
        for (i=0; i< count; i++) {
@@ -730,9 +731,9 @@ GF_Err gf_isom_sdp_add_track_line(GF_ISOFile *the_file, u32 trackNumber, const c
        if (!map) return GF_ISOM_INVALID_FILE;
 
        //we should have only one HNTI in the UDTA
-       if (gf_list_count(map->boxList) != 1) return GF_ISOM_INVALID_FILE;
+       if (gf_list_count(map->other_boxes) != 1) return GF_ISOM_INVALID_FILE;
 
-       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0);
+       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0);
        if (!hnti->SDP) {
                e = hnti_AddBox(hnti, gf_isom_box_new(GF_ISOM_BOX_TYPE_SDP));
                if (e) return e;
@@ -772,9 +773,9 @@ GF_Err gf_isom_sdp_clean_track(GF_ISOFile *the_file, u32 trackNumber)
        if (!map) return GF_ISOM_INVALID_FILE;
 
        //we should have only one HNTI in the UDTA
-       if (gf_list_count(map->boxList) != 1) return GF_ISOM_INVALID_FILE;
+       if (gf_list_count(map->other_boxes) != 1) return GF_ISOM_INVALID_FILE;
 
-       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0);
+       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0);
        if (!hnti->SDP) return GF_OK;
        //and free the SDP
        gf_free(((GF_SDPBox *)hnti->SDP)->sdpText);
@@ -810,13 +811,13 @@ GF_Err gf_isom_sdp_add_line(GF_ISOFile *movie, const char *text)
        }
 
        //there should be one and only one hnti
-       if (!gf_list_count(map->boxList) ) {
+       if (!gf_list_count(map->other_boxes) ) {
                e = udta_AddBox(movie->moov->udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HNTI));
                if (e) return e;
        }
-       else if (gf_list_count(map->boxList) < 1) return GF_ISOM_INVALID_FILE;
+       else if (gf_list_count(map->other_boxes) < 1) return GF_ISOM_INVALID_FILE;
 
-       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0);
+       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0);
 
        if (!hnti->SDP) {
                //we have to create it by hand, as we have a duplication of box type 
@@ -861,11 +862,11 @@ GF_Err gf_isom_sdp_clean(GF_ISOFile *movie)
        if (!map) return GF_OK;
 
        //there should be one and only one hnti
-       if (gf_list_count(map->boxList) != 1) return GF_ISOM_INVALID_FILE;
-       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0);
+       if (gf_list_count(map->other_boxes) != 1) return GF_ISOM_INVALID_FILE;
+       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0);
 
        //remove and destroy the entry
-       gf_list_rem(map->boxList, 0);
+       gf_list_rem(map->other_boxes, 0);
        gf_isom_box_del((GF_Box *)hnti);
        return GF_OK;
 }
@@ -889,8 +890,8 @@ GF_Err gf_isom_sdp_get(GF_ISOFile *movie, const char **sdp, u32 *length)
        if (!map) return GF_OK;
 
        //there should be one and only one hnti
-       if (gf_list_count(map->boxList) != 1) return GF_ISOM_INVALID_FILE;
-       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0);
+       if (gf_list_count(map->other_boxes) != 1) return GF_ISOM_INVALID_FILE;
+       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0);
 
        if (!hnti->SDP) return GF_OK;
        rtp = (GF_RTPBox *) hnti->SDP;
@@ -919,9 +920,9 @@ GF_Err gf_isom_sdp_track_get(GF_ISOFile *the_file, u32 trackNumber, const char *
        if (!map) return GF_ISOM_INVALID_FILE;
 
        //we should have only one HNTI in the UDTA
-       if (gf_list_count(map->boxList) != 1) return GF_ISOM_INVALID_FILE;
+       if (gf_list_count(map->other_boxes) != 1) return GF_ISOM_INVALID_FILE;
 
-       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0);
+       hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0);
        if (!hnti->SDP) return GF_OK;
        sdpa = (GF_SDPBox *) hnti->SDP;
 
@@ -946,12 +947,12 @@ u32 gf_isom_get_payt_count(GF_ISOFile *the_file, u32 trackNumber)
        if (!CheckHintFormat(trak, GF_4CC('r', 't', 'p', ' '))) return 0;
        map = udta_getEntry(trak->udta, GF_ISOM_BOX_TYPE_HINF, NULL);
        if (!map) return 0;
-       if (gf_list_count(map->boxList) != 1) return 0;
+       if (gf_list_count(map->other_boxes) != 1) return 0;
 
-       hinf = (GF_HintInfoBox *)gf_list_get(map->boxList, 0);
+       hinf = (GF_HintInfoBox *)gf_list_get(map->other_boxes, 0);
        count = 0;
        i = 0;
-       while ((payt = gf_list_enum(hinf->boxList, &i))) {
+       while ((payt = gf_list_enum(hinf->other_boxes, &i))) {
                if (payt->type == GF_ISOM_BOX_TYPE_PAYT) count++;
        }
        return count;
@@ -972,12 +973,12 @@ const char *gf_isom_get_payt_info(GF_ISOFile *the_file, u32 trackNumber, u32 ind
        if (!CheckHintFormat(trak, GF_4CC('r', 't', 'p', ' '))) return NULL;
        map = udta_getEntry(trak->udta, GF_ISOM_BOX_TYPE_HINF, NULL);
        if (!map) return NULL;
-       if (gf_list_count(map->boxList) != 1) return NULL;
+       if (gf_list_count(map->other_boxes) != 1) return NULL;
 
-       hinf = (GF_HintInfoBox *)gf_list_get(map->boxList, 0);
+       hinf = (GF_HintInfoBox *)gf_list_get(map->other_boxes, 0);
        count = 0;
        i = 0;
-       while ((payt = gf_list_enum(hinf->boxList, &i))) {
+       while ((payt = gf_list_enum(hinf->other_boxes, &i))) {
                if (payt->type == GF_ISOM_BOX_TYPE_PAYT) {
                        count++;
                        if (count == index) {
index 942f3afb8d25bbb937b21cbd9d3b46ab26534032..947fd74d4fee39d3755a76138652591850e980c0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
diff --git a/src/isomedia/isma_sample.c b/src/isomedia/isma_sample.c
deleted file mode 100644 (file)
index 485f1ba..0000000
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- *                     GPAC - Multimedia Framework C SDK
- *
- *                     Copyright (c) Cyril Concolato / Jean Le Feuvre 2005
- *                                     All rights reserved
- *
- *  This file is part of GPAC / ISO Media File Format 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. 
- *
- */
-
-#include <gpac/internal/isomedia_dev.h>
-
-#ifndef GPAC_DISABLE_ISOM
-
-GF_ISMASample *gf_isom_ismacryp_new_sample()
-{
-       GF_ISMASample *tmp = (GF_ISMASample *) gf_malloc(sizeof(GF_ISMASample));
-       if (!tmp) return NULL;
-       memset(tmp, 0, sizeof(GF_ISMASample));
-       return tmp;
-}
-GF_EXPORT
-void gf_isom_ismacryp_delete_sample(GF_ISMASample *samp)
-{
-       if (!samp) return;
-       if (samp->data && samp->dataLength) gf_free(samp->data);
-       if (samp->key_indicator) gf_free(samp->key_indicator);
-       gf_free(samp);
-}
-
-
-GF_ISMASample *gf_isom_ismacryp_sample_from_data(char *data, u32 dataLength, Bool use_selective_encryption, u8 KI_length, u8 IV_length)
-{
-       GF_ISMASample *s;
-       GF_BitStream *bs;
-       /*empty text sample*/
-       if (!data || !dataLength) {
-               return gf_isom_ismacryp_new_sample();
-       }
-       
-       s = gf_isom_ismacryp_new_sample();
-               
-       /*empty sample*/
-       if (!data || !dataLength) return s;
-
-       bs = gf_bs_new(data, dataLength, GF_BITSTREAM_READ);
-
-       s->dataLength = dataLength;
-       s->IV_length = IV_length;
-       s->KI_length = KI_length;
-
-       if (use_selective_encryption) {
-               s->flags = GF_ISOM_ISMA_USE_SEL_ENC;
-               if (s->dataLength < 1) goto exit;
-               if (gf_bs_read_int(bs, 1)) s->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
-               gf_bs_read_int(bs, 7);
-               s->dataLength -= 1;
-       } else {
-               s->flags = GF_ISOM_ISMA_IS_ENCRYPTED;
-       }
-       if (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) {
-               if (IV_length != 0) {
-                       if (s->dataLength < IV_length) goto exit;
-                       s->IV = gf_bs_read_long_int(bs, 8*IV_length);
-                       s->dataLength -= IV_length;
-               }
-               if (KI_length) {
-                       if (s->dataLength < KI_length) goto exit;
-                       s->key_indicator = (u8 *)gf_malloc(KI_length);
-                       gf_bs_read_data(bs, (char*)s->key_indicator, KI_length);
-                       s->dataLength -= KI_length;
-               }
-       }
-       s->data = (char*)gf_malloc(sizeof(char)*s->dataLength);
-       gf_bs_read_data(bs, s->data, s->dataLength);
-       gf_bs_del(bs);
-       return s;
-
-exit:
-       gf_isom_ismacryp_delete_sample(s);
-       return NULL;
-}
-
-GF_Err gf_isom_ismacryp_sample_to_sample(GF_ISMASample *s, GF_ISOSample *dest)
-{
-       GF_BitStream *bs;
-       if (!s || !dest) return GF_BAD_PARAM;
-
-       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
-
-       if (s->flags & GF_ISOM_ISMA_USE_SEL_ENC) {
-               gf_bs_write_int(bs, (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) ? 1 : 0, 1);
-               gf_bs_write_int(bs, 0, 7);
-       } 
-       if (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) {
-               if (s->IV_length) gf_bs_write_long_int(bs, (s64) s->IV, 8*s->IV_length);
-               if (s->KI_length) gf_bs_write_data(bs, (char*)s->key_indicator, s->KI_length);
-       }
-       gf_bs_write_data(bs, s->data, s->dataLength);
-       if (dest->data) gf_free(dest->data);
-       dest->data = NULL;
-       dest->dataLength = 0;
-       gf_bs_get_content(bs, &dest->data, &dest->dataLength);
-       gf_bs_del(bs);
-       return GF_OK;
-}
-
-GF_EXPORT
-GF_ISMASample *gf_isom_get_ismacryp_sample(GF_ISOFile *the_file, u32 trackNumber, GF_ISOSample *samp, u32 sampleDescriptionIndex)
-{
-       GF_TrackBox *trak;
-       GF_ISMASampleFormatBox *fmt;
-       GF_SampleEntryBox *sea;
-       
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return NULL;
-
-       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea || !sea->protection_info 
-               || !sea->protection_info->scheme_type 
-               || !sea->protection_info->info
-               ) {
-               return NULL;
-       }
-       /*ISMA*/
-       if (sea->protection_info->scheme_type->scheme_type == GF_ISOM_ISMACRYP_SCHEME) {
-               fmt = sea->protection_info->info->isfm;
-               if (!fmt) return NULL;
-               return gf_isom_ismacryp_sample_from_data(samp->data, samp->dataLength, sea->protection_info->info->isfm->selective_encryption, sea->protection_info->info->isfm->key_indicator_length, sea->protection_info->info->isfm->IV_length);
-       }
-       /*OMA*/
-       else if (sea->protection_info->scheme_type->scheme_type == GF_4CC('o','d','k','m') ) {
-               if (!sea->protection_info->info->okms) return NULL;
-               fmt = sea->protection_info->info->okms->fmt;
-
-               if (fmt) {
-                       return gf_isom_ismacryp_sample_from_data(samp->data, samp->dataLength, fmt->selective_encryption, fmt->key_indicator_length, fmt->IV_length);
-               }
-               /*OMA default: no selective encryption, one key, 128 bit IV*/
-               return gf_isom_ismacryp_sample_from_data(samp->data, samp->dataLength, 0, 0, 128);
-       }
-       return NULL;
-}
-
-
-GF_EXPORT
-u32 gf_isom_is_media_encrypted(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
-{
-       GF_TrackBox *trak;
-       GF_SampleEntryBox *sea;
-
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return 0;
-
-       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea || !sea->protection_info || !sea->protection_info->scheme_type) return 0;
-       return sea->protection_info->scheme_type->scheme_type;
-}
-
-GF_EXPORT
-Bool gf_isom_is_ismacryp_media(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
-{
-       GF_TrackBox *trak;
-       GF_SampleEntryBox *sea;
-
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return 0;
-
-       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea 
-               || !sea->protection_info 
-               || !sea->protection_info->scheme_type 
-               || (sea->protection_info->scheme_type->scheme_type != GF_ISOM_ISMACRYP_SCHEME)
-               || !sea->protection_info->info
-               || !sea->protection_info->info->ikms
-               || !sea->protection_info->info->isfm
-               ) 
-               return 0;
-
-       return 1;
-}
-
-GF_EXPORT
-Bool gf_isom_is_omadrm_media(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
-{
-       GF_TrackBox *trak;
-       GF_SampleEntryBox *sea;
-
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return 0;
-
-       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea 
-               || !sea->protection_info 
-               || !sea->protection_info->scheme_type 
-               || (sea->protection_info->scheme_type->scheme_type != GF_4CC('o','d','k','m') )
-               || !sea->protection_info->info
-               || !sea->protection_info->info->okms
-               || !sea->protection_info->info->okms->hdr
-               ) 
-               return 0;
-
-       return 1;
-}
-
-/*retrieves ISMACryp info for the given track & SDI*/
-GF_EXPORT
-GF_Err gf_isom_get_ismacryp_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat, u32 *outSchemeType, u32 *outSchemeVersion, const char **outSchemeURI, const char **outKMS_URI, Bool *outSelectiveEncryption, u32 *outIVLength, u32 *outKeyIndicationLength)
-{
-       GF_TrackBox *trak;
-       GF_SampleEntryBox *sea;
-       
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return GF_BAD_PARAM;
-
-       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea || !sea->protection_info) return GF_BAD_PARAM;
-       if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;
-
-       if (outOriginalFormat) {
-               *outOriginalFormat = sea->protection_info->original_format->data_format;
-               if (IsMP4Description(sea->protection_info->original_format->data_format)) *outOriginalFormat = GF_ISOM_SUBTYPE_MPEG4;
-       }
-       if (outSchemeType) *outSchemeType = sea->protection_info->scheme_type->scheme_type;
-       if (outSchemeVersion) *outSchemeVersion = sea->protection_info->scheme_type->scheme_version;
-       if (outSchemeURI) *outSchemeURI = sea->protection_info->scheme_type->URI;
-
-       if (sea->protection_info->info && sea->protection_info->info->ikms) {
-               if (outKMS_URI) *outKMS_URI = sea->protection_info->info->ikms->URI;
-       } else {
-               if (outKMS_URI) *outKMS_URI = NULL;
-       }
-       if (sea->protection_info->info && sea->protection_info->info->isfm) {
-               if (outSelectiveEncryption) *outSelectiveEncryption = sea->protection_info->info->isfm->selective_encryption;
-               if (outIVLength) *outIVLength = sea->protection_info->info->isfm->IV_length;
-               if (outKeyIndicationLength) *outKeyIndicationLength = sea->protection_info->info->isfm->key_indicator_length;
-       } else {
-               if (outSelectiveEncryption) *outSelectiveEncryption = 0;
-               if (outIVLength) *outIVLength = 0;
-               if (outKeyIndicationLength) *outKeyIndicationLength = 0;
-       }
-       return GF_OK;
-}
-
-
-/*retrieves ISMACryp info for the given track & SDI*/
-GF_EXPORT
-GF_Err gf_isom_get_omadrm_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat,
-                                                          u32 *outSchemeType, u32 *outSchemeVersion,
-                                                          const char **outContentID, const char **outRightsIssuerURL, const char **outTextualHeaders, u32 *outTextualHeadersLen, u64 *outPlaintextLength, u32 *outEncryptionType, Bool *outSelectiveEncryption, u32 *outIVLength, u32 *outKeyIndicationLength)
-{
-       GF_TrackBox *trak;
-       GF_SampleEntryBox *sea;
-       
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return GF_BAD_PARAM;
-
-       Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea || !sea->protection_info) return GF_BAD_PARAM;
-       if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;
-       if (!sea->protection_info->info || !sea->protection_info->info->okms || !sea->protection_info->info->okms->hdr) return GF_NON_COMPLIANT_BITSTREAM;
-
-       if (outOriginalFormat) {
-               *outOriginalFormat = sea->protection_info->original_format->data_format;
-               if (IsMP4Description(sea->protection_info->original_format->data_format)) *outOriginalFormat = GF_ISOM_SUBTYPE_MPEG4;
-       }
-       if (outSchemeType) *outSchemeType = sea->protection_info->scheme_type->scheme_type;
-       if (outSchemeVersion) *outSchemeVersion = sea->protection_info->scheme_type->scheme_version;
-       if (outContentID) *outContentID = sea->protection_info->info->okms->hdr->ContentID;
-       if (outRightsIssuerURL) *outRightsIssuerURL = sea->protection_info->info->okms->hdr->RightsIssuerURL;
-       if (outTextualHeaders) {
-               *outTextualHeaders = sea->protection_info->info->okms->hdr->TextualHeaders;
-               if (outTextualHeadersLen) *outTextualHeadersLen = sea->protection_info->info->okms->hdr->TextualHeadersLen;
-       }
-       if (outPlaintextLength) *outPlaintextLength = sea->protection_info->info->okms->hdr->PlaintextLength;
-       if (outEncryptionType) *outEncryptionType = sea->protection_info->info->okms->hdr->EncryptionMethod;
-
-       if (sea->protection_info->info && sea->protection_info->info->okms  && sea->protection_info->info->okms->fmt) {
-               if (outSelectiveEncryption) *outSelectiveEncryption = sea->protection_info->info->okms->fmt->selective_encryption;
-               if (outIVLength) *outIVLength = sea->protection_info->info->okms->fmt->IV_length;
-               if (outKeyIndicationLength) *outKeyIndicationLength = sea->protection_info->info->okms->fmt->key_indicator_length;
-       } else {
-               if (outSelectiveEncryption) *outSelectiveEncryption = 0;
-               if (outIVLength) *outIVLength = 0;
-               if (outKeyIndicationLength) *outKeyIndicationLength = 0;
-       }
-       return GF_OK;
-}
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-
-GF_Err gf_isom_remove_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex)
-{
-       GF_TrackBox *trak;
-       GF_Err e;
-       GF_SampleEntryBox *sea;
-
-       e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
-       if (e) return e;
-       
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak || !trak->Media || !StreamDescriptionIndex) return GF_BAD_PARAM;
-
-       Media_GetSampleDesc(trak->Media, StreamDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea || !sea->protection_info) return GF_BAD_PARAM;
-       if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;
-
-       sea->type = sea->protection_info->original_format->data_format;
-       gf_isom_box_del((GF_Box *)sea->protection_info);
-       sea->protection_info = NULL;
-       if (sea->type == GF_4CC('2','6','4','b')) sea->type = GF_ISOM_BOX_TYPE_AVC1;
-       return GF_OK;
-}
-
-GF_EXPORT
-GF_Err gf_isom_change_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, char *scheme_uri, char *kms_uri)
-{
-       GF_TrackBox *trak;
-       GF_Err e;
-       GF_SampleEntryBox *sea;
-
-       e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
-       if (e) return e;
-       
-       trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak || !trak->Media || !StreamDescriptionIndex) return GF_BAD_PARAM;
-
-       Media_GetSampleDesc(trak->Media, StreamDescriptionIndex, &sea, NULL);
-       /*non-encrypted or non-ISMA*/
-       if (!sea || !sea->protection_info) return GF_BAD_PARAM;
-       if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;
-
-       if (scheme_uri) {
-               gf_free(sea->protection_info->scheme_type->URI);
-               sea->protection_info->scheme_type->URI = gf_strdup(scheme_uri);
-       }
-       if (kms_uri) {
-               gf_free(sea->protection_info->info->ikms->URI);
-               sea->protection_info->info->ikms->URI = gf_strdup(kms_uri);
-       }
-       return GF_OK;
-}
-
-
-GF_Err gf_isom_set_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 desc_index, u32 scheme_type, 
-                                                  u32 scheme_version, char *scheme_uri, char *kms_URI,
-                                                  Bool selective_encryption, u32 KI_length, u32 IV_length)
-{
-       u32 original_format;
-       GF_Err e;
-       GF_SampleEntryBox *sea;
-       GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return GF_BAD_PARAM;
-
-       e = Media_GetSampleDesc(trak->Media, desc_index, &sea, NULL);
-       if (e) return e;
-
-       /* Replacing the Media Type */
-       switch (sea->type) {
-       case GF_ISOM_BOX_TYPE_MP4A:
-       case GF_ISOM_BOX_TYPE_DAMR:
-       case GF_ISOM_BOX_TYPE_DEVC:
-       case GF_ISOM_BOX_TYPE_DQCP:
-       case GF_ISOM_BOX_TYPE_DSMV:
-       case GF_ISOM_BOX_TYPE_AC3:
-               original_format = sea->type;
-               sea->type = GF_ISOM_BOX_TYPE_ENCA;
-               break;
-       case GF_ISOM_BOX_TYPE_MP4V:
-       case GF_ISOM_BOX_TYPE_D263:
-               original_format = sea->type;
-               sea->type = GF_ISOM_BOX_TYPE_ENCV;
-               break;
-       /*special case for AVC1*/
-       case GF_ISOM_BOX_TYPE_AVC1:
-       case GF_ISOM_BOX_TYPE_AVC2:
-       case GF_ISOM_BOX_TYPE_SVC1:
-               original_format = GF_4CC('2','6','4','b');
-               sea->type = GF_ISOM_BOX_TYPE_ENCV;
-               break;
-       case GF_ISOM_BOX_TYPE_MP4S:
-       case GF_ISOM_BOX_TYPE_LSR1:
-               original_format = sea->type;
-               sea->type = GF_ISOM_BOX_TYPE_ENCS;
-               break;
-       default:
-               return GF_BAD_PARAM;
-       }
-       
-       sea->protection_info = (GF_ProtectionInfoBox *)sinf_New();
-       sea->protection_info->scheme_type = (GF_SchemeTypeBox *)schm_New();
-       sea->protection_info->scheme_type->scheme_type = scheme_type;
-       sea->protection_info->scheme_type->scheme_version = scheme_version;
-       if (scheme_uri) {
-               sea->protection_info->scheme_type->flags |= 0x000001;
-               sea->protection_info->scheme_type->URI = gf_strdup(scheme_uri);
-       }
-       sea->protection_info->original_format = (GF_OriginalFormatBox *)frma_New();
-       sea->protection_info->original_format->data_format = original_format;
-       sea->protection_info->info = (GF_SchemeInformationBox *)schi_New();
-
-       sea->protection_info->info->ikms = (GF_ISMAKMSBox *)iKMS_New();
-       sea->protection_info->info->ikms->URI = gf_strdup(kms_URI);
-
-       sea->protection_info->info->isfm = (GF_ISMASampleFormatBox *)iSFM_New();
-       sea->protection_info->info->isfm->selective_encryption = selective_encryption;
-       sea->protection_info->info->isfm->key_indicator_length = KI_length;
-       sea->protection_info->info->isfm->IV_length = IV_length;
-       return GF_OK;
-}
-
-GF_Err gf_isom_set_oma_protection(GF_ISOFile *the_file, u32 trackNumber, u32 desc_index,
-                                                  char *contentID, char *kms_URI, u32 encryption_type, u64 plainTextLength, char *textual_headers, u32 textual_headers_len,
-                                                  Bool selective_encryption, u32 KI_length, u32 IV_length)
-{
-       u32 original_format;
-       GF_Err e;
-       GF_SampleEntryBox *sea;
-       GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber);
-       if (!trak) return GF_BAD_PARAM;
-
-       e = Media_GetSampleDesc(trak->Media, desc_index, &sea, NULL);
-       if (e) return e;
-
-       /* Replacing the Media Type */
-       switch (sea->type) {
-       case GF_ISOM_BOX_TYPE_MP4A:
-       case GF_ISOM_BOX_TYPE_DAMR:
-       case GF_ISOM_BOX_TYPE_DEVC:
-       case GF_ISOM_BOX_TYPE_DQCP:
-       case GF_ISOM_BOX_TYPE_DSMV:
-               original_format = sea->type;
-               sea->type = GF_ISOM_BOX_TYPE_ENCA;
-               break;
-       case GF_ISOM_BOX_TYPE_MP4V:
-       case GF_ISOM_BOX_TYPE_AVC1:
-       case GF_ISOM_BOX_TYPE_AVC2:
-       case GF_ISOM_BOX_TYPE_SVC1:
-       case GF_ISOM_BOX_TYPE_D263:
-               original_format = sea->type;
-               sea->type = GF_ISOM_BOX_TYPE_ENCV;
-               break;
-       case GF_ISOM_BOX_TYPE_MP4S:
-       case GF_ISOM_BOX_TYPE_LSR1:
-               original_format = sea->type;
-               sea->type = GF_ISOM_BOX_TYPE_ENCS;
-               break;
-       default:
-               return GF_BAD_PARAM;
-       }
-       
-       sea->protection_info = (GF_ProtectionInfoBox *)sinf_New();
-       sea->protection_info->scheme_type = (GF_SchemeTypeBox *)schm_New();
-       sea->protection_info->scheme_type->scheme_type = GF_4CC('o','d','k','m');
-       sea->protection_info->scheme_type->scheme_version = 0x00000200;
-
-       sea->protection_info->original_format = (GF_OriginalFormatBox *)frma_New();
-       sea->protection_info->original_format->data_format = original_format;
-       sea->protection_info->info = (GF_SchemeInformationBox *)schi_New();
-
-       sea->protection_info->info->okms = (GF_OMADRMKMSBox *)odkm_New();
-       sea->protection_info->info->okms->fmt = (GF_OMADRMAUFormatBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_ODAF);
-       sea->protection_info->info->okms->fmt->selective_encryption = selective_encryption;
-       sea->protection_info->info->okms->fmt->key_indicator_length = KI_length;
-       sea->protection_info->info->okms->fmt->IV_length = IV_length;
-
-       sea->protection_info->info->okms->hdr = (GF_OMADRMCommonHeaderBox*)ohdr_New();
-       sea->protection_info->info->okms->hdr->EncryptionMethod = encryption_type;
-       sea->protection_info->info->okms->hdr->PaddingScheme = (encryption_type==0x01) ? 1 : 0;
-       sea->protection_info->info->okms->hdr->PlaintextLength = plainTextLength;
-       if (contentID) sea->protection_info->info->okms->hdr->ContentID = gf_strdup(contentID);
-       if (kms_URI) sea->protection_info->info->okms->hdr->RightsIssuerURL = gf_strdup(kms_URI);
-       if (textual_headers) {
-               sea->protection_info->info->okms->hdr->TextualHeaders = gf_malloc(sizeof(char)*textual_headers_len);
-               memcpy(sea->protection_info->info->okms->hdr->TextualHeaders, textual_headers, sizeof(char)*textual_headers_len);
-               sea->protection_info->info->okms->hdr->TextualHeadersLen = textual_headers_len;
-       }
-       return GF_OK;
-}
-
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
-
-
-#endif /*GPAC_DISABLE_ISOM*/
index 28753542508c13a9df1db65ef0db0577a5264021..6d54c1f88c7c8f7f943cdd4a48682feb5fa2d077 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -37,6 +38,7 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset,
 
 GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov)
 {
+       GF_Err e;
        u32 i, j;
        u64 MaxDur;
        GF_TrackFragmentBox *traf;
@@ -45,9 +47,16 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov)
        MaxDur = 0;
 
        //we shall have a MOOV and its MVEX BEFORE any MOOF
-       if (!mov->moov || !mov->moov->mvex) return GF_ISOM_INVALID_FILE;
-       //and all fragments must be continous
-       if (mov->NextMoofNumber && (mov->NextMoofNumber >= moof->mfhd->sequence_number)) return GF_ISOM_INVALID_FILE;
+       if (!mov->moov || !mov->moov->mvex) {
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error: %s not received before merging frament\n", mov->moov ? "mvex" : "moov" ));
+               return GF_ISOM_INVALID_FILE;
+       }
+       //and all fragments must be continous - we do not throw an error as we may still want to be able to concatenate depednent representation in DASH and
+       //we will likely a-have R1(moofSN 1, 3, 5, 7) plus R2(moofSN 2, 4, 6, 8) 
+       if (mov->NextMoofNumber && (mov->NextMoofNumber >= moof->mfhd->sequence_number)) {
+               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Warning: wrong sequence number: got %d but last one was %d\n", moof->mfhd->sequence_number, mov->NextMoofNumber));
+//             return GF_ISOM_INVALID_FILE;
+       }
 
        i=0;
        while ((traf = (GF_TrackFragmentBox*)gf_list_enum(moof->TrackList, &i))) {
@@ -62,17 +71,23 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov)
                                traf->trex = NULL;
                        }
                }
-               if (!trak || !traf->trex) return GF_ISOM_INVALID_FILE;
 
-               MergeTrack(trak, traf, mov->current_top_box_start, !mov->first_moof_merged);
+               if (!trak || !traf->trex) {
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error: Cannot find fragment track with ID %d\n", traf->tfhd->trackID));
+                       return GF_ISOM_INVALID_FILE;
+               }
+
+               e = MergeTrack(trak, traf, mov->current_top_box_start, !trak->first_traf_merged);
+               if (e) return e;
 
                //update trak duration
                SetTrackDuration(trak);
                if (trak->Header->duration > MaxDur) 
                        MaxDur = trak->Header->duration;
+
+               trak->first_traf_merged = 1;
        }
 
-       mov->first_moof_merged = 1;
        mov->NextMoofNumber = moof->mfhd->sequence_number;
        //update movie duration
        if (mov->moov->mvhd->duration < MaxDur) mov->moov->mvhd->duration = MaxDur;
@@ -224,7 +239,25 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing, Bool progre
             mov->moof = (GF_MovieFragmentBox *) a;
                        /*read & debug: store at root level*/
                        if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {
-                gf_list_add(mov->TopBoxes, a);
+                u32 k;
+                               gf_list_add(mov->TopBoxes, a);
+                               /*also update pointers to trex for debug*/
+                               if (mov->moov) {
+                                       for (k=0; k<gf_list_count(mov->moof->TrackList); k++) {
+                                               GF_TrackFragmentBox *traf = gf_list_get(mov->moof->TrackList, k);
+                                               if (traf->tfhd) {
+                                                       GF_TrackBox *trak = gf_isom_get_track_from_id(mov->moov, traf->tfhd->trackID);
+                                                       u32 j=0;
+                                                       while ((traf->trex = (GF_TrackExtendsBox*)gf_list_enum(mov->moov->mvex->TrackExList, &j))) {
+                                                               if (traf->trex->trackID == traf->tfhd->trackID) {
+                                                                       if (!traf->trex->track) traf->trex->track = trak;
+                                                                       break;
+                                                               }
+                                                               traf->trex = NULL;
+                                                       }
+                                               }
+                                       }
+                               }
                        } else if (mov->openMode==GF_ISOM_OPEN_CAT_FRAGMENTS) {
                                mov->NextMoofNumber = mov->moof->mfhd->sequence_number+1;
                                mov->moof = NULL;
@@ -233,9 +266,6 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing, Bool progre
                                /*merge all info*/
                                e = MergeFragment((GF_MovieFragmentBox *)a, mov);
                                gf_isom_box_del(a);
-                               if (e) {
-                                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error merging fragment: %s\n", gf_error_to_string(e) ));
-                               }
                        }
                        break;
 #endif
@@ -294,7 +324,6 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing, Bool progre
        return GF_OK;
 }
 
-
 GF_ISOFile *gf_isom_new_movie()
 {
        GF_ISOFile *mov = (GF_ISOFile*)gf_malloc(sizeof(GF_ISOFile));
@@ -764,14 +793,14 @@ GF_EdtsEntry *CreateEditEntry(u64 EditDuration, u64 MediaTime, u8 EditMode)
 GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable)
 {
        u32 i, count, last_sample;
-       GF_SampleEntry *pSamp;
+       GF_SubSampleInfoEntry *pSamp;
        GF_SubSampleEntry *pSubSamp;
 
        pSamp = NULL;
        last_sample = 0;
        count = gf_list_count(sub_samples->Samples);
        for (i=0; i<count; i++) {
-               pSamp = (GF_SampleEntry*) gf_list_get(sub_samples->Samples, i);
+               pSamp = (GF_SubSampleInfoEntry*) gf_list_get(sub_samples->Samples, i);
                /*TODO - do we need to support insertion of subsample info ?*/
                if (last_sample + pSamp->sample_delta > sampleNumber) return GF_NOT_SUPPORTED; 
                if (last_sample + pSamp->sample_delta == sampleNumber) break; 
@@ -780,7 +809,7 @@ GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 s
        }
 
        if (!pSamp) {
-               GF_SAFEALLOC(pSamp, GF_SampleEntry);
+               GF_SAFEALLOC(pSamp, GF_SubSampleInfoEntry);
                if (!pSamp) return GF_OUT_OF_MEM;
                pSamp->SubSamples = gf_list_new();
                if (!pSamp->SubSamples ) {
@@ -818,7 +847,7 @@ GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 s
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
-u32 gf_isom_sample_get_subsample_entry(GF_ISOFile *movie, u32 track, u32 sampleNumber, GF_SampleEntry **sub_sample)
+u32 gf_isom_sample_get_subsample_entry(GF_ISOFile *movie, u32 track, u32 sampleNumber, GF_SubSampleInfoEntry **sub_sample)
 {
        u32 i, count, last_sample;
        GF_SubSampleInformationBox *sub_samples;
@@ -831,7 +860,7 @@ u32 gf_isom_sample_get_subsample_entry(GF_ISOFile *movie, u32 track, u32 sampleN
        last_sample = 0;
        count = gf_list_count(sub_samples->Samples);
        for (i=0; i<count; i++) {
-               GF_SampleEntry*pSamp = (GF_SampleEntry*) gf_list_get(sub_samples->Samples, i);
+               GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry *) gf_list_get(sub_samples->Samples, i);
                if (last_sample + pSamp->sample_delta == sampleNumber) {
                        if (sub_sample) *sub_sample = pSamp;
                        return gf_list_count(pSamp->SubSamples);
index 94bc82d1fd5476c10ef9422e1ebce920e365fa9a..8638353a4105bcc1dcc7b6a47d618f84df76c986 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -109,6 +110,11 @@ Bool gf_isom_probe_file(const char *fileName)
 #ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
        case GF_ISOM_BOX_TYPE_MOOF:
        case GF_ISOM_BOX_TYPE_STYP:
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+       /*Adobe specific*/
+       case GF_ISOM_BOX_TYPE_AFRA:
+       case GF_ISOM_BOX_TYPE_ABST:
+#endif
 #endif
        case GF_ISOM_BOX_TYPE_FREE:
        case GF_ISOM_BOX_TYPE_SKIP:
@@ -438,6 +444,7 @@ u32 gf_isom_get_timescale(GF_ISOFile *movie)
        return movie->moov->mvhd->timeScale;
 }
 
+
 //return the duration of the movie, 0 if error
 GF_EXPORT
 u64 gf_isom_get_duration(GF_ISOFile *movie)
@@ -677,7 +684,7 @@ u32 gf_isom_get_sample_description_count(GF_ISOFile *the_file, u32 trackNumber)
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak) return 0;
 
-       return gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       return gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
 }
 
 
@@ -757,7 +764,7 @@ u32 gf_isom_get_copyright_count(GF_ISOFile *mov)
        if (!mov || !mov->moov || !mov->moov->udta) return 0;
        map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_CPRT, NULL);
        if (!map) return 0;
-       return gf_list_count(map->boxList);
+       return gf_list_count(map->other_boxes);
 }
 
 GF_EXPORT
@@ -772,9 +779,9 @@ GF_Err gf_isom_get_copyright(GF_ISOFile *mov, u32 Index, const char **threeCharC
        map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_CPRT, NULL);
        if (!map) return GF_OK;
 
-       if (Index > gf_list_count(map->boxList)) return GF_BAD_PARAM;
+       if (Index > gf_list_count(map->other_boxes)) return GF_BAD_PARAM;
 
-       cprt = (GF_CopyrightBox*)gf_list_get(map->boxList, Index-1);
+       cprt = (GF_CopyrightBox*)gf_list_get(map->other_boxes, Index-1);
        (*threeCharCode) = cprt->packedLanguageCode;
        (*notice) = cprt->notice;
        return GF_OK;
@@ -792,7 +799,7 @@ GF_Err gf_isom_get_watermark(GF_ISOFile *mov, bin128 UUID, u8** data, u32* lengt
        map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_UUID, (bin128 *) & UUID);
        if (!map) return GF_NOT_SUPPORTED;
 
-       wm = (GF_UnknownUUIDBox*)gf_list_get(map->boxList, 0);
+       wm = (GF_UnknownUUIDBox*)gf_list_get(map->other_boxes, 0);
        if (!wm) return GF_NOT_SUPPORTED;
 
        *data = (u8 *) gf_malloc(sizeof(char)*wm->dataSize);
@@ -821,7 +828,7 @@ u32 gf_isom_get_chapter_count(GF_ISOFile *movie, u32 trackNumber)
        if (!udta) return 0;
        map = udta_getEntry(udta, GF_ISOM_BOX_TYPE_CHPL, NULL);
        if (!map) return 0;
-       lst = (GF_ChapterListBox *)gf_list_get(map->boxList, 0);
+       lst = (GF_ChapterListBox *)gf_list_get(map->other_boxes, 0);
        if (!lst) return 0;
        return gf_list_count(lst->list);
 }
@@ -847,7 +854,7 @@ GF_Err gf_isom_get_chapter(GF_ISOFile *movie, u32 trackNumber, u32 Index, u64 *c
        if (!udta) return GF_BAD_PARAM;
        map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_CHPL, NULL);
        if (!map) return GF_BAD_PARAM;
-       lst = (GF_ChapterListBox *)gf_list_get(map->boxList, 0);
+       lst = (GF_ChapterListBox *)gf_list_get(map->other_boxes, 0);
        if (!lst) return GF_BAD_PARAM;
 
        ce = (GF_ChapterEntry *)gf_list_get(lst->list, Index-1);
@@ -904,7 +911,7 @@ u8 gf_isom_is_track_encrypted(GF_ISOFile *the_file, u32 trackNumber)
        GF_Box *entry;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak) return 2;
-       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0);
+       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, 0);
        if (!entry) return 2;
        return IsMP4EncryptedDescription(entry->type);
 }
@@ -916,7 +923,7 @@ u32 gf_isom_get_media_subtype(GF_ISOFile *the_file, u32 trackNumber, u32 Descrip
        GF_Box *entry;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !DescriptionIndex) return 0;
-       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!entry) return 0;
 
        //filter MPEG sub-types
@@ -943,7 +950,7 @@ u32 gf_isom_get_mpeg4_subtype(GF_ISOFile *the_file, u32 trackNumber, u32 Descrip
        GF_Box *entry;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !DescriptionIndex) return 0;
-       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!entry) return 0;
 
        //filter MPEG sub-types
@@ -1000,7 +1007,7 @@ GF_Err gf_isom_get_data_reference(GF_ISOFile *the_file, u32 trackNumber, u32 Str
        if (e) return e;
        if (!drefIndex) return GF_BAD_PARAM;
 
-       url = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, drefIndex - 1);
+       url = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->other_boxes, drefIndex - 1);
        if (!url) return GF_ISOM_INVALID_FILE;
 
        *outURL = *outURN = NULL;
@@ -1042,7 +1049,7 @@ u32 gf_isom_get_constant_sample_size(GF_ISOFile *the_file, u32 trackNumber)
 }
 
 GF_EXPORT
-Bool gf_isom_has_time_offset(GF_ISOFile *the_file, u32 trackNumber)
+u32 gf_isom_has_time_offset(GF_ISOFile *the_file, u32 trackNumber)
 {
        u32 i;
        GF_CompositionOffsetBox *ctts;
@@ -1053,7 +1060,7 @@ Bool gf_isom_has_time_offset(GF_ISOFile *the_file, u32 trackNumber)
        //return true at the first offset found
        ctts = trak->Media->information->sampleTable->CompositionOffset;
        for (i=0; i<ctts->nb_entries; i++) {
-               if (ctts->entries[i].decodingOffset && ctts->entries[i].sampleCount) return 1;
+               if (ctts->entries[i].decodingOffset && ctts->entries[i].sampleCount) return ctts->version ? 2 : 1;
        }
        return 0;
 }
@@ -1666,7 +1673,7 @@ u32 gf_isom_get_user_data_count(GF_ISOFile *movie, u32 trackNumber, u32 UserData
 
        i=0;
        while ((map = (GF_UserDataMap*)gf_list_enum(udta->recordList, &i))) {
-               count = gf_list_count(map->boxList);
+               count = gf_list_count(map->other_boxes);
 
                if ((map->boxType == GF_ISOM_BOX_TYPE_UUID) && !memcmp(map->uuid, UUID, 16)) return count;
                else if (map->boxType == UserDataType) return count;
@@ -1711,8 +1718,8 @@ GF_Err gf_isom_get_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataTyp
 
 found:
 
-       if (UserDataIndex > gf_list_count(map->boxList) ) return GF_BAD_PARAM;
-       ptr = (GF_UnknownBox*)gf_list_get(map->boxList, UserDataIndex-1);
+       if (UserDataIndex > gf_list_count(map->other_boxes) ) return GF_BAD_PARAM;
+       ptr = (GF_UnknownBox*)gf_list_get(map->other_boxes, UserDataIndex-1);
 
        //ok alloc the data
        *userData = (char *)gf_malloc(sizeof(char)*ptr->dataSize);
@@ -1769,7 +1776,7 @@ GF_Err gf_isom_get_chunks_infos(GF_ISOFile *movie, u32 trackNumber, u32 *dur_min
                        davg += chunk_dur;
                        if (smin>chunk_size) smin = chunk_size;
                        if (smax<chunk_size) smax = chunk_size;
-                       savg += chunk_dur;
+                       savg += chunk_size;
                        
                        tot_chunks ++;
                        sample_idx += stsc->entries[i].samplesPerChunk;
@@ -1778,8 +1785,10 @@ GF_Err gf_isom_get_chunks_infos(GF_ISOFile *movie, u32 trackNumber, u32 *dur_min
                        if (stsc->entries[i].firstChunk + nb_chunk == stsc->entries[i+1].firstChunk) break;
                }
        }
-       if (tot_chunks) davg /= tot_chunks;
-
+       if (tot_chunks) {
+               davg /= tot_chunks;
+               savg /= tot_chunks;
+       }
        if (dur_min) *dur_min = dmin;
        if (dur_avg) *dur_avg = (u32) davg;
        if (dur_max) *dur_max = dmax;
@@ -1954,6 +1963,7 @@ GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables)
 
        for (i=0; i<gf_list_count(movie->moov->trackList); i++) {
                GF_TrackBox *trak = gf_list_get(movie->moov->trackList, i);
+               trak->first_traf_merged = 0;
                if (trak->Media->information->dataHandler == movie->movieFileMap) {
                        trak->Media->information->dataHandler = NULL;
                }
@@ -1986,7 +1996,6 @@ GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables)
                }
        }
 
-       movie->first_moof_merged = 0;
        gf_isom_datamap_del(movie->movieFileMap);
        movie->movieFileMap = NULL;
 #endif
@@ -2053,7 +2062,7 @@ GF_GenericSampleDescription *gf_isom_get_generic_sample_description(GF_ISOFile *
        trak = gf_isom_get_track_from_file(movie, trackNumber);
        if (!trak || !StreamDescriptionIndex) return NULL;
 
-       entry = (GF_GenericVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex-1);
+       entry = (GF_GenericVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, StreamDescriptionIndex-1);
        //no entry or MPEG entry:
        if (!entry || IsMP4Description(entry->type) ) return NULL;
        //if we handle the description return false
@@ -2076,7 +2085,7 @@ GF_GenericSampleDescription *gf_isom_get_generic_sample_description(GF_ISOFile *
                udesc->revision = entry->revision;
                udesc->vendor_code = entry->vendor;
                udesc->temporal_quality = entry->temporal_quality;
-               udesc->spacial_quality = entry->spacial_quality;
+               udesc->spatial_quality = entry->spatial_quality;
                udesc->width = entry->Width;
                udesc->height = entry->Height;
                udesc->h_res = entry->horiz_res;
@@ -2140,9 +2149,9 @@ GF_Err gf_isom_get_visual_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDes
 
        stsd = trak->Media->information->sampleTable->SampleDescription;
        if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE;
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) return movie->LastError = GF_BAD_PARAM;
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) return movie->LastError = GF_BAD_PARAM;
 
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
 
@@ -2180,15 +2189,14 @@ GF_Err gf_isom_get_audio_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDesc
 
        stsd = trak->Media->information->sampleTable->SampleDescription;
        if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE;
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) return movie->LastError = GF_BAD_PARAM;
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) return movie->LastError = GF_BAD_PARAM;
 
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
 
        switch (entry->type) {
        case GF_ISOM_BOX_TYPE_ENCA:
-               if (entry->protection_info && (entry->protection_info->original_format->data_format!= GF_ISOM_BOX_TYPE_MP4A)) return GF_ISOM_INVALID_MEDIA;
        case GF_ISOM_BOX_TYPE_MP4A:
        case GF_ISOM_SUBTYPE_3GP_AMR:
        case GF_ISOM_SUBTYPE_3GP_AMR_WB:
@@ -2217,9 +2225,9 @@ GF_Err gf_isom_get_pixel_aspect_ratio(GF_ISOFile *movie, u32 trackNumber, u32 St
 
        stsd = trak->Media->information->sampleTable->SampleDescription;
        if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE;
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) return movie->LastError = GF_BAD_PARAM;
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) return movie->LastError = GF_BAD_PARAM;
 
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
 
@@ -2533,7 +2541,7 @@ GF_Err gf_isom_apple_get_tag(GF_ISOFile *mov, u32 tag, const char **data, u32 *d
        if (tag==GF_ISOM_ITUNE_PROBE) return GF_OK;
 
        i=0;
-       while ( (info=gf_list_enum(ilst->tags, &i))) {
+       while ( (info=gf_list_enum(ilst->other_boxes, &i))) {
                if (info->type==tag) break;
                /*special cases*/
                if ((tag==GF_ISOM_ITUNE_GENRE) && (info->type==(u32) GF_ISOM_BOX_TYPE_0xA9GEN)) break;
@@ -2573,7 +2581,7 @@ GF_Err gf_isom_get_track_switch_group_count(GF_ISOFile *movie, u32 trackNumber,
 
        map = udta_getEntry(trak->udta, GF_ISOM_BOX_TYPE_TSEL, NULL);
        if (!map) return 0;
-       *nb_groups = gf_list_count(map->boxList);
+       *nb_groups = gf_list_count(map->other_boxes);
        return GF_OK;
 }
 
@@ -2589,7 +2597,7 @@ const u32 *gf_isom_get_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber
 
        map = udta_getEntry(trak->udta, GF_ISOM_BOX_TYPE_TSEL, NULL);
        if (!map) return NULL;
-       tsel = gf_list_get(map->boxList, group_index-1);
+       tsel = gf_list_get(map->other_boxes, group_index-1);
        *switchGroupID = tsel->switchGroup;
        *criteriaListSize = tsel->attributeListCount;
        return (const u32 *) tsel->attributeList;
@@ -2603,7 +2611,7 @@ GF_Err gf_isom_get_timed_meta_data_info(GF_ISOFile *file, u32 track, u32 sampleD
        GF_MetaDataSampleEntryBox *ptr;
        trak = gf_isom_get_track_from_file(file, track);
        if (!trak || !sampleDescription) return GF_BAD_PARAM;
-       ptr = (GF_MetaDataSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sampleDescription-1);
+       ptr = (GF_MetaDataSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, sampleDescription-1);
        if (!ptr) return GF_BAD_PARAM;
 
        if (ptr->type==GF_ISOM_BOX_TYPE_METX) {
@@ -2641,7 +2649,7 @@ u32 gf_isom_sample_has_subsamples(GF_ISOFile *movie, u32 track, u32 sampleNumber
 GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleNumber, u32 *size, u8 *priority, u32 *reserved, Bool *discardable)
 {
        GF_SubSampleEntry *entry;
-       GF_SampleEntry *sub_sample;
+       GF_SubSampleInfoEntry *sub_sample;
        u32 count = gf_isom_sample_get_subsample_entry(movie, track, sampleNumber, &sub_sample);
        if (!size || !priority || !discardable) return GF_BAD_PARAM;
 
@@ -2667,7 +2675,7 @@ GF_Err gf_isom_get_rvc_config(GF_ISOFile *movie, u32 track, u32 sampleDescriptio
        if (!trak) return GF_BAD_PARAM;
 
 
-       entry = (GF_MPEGVisualSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sampleDescriptionIndex-1);
+       entry = (GF_MPEGVisualSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, sampleDescriptionIndex-1);
        if (!entry ) return GF_BAD_PARAM;
        switch (entry->type) {
        case GF_ISOM_BOX_TYPE_MP4V:
@@ -2719,6 +2727,7 @@ void gf_isom_reset_fragment_info(GF_ISOFile *movie)
 #endif
 }
 
+GF_EXPORT
 GF_Err gf_isom_get_sample_rap_roll_info(GF_ISOFile *the_file, u32 trackNumber, u32 sample_number, Bool *is_rap, Bool *has_roll, s32 *roll_distance)
 {
        GF_TrackBox *trak;
@@ -2732,6 +2741,32 @@ GF_Err gf_isom_get_sample_rap_roll_info(GF_ISOFile *the_file, u32 trackNumber, u
        if (!trak) return GF_BAD_PARAM;
        if (!trak->Media->information->sampleTable->sampleGroups) return GF_OK;
 
+       if (!sample_number) {
+               count = gf_list_count(trak->Media->information->sampleTable->sampleGroupsDescription);
+               for (i=0; i<count; i++) {
+                       GF_SampleGroupDescriptionBox *sgdesc = gf_list_get(trak->Media->information->sampleTable->sampleGroupsDescription, i);
+                       switch (sgdesc->grouping_type) {
+                       case GF_4CC('r','a','p',' '):
+                               if (is_rap) *is_rap = 1;
+                               break;
+                       case GF_4CC('r','o','l','l'):
+                               if (has_roll) *has_roll = 1;
+                               if (roll_distance) {
+                                       s32 max_roll = 0;
+                                       u32 j;
+                                       for (j=0; j<gf_list_count(sgdesc->group_descriptions);j++) {
+                                               GF_RollRecoveryEntry *roll_entry = gf_list_get(sgdesc->group_descriptions, j);
+                                               if (max_roll < roll_entry->roll_distance) 
+                                                       max_roll = roll_entry->roll_distance;
+                                       }
+                                       if (*roll_distance < max_roll) *roll_distance = max_roll;
+                               }
+                               break;
+                       }
+               }
+               return GF_OK;
+       }
+
        count = gf_list_count(trak->Media->information->sampleTable->sampleGroups);
        for (i=0; i<count; i++) {
                GF_SampleGroupBox *sg;
@@ -2748,7 +2783,7 @@ GF_Err gf_isom_get_sample_rap_roll_info(GF_ISOFile *the_file, u32 trackNumber, u
                                continue;
                        }
                        /*we found our sample*/
-                       group_desc_index = sg->sample_entries[j].group_description_index;
+                       group_desc_index = 1 + sg->sample_entries[j].group_description_index;
                        break;
                }
                /*no sampleGroup info associated*/
@@ -2779,4 +2814,35 @@ GF_Err gf_isom_get_sample_rap_roll_info(GF_ISOFile *the_file, u32 trackNumber, u
        return GF_OK;
 }
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+//return the duration of the movie+fragments if known, 0 if error
+GF_EXPORT
+u64 gf_isom_get_fragmented_duration(GF_ISOFile *movie)
+{
+       if (movie->moov->mvex && movie->moov->mvex->mehd)
+               return movie->moov->mvex->mehd->fragment_duration;
+
+       return 0;
+}
+//return the duration of the movie+fragments if known, 0 if error
+GF_EXPORT
+u32 gf_isom_get_fragments_count(GF_ISOFile *movie, Bool segments_only)
+{
+       u32 i=0;
+       u32 nb_frags = 0;
+       GF_Box *b;
+       while ((b=gf_list_enum(movie->TopBoxes, &i))) {
+               if (segments_only) {
+                       if (b->type==GF_ISOM_BOX_TYPE_SIDX) 
+                               nb_frags++;
+               } else {
+                       if (b->type==GF_ISOM_BOX_TYPE_MOOF) 
+                               nb_frags++;
+               }
+       }
+       return nb_frags;
+}
+
+#endif
+
 #endif /*GPAC_DISABLE_ISOM*/
index 6a954e6b24531308fadf49f2aed01fccdf42c408..73c746b2f5516213bf1c08b73b9475908589010f 100644 (file)
@@ -2,7 +2,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -361,10 +362,12 @@ GF_Err WriteSample(MovieWriter *mw, u32 size, u64 offset, u8 isEdited, GF_BitStr
        }
        //get the payload...
        bytes = gf_isom_datamap_get_data(map, mw->buffer, size, offset);
-       if (bytes != size) return GF_IO_ERR;
+       if (bytes != size) 
+               return GF_IO_ERR;
        //write it to our stream...
        bytes = gf_bs_write_data(bs, mw->buffer, size);
-       if (bytes != size) return GF_IO_ERR;
+       if (bytes != size) 
+               return GF_IO_ERR;
 
        mw->nb_done++;
        gf_set_progress("ISO File Writing", mw->nb_done, mw->total_samples);
@@ -674,6 +677,10 @@ GF_Err WriteFlat(MovieWriter *mw, u8 moovFirst, GF_BitStream *bs)
                        case GF_ISOM_BOX_TYPE_META:
                        case GF_ISOM_BOX_TYPE_FTYP:
                        case GF_ISOM_BOX_TYPE_PDIN:
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+                       case GF_ISOM_BOX_TYPE_AFRA:
+                       case GF_ISOM_BOX_TYPE_ABST:
+#endif
                                break;
                        case GF_ISOM_BOX_TYPE_MDAT:
                                //in case we're capturing
@@ -704,6 +711,21 @@ GF_Err WriteFlat(MovieWriter *mw, u8 moovFirst, GF_BitStream *bs)
                e = WriteMoovAndMeta(movie, writers, bs);
                if (e) goto exit;
 
+#ifndef GPAC_DISABLE_ISOM_ADOBE
+               i=0;
+               while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
+                       switch (a->type) {
+                       case GF_ISOM_BOX_TYPE_AFRA:
+                       case GF_ISOM_BOX_TYPE_ABST:
+                               e = gf_isom_box_size(a);
+                               if (e) goto exit;
+                               e = gf_isom_box_write(a, bs);
+                               if (e) goto exit;
+                               break;
+                       }
+               }
+#endif
+
                /*if data has been written, update mdat size*/
                if (totSize) {
                        offset = gf_bs_get_position(bs);
@@ -958,9 +980,9 @@ GF_Err DoInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emul
                memset(blank, 0, sizeof(char)*1024*1024);
                while (i<count) {
                        u32 res = gf_bs_write_data(bs, blank, 1024*1024);
-                       if (res != 1024*1024) fprintf(stdout, "error writing to disk: only %d bytes written\n", res);
+                       if (res != 1024*1024) fprintf(stderr, "error writing to disk: only %d bytes written\n", res);
                        i++;
-                       fprintf(stdout, "writing blank block: %.02f done - %d/%d \r", (100.0*i)/count , i, count);
+                       fprintf(stderr, "writing blank block: %.02f done - %d/%d \r", (100.0*i)/count , i, count);
                }
                gf_free(blank);
        }
@@ -1233,6 +1255,7 @@ exit:
        return e;
 }
 
+extern u32 default_write_buffering_size;
 
 GF_Err WriteToFile(GF_ISOFile *movie)
 {
@@ -1254,15 +1277,26 @@ GF_Err WriteToFile(GF_ISOFile *movie)
        if (movie->openMode == GF_ISOM_OPEN_WRITE) {
                e = WriteFlat(&mw, 0, movie->editFileMap->bs);
        } else {
+               u32 buffer_size = movie->editFileMap ? gf_bs_get_output_buffering(movie->editFileMap->bs) : 0;
+               Bool is_stdout = 0;
+               if (!strcmp(movie->finalName, "std"))
+                       is_stdout = 1;
+
                //OK, we need a new bitstream
-               stream = gf_f64_open(movie->finalName, "w+b");
-               if (!stream) return GF_IO_ERR;
+               stream = is_stdout ? stdout : gf_f64_open(movie->finalName, "w+b");
+               if (!stream) 
+                       return GF_IO_ERR;
                bs = gf_bs_from_file(stream, GF_BITSTREAM_WRITE);
                if (!bs) {
-                       fclose(stream);
+                       if (!is_stdout)
+                               fclose(stream);
                        return GF_OUT_OF_MEM;
                }
 
+               if (buffer_size) {
+                       gf_bs_set_output_buffering(bs, buffer_size);
+               }
+
                switch (movie->storageMode) {
                case GF_ISOM_STORE_TIGHT:
                case GF_ISOM_STORE_INTERLEAVED:
@@ -1280,7 +1314,8 @@ GF_Err WriteToFile(GF_ISOFile *movie)
                }
                
                gf_bs_del(bs);
-               fclose(stream);
+               if (!is_stdout)
+                       fclose(stream);
        }
        if (mw.buffer) gf_free(mw.buffer);
        if (mw.nb_done<mw.total_samples) {
index 0ab755a20ec76f6c82081c67925c6e52322e77eb..f94d4df2a1002823ccf32faaf922b87539411318 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -621,7 +622,7 @@ GF_Err gf_isom_add_sample(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescript
 
 
        //get this dataRef and return false if not self contained
-       Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);
+       Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->other_boxes, dataRefIndex - 1);
        if (!Dentry || Dentry->flags != 1) return GF_BAD_PARAM;
 
        //Open our data map. We are adding stuff, so use EDIT
@@ -690,7 +691,7 @@ GF_Err gf_isom_add_sample_shadow(GF_ISOFile *movie, u32 trackNumber, GF_ISOSampl
        trak->Media->information->sampleTable->currentEntryIndex = descIndex;
 
        //get this dataRef and return false if not self contained
-       Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);
+       Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->other_boxes, dataRefIndex - 1);
        if (!Dentry || Dentry->flags != 1) return GF_BAD_PARAM;
 
        //Open our data map. We are adding stuff, so use EDIT
@@ -763,7 +764,7 @@ GF_Err gf_isom_append_sample_data(GF_ISOFile *movie, u32 trackNumber, char *data
        if (!entry || !dataRefIndex) return GF_BAD_PARAM;
 
        //get this dataRef and return false if not self contained
-       Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);
+       Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->other_boxes, dataRefIndex - 1);
        if (!Dentry || Dentry->flags != 1) return GF_BAD_PARAM;
 
        //Open our data map. We are adding stuff, so use EDIT
@@ -820,7 +821,7 @@ GF_Err gf_isom_add_sample_reference(GF_ISOFile *movie, u32 trackNumber, u32 Stre
 
 
        //get this dataRef and return false if self contained
-       Dentry =(GF_DataEntryURLBox*) gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);
+       Dentry =(GF_DataEntryURLBox*) gf_list_get(trak->Media->information->dataInformation->dref->other_boxes, dataRefIndex - 1);
        if (Dentry->flags == 1) return GF_BAD_PARAM;
 
        //add the meta data
@@ -1126,10 +1127,10 @@ GF_Err gf_isom_change_mpeg4_description(GF_ISOFile *movie, u32 trackNumber, u32
        stsd = trak->Media->information->sampleTable->SampleDescription;
        if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE;
 
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) {
                return movie->LastError = GF_BAD_PARAM;
        }
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
 
@@ -1156,10 +1157,10 @@ GF_Err gf_isom_set_visual_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDes
        if (!stsd) {
                return movie->LastError = GF_ISOM_INVALID_FILE;
        }
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) {
                return movie->LastError = GF_BAD_PARAM;
        }
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
        trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
@@ -1202,10 +1203,10 @@ GF_Err gf_isom_set_pixel_aspect_ratio(GF_ISOFile *movie, u32 trackNumber, u32 St
 
        stsd = trak->Media->information->sampleTable->SampleDescription;
        if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE;
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) {
                return movie->LastError = GF_BAD_PARAM;
        }
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
        trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
@@ -1248,10 +1249,10 @@ GF_Err gf_isom_set_audio_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDesc
        if (!stsd) {
                return movie->LastError = GF_ISOM_INVALID_FILE;
        }
-       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {
+       if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->other_boxes)) {
                return movie->LastError = GF_BAD_PARAM;
        }
-       entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox *)gf_list_get(stsd->other_boxes, StreamDescriptionIndex - 1);
        //no support for generic sample entries (eg, no MPEG4 descriptor)
        if (entry == NULL) return GF_BAD_PARAM;
        trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
@@ -1587,10 +1588,10 @@ GF_Err gf_isom_remove_track(GF_ISOFile *movie, u32 trackNumber)
        i=0;
        while ((trak = (GF_TrackBox *)gf_list_enum(movie->moov->trackList, &i))) {
                if (trak == the_trak) continue;
-               if (! trak->References || ! gf_list_count(trak->References->boxList)) continue;
+               if (! trak->References || ! gf_list_count(trak->References->other_boxes)) continue;
                
                j=0;
-               while ((tref = (GF_TrackReferenceTypeBox *)gf_list_enum(trak->References->boxList, &j))) {
+               while ((tref = (GF_TrackReferenceTypeBox *)gf_list_enum(trak->References->other_boxes, &j))) {
                        found = 0;
                        for (k=0; k<tref->trackIDCount; k++) {
                                if (tref->trackIDs[k] == the_trak->Header->trackID) found++;
@@ -1600,7 +1601,7 @@ GF_Err gf_isom_remove_track(GF_ISOFile *movie, u32 trackNumber)
                        if (found == tref->trackIDCount) {
                                gf_isom_box_del((GF_Box *)tref);
                                j--;
-                               gf_list_rem(trak->References->boxList, j);
+                               gf_list_rem(trak->References->other_boxes, j);
                        } else {
                                newRefs = (u32*)gf_malloc(sizeof(u32) * (tref->trackIDCount - found));
                                found = 0;
@@ -1617,7 +1618,7 @@ GF_Err gf_isom_remove_track(GF_ISOFile *movie, u32 trackNumber)
                        }
                }
                //a little opt: remove the ref box if empty...
-               if (! gf_list_count(trak->References->boxList)) {
+               if (! gf_list_count(trak->References->other_boxes)) {
                        gf_isom_box_del((GF_Box *)trak->References);
                        trak->References = NULL;
                }
@@ -1660,9 +1661,9 @@ GF_Err gf_isom_set_copyright(GF_ISOFile *movie, const char *threeCharCode, char
        
        if (map) {
                //try to find one in our language...
-               count = gf_list_count(map->boxList);
+               count = gf_list_count(map->other_boxes);
                for (i=0; i<count; i++) {
-                       ptr = (GF_CopyrightBox*)gf_list_get(map->boxList, i);
+                       ptr = (GF_CopyrightBox*)gf_list_get(map->other_boxes, i);
                        if (!strcmp(threeCharCode, (const char *) ptr->packedLanguageCode)) {
                                gf_free(ptr->notice);
                                ptr->notice = (char*)gf_malloc(sizeof(char) * (strlen(notice) + 1));
@@ -1718,12 +1719,12 @@ GF_Err gf_isom_add_chapter(GF_ISOFile *movie, u32 trackNumber, u64 timestamp, ch
                e = udta_AddBox(udta, (GF_Box *) ptr);
                if (e) return e;
        } else {
-               ptr = (GF_ChapterListBox*)gf_list_get(map->boxList, 0);
+               ptr = (GF_ChapterListBox*)gf_list_get(map->other_boxes, 0);
        }
        /*this may happen if original MP4 is not properly formatted*/
        if (!ptr) {
                ptr = (GF_ChapterListBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_CHPL);
-               gf_list_add(map->boxList, ptr);
+               gf_list_add(map->other_boxes, ptr);
        }
 
        GF_SAFEALLOC(ce, GF_ChapterEntry);
@@ -1777,7 +1778,7 @@ GF_Err gf_isom_remove_chapter(GF_ISOFile *movie, u32 trackNumber, u32 index)
 
        map = udta_getEntry(udta, GF_ISOM_BOX_TYPE_CHPL, NULL);
        if (!map) return GF_OK;
-       ptr = (GF_ChapterListBox*)gf_list_get(map->boxList, 0);
+       ptr = (GF_ChapterListBox*)gf_list_get(map->other_boxes, 0);
        if (!ptr) return GF_OK;
        
        if (index) {
@@ -1796,7 +1797,7 @@ GF_Err gf_isom_remove_chapter(GF_ISOFile *movie, u32 trackNumber, u32 index)
        }
        if (!gf_list_count(ptr->list)) {
                gf_list_del_item(udta->recordList, map);
-               gf_isom_box_array_del(map->boxList);
+               gf_isom_box_array_del(map->other_boxes);
                gf_free(map);
        }
        return GF_OK;
@@ -1819,19 +1820,19 @@ GF_Err gf_isom_remove_copyright(GF_ISOFile *movie, u32 index)
        map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_CPRT, NULL);
        if (!map) return GF_OK;
 
-       count = gf_list_count(map->boxList);
+       count = gf_list_count(map->other_boxes);
        if (index>count) return GF_BAD_PARAM;
 
-       ptr = (GF_CopyrightBox*)gf_list_get(map->boxList, index-1);
+       ptr = (GF_CopyrightBox*)gf_list_get(map->other_boxes, index-1);
        if (ptr) {
-               gf_list_rem(map->boxList, index-1);
+               gf_list_rem(map->other_boxes, index-1);
                if (ptr->notice) gf_free(ptr->notice);
                gf_free(ptr);
        }
        /*last copyright, remove*/
-       if (!gf_list_count(map->boxList)) {
+       if (!gf_list_count(map->other_boxes)) {
                gf_list_del_item(movie->moov->udta->recordList, map);
-               gf_list_del(map->boxList);
+               gf_list_del(map->other_boxes);
                gf_free(map);
        }
        return GF_OK;
@@ -1856,7 +1857,7 @@ GF_Err gf_isom_set_watermark(GF_ISOFile *movie, bin128 UUID, u8* data, u32 lengt
        
        map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_UUID, (bin128 *) & UUID);
        if (map) {
-               ptr = (GF_UnknownUUIDBox *)gf_list_get(map->boxList, 0);
+               ptr = (GF_UnknownUUIDBox *)gf_list_get(map->other_boxes, 0);
                if (ptr) {
                        gf_free(ptr->data);
                        ptr->data = (char*)gf_malloc(length);
@@ -2162,17 +2163,17 @@ GF_Err gf_isom_remove_user_data_item(GF_ISOFile *movie, u32 trackNumber, u32 Use
 
 found:
 
-       if (UserDataIndex > gf_list_count(map->boxList) ) return GF_BAD_PARAM;
+       if (UserDataIndex > gf_list_count(map->other_boxes) ) return GF_BAD_PARAM;
        //delete the box
-       a = (GF_Box*)gf_list_get(map->boxList, UserDataIndex-1);
+       a = (GF_Box*)gf_list_get(map->other_boxes, UserDataIndex-1);
        
-       gf_list_rem(map->boxList, UserDataIndex-1);
+       gf_list_rem(map->other_boxes, UserDataIndex-1);
        gf_isom_box_del(a);
 
        //remove the map if empty
-       if (!gf_list_count(map->boxList)) {
+       if (!gf_list_count(map->other_boxes)) {
                gf_list_rem(udta->recordList, i-1);
-               gf_isom_box_array_del(map->boxList);
+               gf_isom_box_array_del(map->other_boxes);
                gf_free(map);
        }
        //but we keep the UDTA no matter what
@@ -2214,7 +2215,7 @@ GF_Err gf_isom_remove_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserData
 found:
 
        gf_list_rem(udta->recordList, i-1);
-       gf_isom_box_array_del(map->boxList);
+       gf_isom_box_array_del(map->other_boxes);
        gf_free(map);
 
        //but we keep the UDTA no matter what
@@ -2334,7 +2335,7 @@ GF_Err gf_isom_clone_pl_indications(GF_ISOFile *orig, GF_ISOFile *dest)
        return GF_OK;
 }
 
-static GF_Err clone_box(GF_Box *src, GF_Box **dst)
+GF_Err gf_isom_clone_box(GF_Box *src, GF_Box **dst)
 {
        GF_Err e;
        char *data;
@@ -2362,6 +2363,8 @@ static GF_Err clone_box(GF_Box *src, GF_Box **dst)
 GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool clone_tracks, Bool keep_hint_tracks)
 {
        GF_Err e;
+       u32 i;
+       GF_Box *box;
        
        e = CanAccessMovie(dest_file, GF_ISOM_OPEN_WRITE);
        if (e) return e;
@@ -2370,7 +2373,7 @@ GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool cl
                gf_list_del_item(dest_file->TopBoxes, dest_file->brand);
                gf_isom_box_del((GF_Box *)dest_file->brand);
                dest_file->brand = NULL;
-               clone_box((GF_Box *)orig_file->brand, (GF_Box **)&dest_file->brand);
+               gf_isom_clone_box((GF_Box *)orig_file->brand, (GF_Box **)&dest_file->brand);
                if (dest_file->brand) gf_list_add(dest_file->TopBoxes, dest_file->brand);
        }
 
@@ -2379,7 +2382,7 @@ GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool cl
                gf_isom_box_del((GF_Box *)dest_file->meta);
                dest_file->meta = NULL;
                /*fixme - check imports*/
-               clone_box((GF_Box *)orig_file->meta, (GF_Box **)dest_file->meta);
+               gf_isom_clone_box((GF_Box *)orig_file->meta, (GF_Box **)&dest_file->meta);
                if (dest_file->meta) gf_list_add(dest_file->TopBoxes, dest_file->meta);
        }
        if (orig_file->moov) {
@@ -2390,7 +2393,7 @@ GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool cl
                orig_file->moov->trackList = tracks;
                iods = (GF_Box*)orig_file->moov->iods;
                orig_file->moov->iods = NULL;
-               clone_box((GF_Box *)orig_file->moov, (GF_Box **)&dest_file->moov);
+               gf_isom_clone_box((GF_Box *)orig_file->moov, (GF_Box **)&dest_file->moov);
                orig_file->moov->trackList = old_tracks;
                gf_list_del(tracks);
                orig_file->moov->iods = (GF_ObjectDescriptorBox*)iods;
@@ -2404,13 +2407,40 @@ GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool cl
                                }
                        }
                        if (iods) 
-                               clone_box((GF_Box *)orig_file->moov->iods, (GF_Box **)dest_file->moov->iods);
+                               gf_isom_clone_box((GF_Box *)orig_file->moov->iods, (GF_Box **)dest_file->moov->iods);
                } else {
                        dest_file->moov->mvhd->nextTrackID = 1;
                        gf_isom_clone_pl_indications(orig_file, dest_file);
                }
                dest_file->moov->mov = dest_file;
        }
+
+       //duplicate other boxes
+       i=0;
+       while ((box = (GF_Box*)gf_list_get(orig_file->TopBoxes, i++))) {
+               switch(box->type) {
+                       case GF_ISOM_BOX_TYPE_MOOV:
+                       case GF_ISOM_BOX_TYPE_META:
+                       case GF_ISOM_BOX_TYPE_MDAT:
+                       case GF_ISOM_BOX_TYPE_FTYP:
+                       case GF_ISOM_BOX_TYPE_PDIN:
+#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
+                       case GF_ISOM_BOX_TYPE_STYP:
+                       case GF_ISOM_BOX_TYPE_SIDX:
+                       case GF_ISOM_BOX_TYPE_MOOF:
+#endif
+                       case GF_4CC('j','P',' ',' '):
+                               break;
+                       default:
+                               {
+                                       GF_Box *box2 = NULL;
+                                       gf_isom_clone_box(box, &box2);
+                                       gf_list_add(dest_file->TopBoxes, box2);
+                               }
+                               break;
+               }
+       }
+
        return GF_OK;
 }
 
@@ -2494,10 +2524,10 @@ GF_Err gf_isom_clone_track(GF_ISOFile *orig_file, u32 orig_track, GF_ISOFile *de
 
        /*reset data ref*/
        if (!keep_data_ref) {
-               gf_isom_box_array_del(new_tk->Media->information->dataInformation->dref->boxList);
-               new_tk->Media->information->dataInformation->dref->boxList = gf_list_new();
+               gf_isom_box_array_del(new_tk->Media->information->dataInformation->dref->other_boxes);
+               new_tk->Media->information->dataInformation->dref->other_boxes = gf_list_new();
                /*update data ref*/
-               entry = (GF_SampleEntryBox*)gf_list_get(new_tk->Media->information->sampleTable->SampleDescription->boxList, 0);
+               entry = (GF_SampleEntryBox*)gf_list_get(new_tk->Media->information->sampleTable->SampleDescription->other_boxes, 0);
                if (entry) {
                        u32 dref;
                        Media_CreateDataRef(new_tk->Media->information->dataInformation->dref, NULL, NULL, &dref);
@@ -2526,11 +2556,11 @@ GF_Err gf_isom_clone_sample_descriptions(GF_ISOFile *the_file, u32 trackNumber,
        if (!src_trak || !src_trak->Media) return GF_BAD_PARAM;
 
        if (reset_existing) {
-               gf_isom_box_array_del(dst_trak->Media->information->sampleTable->SampleDescription->boxList);
-               dst_trak->Media->information->sampleTable->SampleDescription->boxList = gf_list_new();
+               gf_isom_box_array_del(dst_trak->Media->information->sampleTable->SampleDescription->other_boxes);
+               dst_trak->Media->information->sampleTable->SampleDescription->other_boxes = gf_list_new();
        }
 
-       for (i=0; i<gf_list_count(src_trak->Media->information->sampleTable->SampleDescription->boxList); i++) {
+       for (i=0; i<gf_list_count(src_trak->Media->information->sampleTable->SampleDescription->other_boxes); i++) {
                u32 outDesc;
                e = gf_isom_clone_sample_description(the_file, trackNumber, orig_file, orig_track, i+1, NULL, NULL, &outDesc);
                if (e) break;
@@ -2557,7 +2587,7 @@ GF_Err gf_isom_clone_sample_description(GF_ISOFile *the_file, u32 trackNumber, G
        trak = gf_isom_get_track_from_file(orig_file, orig_track);
        if (!trak || !trak->Media) return GF_BAD_PARAM;
 
-       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, orig_desc_index-1);
+       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, orig_desc_index-1);
        if (!entry) return GF_BAD_PARAM;
 
        bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
@@ -2586,8 +2616,8 @@ GF_Err gf_isom_clone_sample_description(GF_ISOFile *the_file, u32 trackNumber, G
        trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
        /*overwrite dref*/
        ((GF_SampleEntryBox *)entry)->dataReferenceIndex = dataRefIndex;
-       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry);
-       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
+       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
 
        /*also clone track w/h info*/   
        if (gf_isom_get_media_type(the_file, trackNumber) == GF_ISOM_MEDIA_VISUAL) {
@@ -2639,7 +2669,7 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber
                entry->version = udesc->version;
                entry->revision = udesc->revision;
                entry->temporal_quality = udesc->temporal_quality;
-               entry->spacial_quality = udesc->spacial_quality;
+               entry->spatial_quality = udesc->spatial_quality;
                entry->Width = udesc->width;
                entry->Height = udesc->height;
                strcpy(entry->compressor_name, udesc->compressor_name);
@@ -2657,7 +2687,7 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber
                        memcpy(entry->data, udesc->extension_buf, udesc->extension_buf_size);
                        entry->data_size = udesc->extension_buf_size;
                }
-               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry);
+               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
        }
        else if (trak->Media->handler->handlerType==GF_ISOM_MEDIA_AUDIO) {
                GF_GenericAudioSampleEntryBox *gena;
@@ -2689,7 +2719,7 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber
                        memcpy(gena->data, udesc->extension_buf, udesc->extension_buf_size);
                        gena->data_size = udesc->extension_buf_size;
                }
-               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, gena);
+               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, gena);
        }
        else {
                GF_GenericSampleEntryBox *genm;
@@ -2713,9 +2743,9 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber
                        memcpy(genm->data, udesc->extension_buf, udesc->extension_buf_size);
                        genm->data_size = udesc->extension_buf_size;
                }
-               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, genm);
+               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, genm);
        }
-       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        return e;
 }
 
@@ -2733,14 +2763,14 @@ GF_Err gf_isom_change_generic_sample_description(GF_ISOFile *movie, u32 trackNum
        trak = gf_isom_get_track_from_file(movie, trackNumber);
        if (!trak || !trak->Media || !StreamDescriptionIndex) return GF_BAD_PARAM;
 
-       entry = (GF_GenericVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex-1);
+       entry = (GF_GenericVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, StreamDescriptionIndex-1);
        if (!entry) return GF_BAD_PARAM;
        if (entry->type == GF_ISOM_BOX_TYPE_GNRV) {
                entry->vendor = udesc->vendor_code;
                entry->version = udesc->version;
                entry->revision = udesc->revision;
                entry->temporal_quality = udesc->temporal_quality;
-               entry->spacial_quality = udesc->spacial_quality;
+               entry->spatial_quality = udesc->spatial_quality;
                entry->Width = udesc->width;
                entry->Height = udesc->height;
                strcpy(entry->compressor_name, udesc->compressor_name);
@@ -2816,9 +2846,9 @@ GF_Err gf_isom_remove_sample_description(GF_ISOFile *movie, u32 trackNumber, u32
        if (e) return e;
        trak = gf_isom_get_track_from_file(movie, trackNumber);
        if (!trak || !trak->Media || !streamDescIndex) return GF_BAD_PARAM;
-       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, streamDescIndex-1);
+       entry = (GF_Box*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, streamDescIndex-1);
        if (!entry) return GF_BAD_PARAM;
-       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->boxList, streamDescIndex-1);
+       gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, streamDescIndex-1);
        gf_isom_box_del(entry);
        return GF_OK;
 }
@@ -2878,9 +2908,9 @@ GF_Err gf_isom_remove_track_reference(GF_ISOFile *the_file, u32 trackNumber, u32
        //last one
        if (dpnd->trackIDCount==1) {
                i=0;
-               while ((tmp = (GF_TrackReferenceTypeBox *)gf_list_enum(tref->boxList, &i))) {
+               while ((tmp = (GF_TrackReferenceTypeBox *)gf_list_enum(tref->other_boxes, &i))) {
                        if (tmp==dpnd) {
-                               gf_list_rem(tref->boxList, i-1);
+                               gf_list_rem(tref->other_boxes, i-1);
                                gf_isom_box_del((GF_Box *) dpnd);
                                return GF_OK;
                        }
@@ -2921,7 +2951,7 @@ GF_Err gf_isom_set_track_id(GF_ISOFile *movie, u32 trackNumber, u32 trackID)
        while ((a_trak = (GF_TrackBox*)gf_list_enum(movie->moov->trackList, &i))) {
                if (!a_trak->References) continue;
                j=0;
-               while ((ref = (GF_TrackReferenceTypeBox *)gf_list_enum(a_trak->References->boxList, &j))) {
+               while ((ref = (GF_TrackReferenceTypeBox *)gf_list_enum(a_trak->References->other_boxes, &j))) {
                        for (k=0; k<ref->trackIDCount; k++) {
                                if (ref->trackIDs[k]==trak->Header->trackID) {
                                        ref->trackIDs[k] = trackID;
@@ -3134,7 +3164,8 @@ GF_Err gf_isom_load_movie_config(GF_ISOFile *movie)
        return found_cfg ? GF_OK : GF_NOT_SUPPORTED;
 }
 
-GF_Err gf_isom_set_media_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 newTS)
+GF_EXPORT
+GF_Err gf_isom_set_media_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 newTS, Bool force_rescale)
 {
        Double scale;
        GF_TrackBox *trak;
@@ -3145,11 +3176,27 @@ GF_Err gf_isom_set_media_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 ne
        scale = newTS;
        scale /= trak->Media->mediaHeader->timeScale;
        trak->Media->mediaHeader->timeScale = newTS;
-       if (trak->editBox) {
-               GF_EdtsEntry *ent;
-               u32 i=0;
-               while ((ent = (GF_EdtsEntry*)gf_list_enum(trak->editBox->editList->entryList, &i))) {
-                       ent->mediaTime = (u32) (scale*ent->mediaTime);
+       if (!force_rescale) {
+               if (trak->editBox) {
+                       GF_EdtsEntry *ent;
+                       u32 i=0;
+                       while ((ent = (GF_EdtsEntry*)gf_list_enum(trak->editBox->editList->entryList, &i))) {
+                               ent->mediaTime = (u32) (scale*ent->mediaTime);
+                       }
+               }
+               if (trak->Media->information->sampleTable) {
+                       u32 i;
+                       GF_SampleTableBox *stbl = trak->Media->information->sampleTable;
+                       if (stbl->TimeToSample) {
+                               for (i=0; i<stbl->TimeToSample->nb_entries; i++) {
+                                       stbl->TimeToSample->entries[i].sampleDelta = (u32) (scale * stbl->TimeToSample->entries[i].sampleDelta);
+                               }
+                       }
+                       if (stbl->CompositionOffset) {
+                               for (i=0; i<stbl->CompositionOffset->nb_entries; i++) {
+                                       stbl->CompositionOffset->entries[i].decodingOffset = (u32) (scale * stbl->CompositionOffset->entries[i].decodingOffset);
+                               }
+                       }
                }
        }
        return SetTrackDuration(trak);
@@ -3175,18 +3222,18 @@ Bool gf_isom_is_same_sample_description(GF_ISOFile *f1, u32 tk1, u32 sdesc_index
        if (!trak2 || !trak2->Media) return 0;
 
        if (trak1->Media->handler->handlerType != trak2->Media->handler->handlerType) return 0;
-       count = gf_list_count(trak1->Media->information->sampleTable->SampleDescription->boxList);
-       if (count != gf_list_count(trak2->Media->information->sampleTable->SampleDescription->boxList)) {
+       count = gf_list_count(trak1->Media->information->sampleTable->SampleDescription->other_boxes);
+       if (count != gf_list_count(trak2->Media->information->sampleTable->SampleDescription->other_boxes)) {
                if (!sdesc_index1 && !sdesc_index2) return 0;
        }
 
        need_memcmp = 1;
        for (i=0; i<count; i++) {
-               GF_Box *ent1 = (GF_Box *)gf_list_get(trak1->Media->information->sampleTable->SampleDescription->boxList, i);
-               GF_Box *ent2 = (GF_Box *)gf_list_get(trak2->Media->information->sampleTable->SampleDescription->boxList, i);
+               GF_Box *ent1 = (GF_Box *)gf_list_get(trak1->Media->information->sampleTable->SampleDescription->other_boxes, i);
+               GF_Box *ent2 = (GF_Box *)gf_list_get(trak2->Media->information->sampleTable->SampleDescription->other_boxes, i);
 
-               if (sdesc_index1) ent1 = (GF_Box *)gf_list_get(trak1->Media->information->sampleTable->SampleDescription->boxList, sdesc_index1 - 1);
-               if (sdesc_index2) ent2 = (GF_Box *)gf_list_get(trak2->Media->information->sampleTable->SampleDescription->boxList, sdesc_index2 - 1);
+               if (sdesc_index1) ent1 = (GF_Box *)gf_list_get(trak1->Media->information->sampleTable->SampleDescription->other_boxes, sdesc_index1 - 1);
+               if (sdesc_index2) ent2 = (GF_Box *)gf_list_get(trak2->Media->information->sampleTable->SampleDescription->other_boxes, sdesc_index2 - 1);
 
                if (!ent1 || !ent2) return 0;
                if (ent1->type != ent2->type) return 0;
@@ -3199,8 +3246,8 @@ Bool gf_isom_is_same_sample_description(GF_ISOFile *f1, u32 tk1, u32 sdesc_index
                case GF_ISOM_BOX_TYPE_ENCA:
                case GF_ISOM_BOX_TYPE_ENCV:
                case GF_ISOM_BOX_TYPE_ENCS:
-                       Media_GetESD(trak1->Media, sdesc_index1 , &esd1, 1);
-                       Media_GetESD(trak2->Media, sdesc_index2 , &esd2, 1);
+                       Media_GetESD(trak1->Media, sdesc_index1 ? sdesc_index1 : i+1, &esd1, 1);
+                       Media_GetESD(trak2->Media, sdesc_index2 ? sdesc_index2 : i+1, &esd2, 1);
                        if (!esd1 || !esd2) continue;
                        need_memcmp = 0;
                        if (esd1->decoderConfig->streamType != esd2->decoderConfig->streamType) return 0;
@@ -3641,7 +3688,7 @@ GF_Err gf_isom_set_media_subtype(GF_ISOFile *movie, u32 trackNumber, u32 sampleD
        GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber);
        if (!trak || !sampleDescriptionIndex || !new_type) return GF_BAD_PARAM;
 
-       entry = (GF_SampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sampleDescriptionIndex - 1);
+       entry = (GF_SampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, sampleDescriptionIndex - 1);
        if (!entry) return GF_BAD_PARAM;
        entry->type = new_type;
        return GF_OK;
@@ -3667,13 +3714,13 @@ GF_Err gf_isom_remove_uuid(GF_ISOFile *movie, u32 trackNumber, bin128 UUID)
        } else if (trackNumber) {
                GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber);
                if (!trak) return GF_BAD_PARAM;
-               list = trak->boxes;
+               list = trak->other_boxes;
        } else {
                if (!movie) return GF_BAD_PARAM;
-               list = movie->moov->boxes;
+               list = movie->moov->other_boxes;
        }
        
-       count = gf_list_count(list);
+       count = list ? gf_list_count(list) : 0;
        for (i=0; i<count; i++) {
                GF_UnknownUUIDBox *uuid = (GF_UnknownUUIDBox *)gf_list_get(list, i);
                if (uuid->type != GF_ISOM_BOX_TYPE_UUID) continue;
@@ -3700,10 +3747,12 @@ GF_Err gf_isom_add_uuid(GF_ISOFile *movie, u32 trackNumber, bin128 UUID, char *d
        } else if (trackNumber) {
                GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber);
                if (!trak) return GF_BAD_PARAM;
-               list = trak->boxes;
+               if (!trak->other_boxes) trak->other_boxes = gf_list_new();
+               list = trak->other_boxes;
        } else {
                if (!movie) return GF_BAD_PARAM;
-               list = movie->moov->boxes;
+               if (!movie->moov->other_boxes) movie->moov->other_boxes = gf_list_new();
+               list = movie->moov->other_boxes;
        }
        
        GF_SAFEALLOC(uuid, GF_UnknownUUIDBox);
@@ -3745,9 +3794,9 @@ GF_Err gf_isom_apple_set_tag(GF_ISOFile *mov, u32 tag, const char *data, u32 dat
        }
        /*remove tag*/
        i = 0;
-       while ((info = gf_list_enum(ilst->tags, &i))) {
+       while ((info = gf_list_enum(ilst->other_boxes, &i))) {
                if (info->type==btype) {
-                       gf_list_rem(ilst->tags, i-1);
+                       gf_list_rem(ilst->other_boxes, i-1);
                        gf_isom_box_del((GF_Box *) info);
                        break;
                }
@@ -3806,7 +3855,7 @@ GF_Err gf_isom_apple_set_tag(GF_ISOFile *mov, u32 tag, const char *data, u32 dat
                info->data->flags = 0x15;
                gf_bs_del(bs);
        }
-       return gf_list_add(ilst->tags, info);
+       return gf_list_add(ilst->other_boxes, info);
 }
 
 GF_EXPORT
@@ -3858,9 +3907,9 @@ GF_Err gf_isom_set_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber, u3
                                u32 j, count;
                                map = udta_getEntry(a_trak->udta, GF_ISOM_BOX_TYPE_TSEL, NULL);
                                if (map) {
-                                       count = gf_list_count(map->boxList);
+                                       count = gf_list_count(map->other_boxes);
                                        for (j=0; j<count; j++) {
-                                               tsel = gf_list_get(map->boxList, j);
+                                               tsel = gf_list_get(map->other_boxes, j);
 
                                                if (*switchGroupID) {
                                                        if (tsel->switchGroup==next_switch_group_id) {
@@ -3893,9 +3942,9 @@ GF_Err gf_isom_set_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber, u3
 
                /*locate tsel box with no switch group*/
                if (map)  {
-                       u32 j, count = gf_list_count(map->boxList);
+                       u32 j, count = gf_list_count(map->other_boxes);
                        for (j=0; j<count; j++) {
-                               tsel = gf_list_get(map->boxList, j);
+                               tsel = gf_list_get(map->other_boxes, j);
                                if (tsel->switchGroup == *switchGroupID) break;
                                tsel = NULL;
                        }
@@ -3922,7 +3971,7 @@ void reset_tsel_box(GF_TrackBox *trak)
        map = udta_getEntry(trak->udta, GF_ISOM_BOX_TYPE_TSEL, NULL);
        if (map) {
                gf_list_del_item(trak->udta->recordList, map);
-               gf_isom_box_array_del(map->boxList);
+               gf_isom_box_array_del(map->other_boxes);
                gf_free(map);
        }
 
@@ -4001,8 +4050,8 @@ GF_Err gf_isom_timed_meta_data_config_new(GF_ISOFile *movie, u32 trackNumber, Bo
        if (content_encoding) metad->content_encoding = gf_strdup(content_encoding);
        if (schema_loc) metad->xml_schema_loc = gf_strdup(schema_loc);
 
-       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, metad);
-       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, metad);
+       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        return e;
 }
 
@@ -4045,7 +4094,7 @@ GF_Err gf_isom_set_rvc_config(GF_ISOFile *movie, u32 track, u32 sampleDescriptio
        if (!trak) return GF_BAD_PARAM;
 
 
-       entry = (GF_MPEGVisualSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sampleDescriptionIndex-1);
+       entry = (GF_MPEGVisualSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, sampleDescriptionIndex-1);
        if (!entry ) return GF_BAD_PARAM;
        switch (entry->type) {
        case GF_ISOM_BOX_TYPE_MP4V:
@@ -4259,6 +4308,107 @@ GF_Err gf_isom_set_sample_roll_group(GF_ISOFile *movie, u32 track, u32 sample_nu
        return gf_isom_set_sample_group_info(movie, track, sample_number, GF_4CC( 'r', 'o', 'l', 'l' ), &roll_distance, sg_roll_create_entry, sg_roll_compare_entry);
 }
 
+static GF_Err gf_isom_set_ctts_v1(GF_ISOFile *file, u32 track, GF_TrackBox *trak)
+{
+       u32 i, shift;
+       u64 duration;
+       GF_CompositionOffsetBox *ctts;
+       GF_CompositionToDecodeBox *cslg;
+       s32 leastCTTS, greatestCTTS;
+
+       ctts = trak->Media->information->sampleTable->CompositionOffset;
+       shift = ctts->entries[0].decodingOffset;
+       leastCTTS = 0;
+       greatestCTTS = 0; 
+       for (i=0; i<ctts->nb_entries; i++) {
+               ctts->entries[i].decodingOffset -= shift;
+               if ((s32)ctts->entries[i].decodingOffset < leastCTTS)
+                       leastCTTS = ctts->entries[i].decodingOffset;
+               if ((s32)ctts->entries[i].decodingOffset > greatestCTTS)
+                       greatestCTTS = ctts->entries[i].decodingOffset;
+       }
+       ctts->version = 1;
+
+
+       if (!trak->Media->information->sampleTable->CompositionToDecode)
+               trak->Media->information->sampleTable->CompositionToDecode = (GF_CompositionToDecodeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CSLG);
+
+       cslg = trak->Media->information->sampleTable->CompositionToDecode;
+
+       cslg->compositionToDTSShift = -leastCTTS;
+       cslg->leastDecodeToDisplayDelta = leastCTTS;
+       cslg->greatestDecodeToDisplayDelta = greatestCTTS;
+       cslg->compositionStartTime = 0;
+       /*for our use case (first CTS set to 0), the composition end time is the media duration if it fits on 32 bits*/
+       duration = gf_isom_get_media_duration(file, track);
+       cslg->compositionEndTime = (duration<0x7FFFFFFF) ? (s32) duration : 0;
+
+       gf_isom_set_brand_info(file, GF_ISOM_BRAND_ISO4, 0);
+       return GF_OK;
+}
+
+static GF_Err gf_isom_set_ctts_v0(GF_ISOFile *file, GF_TrackBox *trak)
+{
+       u32 i;
+       s32 shift;
+       GF_CompositionOffsetBox *ctts;
+       GF_CompositionToDecodeBox *cslg;
+
+       ctts = trak->Media->information->sampleTable->CompositionOffset;
+       
+       if (!trak->Media->information->sampleTable->CompositionToDecode) 
+       {
+               shift = 0;
+               for (i=0; i<ctts->nb_entries; i++) {
+                       if (-ctts->entries[i].decodingOffset > shift)
+                               shift = -ctts->entries[i].decodingOffset;
+               }
+               if (shift > 0)
+               {
+                       for (i=0; i<ctts->nb_entries; i++) {
+                               ctts->entries[i].decodingOffset += shift;
+                       }
+               }
+       }
+       else
+       {
+               cslg = trak->Media->information->sampleTable->CompositionToDecode;
+               shift = cslg->compositionToDTSShift;
+               for (i=0; i<ctts->nb_entries; i++) {
+                       ctts->entries[i].decodingOffset += shift;
+               }
+               gf_isom_box_del((GF_Box *)cslg);
+               trak->Media->information->sampleTable->CompositionToDecode = NULL;
+       }
+       ctts->version = 0;
+       gf_isom_set_brand_info(file, GF_ISOM_BRAND_ISOM, 1);
+       return GF_OK;
+}
+
+GF_EXPORT
+GF_Err gf_isom_set_composition_offset_mode(GF_ISOFile *file, u32 track, Bool use_negative_offsets)
+{
+       GF_Err e;
+       GF_TrackBox *trak;
+       GF_CompositionOffsetBox *ctts;
+
+       e = CanAccessMovie(file, GF_ISOM_OPEN_WRITE);
+       if (e) return e;
+
+       trak = gf_isom_get_track_from_file(file, track);
+       if (!trak) return GF_BAD_PARAM;
+
+       ctts = trak->Media->information->sampleTable->CompositionOffset;
+       if (!ctts) return GF_OK;
+
+       if (use_negative_offsets) {
+               if (ctts->version==1) return GF_OK;
+               return gf_isom_set_ctts_v1(file, track, trak);
+       } else {
+               if (ctts->version==0) return GF_OK;
+               return gf_isom_set_ctts_v0(file, trak);
+       }
+}
 
 
 #endif /*!defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE)*/
index c84bfa926e2c59370e8fe6469ac2dbbac5a50efe..24a6d200e98b5e7f49be4fdbc9a3b921d18f2a4f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -36,9 +37,9 @@ GF_Err Media_GetSampleDesc(GF_MediaBox *mdia, u32 SampleDescIndex, GF_SampleEntr
 
        stsd = mdia->information->sampleTable->SampleDescription;
        if (!stsd) return GF_ISOM_INVALID_FILE;
-       if (!SampleDescIndex || (SampleDescIndex > gf_list_count(stsd->boxList)) ) return GF_BAD_PARAM;
+       if (!SampleDescIndex || (SampleDescIndex > gf_list_count(stsd->other_boxes)) ) return GF_BAD_PARAM;
 
-       entry = (GF_SampleEntryBox*)gf_list_get(stsd->boxList, SampleDescIndex - 1);
+       entry = (GF_SampleEntryBox*)gf_list_get(stsd->other_boxes, SampleDescIndex - 1);
        if (!entry) return GF_ISOM_INVALID_FILE;
 
        if (out_entry) *out_entry = entry;
@@ -60,7 +61,7 @@ GF_Err Media_GetSampleDescIndex(GF_MediaBox *mdia, u64 DTS, u32 *sampleDescIndex
 
        if (!sampleNumber && !prevSampleNumber) {
                //we have to assume the track was created to be used... If we have a sampleDesc, OK
-               if (gf_list_count(mdia->information->sampleTable->SampleDescription->boxList)) {
+               if (gf_list_count(mdia->information->sampleTable->SampleDescription->other_boxes)) {
                        (*sampleDescIndex) = 1;
                        return GF_OK;
                }               
@@ -153,11 +154,11 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo
        GF_SampleDescriptionBox *stsd = mdia->information->sampleTable->SampleDescription;
        
        *out_esd = NULL;
-       if (!stsd || !stsd->boxList || !sampleDescIndex || (sampleDescIndex > gf_list_count(stsd->boxList)) )
+       if (!stsd || !stsd->other_boxes || !sampleDescIndex || (sampleDescIndex > gf_list_count(stsd->other_boxes)) )
                return GF_BAD_PARAM;
 
        esd = NULL;
-       entry = (GF_MPEGSampleEntryBox*)gf_list_get(stsd->boxList, sampleDescIndex - 1);
+       entry = (GF_MPEGSampleEntryBox*)gf_list_get(stsd->other_boxes, sampleDescIndex - 1);
        if (! entry) return GF_ISOM_INVALID_MEDIA;
 
        *out_esd = NULL;
@@ -396,9 +397,9 @@ GF_Err Media_CheckDataEntry(GF_MediaBox *mdia, u32 dataEntryIndex)
        GF_DataEntryURLBox *entry;
        GF_DataMap *map;
        GF_Err e;
-       if (!mdia || !dataEntryIndex || dataEntryIndex > gf_list_count(mdia->information->dataInformation->dref->boxList)) return GF_BAD_PARAM;
+       if (!mdia || !dataEntryIndex || dataEntryIndex > gf_list_count(mdia->information->dataInformation->dref->other_boxes)) return GF_BAD_PARAM;
 
-       entry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->boxList, dataEntryIndex - 1);
+       entry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, dataEntryIndex - 1);
        if (!entry) return GF_ISOM_INVALID_FILE;
        if (entry->flags == 1) return GF_OK;
        
@@ -424,7 +425,7 @@ Bool Media_IsSelfContained(GF_MediaBox *mdia, u32 StreamDescIndex)
 
        Media_GetSampleDesc(mdia, StreamDescIndex, &se, &drefIndex);
        if (!drefIndex) return 0;
-       a = (GF_FullBox*)gf_list_get(mdia->information->dataInformation->dref->boxList, drefIndex - 1);
+       a = (GF_FullBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, drefIndex - 1);
        if (!a) {
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] broken file: Data reference index set to %d but no data reference entry found\n", drefIndex));
                return 0;
@@ -488,7 +489,7 @@ GF_Err Media_FindDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNname
        if (!dref) return GF_BAD_PARAM;
        *dataRefIndex = 0;
        i=0;
-       while ((entry = (GF_DataEntryURLBox*)gf_list_enum(dref->boxList, &i))) {
+       while ((entry = (GF_DataEntryURLBox*)gf_list_enum(dref->other_boxes, &i))) {
                if (entry->type == GF_ISOM_BOX_TYPE_URL) {
                        //self-contained case
                        if (entry->flags == 1) {
@@ -614,7 +615,7 @@ GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNna
                entry->flags |= 1;
                e = dref_AddDataEntry(dref, (GF_Box *)entry);
                if (e) return e;
-               *dataRefIndex = gf_list_count(dref->boxList);
+               *dataRefIndex = gf_list_count(dref->other_boxes);
                return GF_OK;
        } else if (!URNname && URLname) {
                //THIS IS URL
@@ -628,7 +629,7 @@ GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNna
                strcpy(entry->location, URLname);
                e = dref_AddDataEntry(dref, (GF_Box *)entry);
                if (e) return e;
-               *dataRefIndex = gf_list_count(dref->boxList);
+               *dataRefIndex = gf_list_count(dref->other_boxes);
                return GF_OK;
        } else {
                //THIS IS URN
@@ -651,7 +652,7 @@ GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNna
                }
                e = dref_AddDataEntry(dref, (GF_Box *)entry);
                if (e) return e;
-               *dataRefIndex = gf_list_count(dref->boxList);
+               *dataRefIndex = gf_list_count(dref->other_boxes);
                return GF_OK;
        }
        return GF_OK;
@@ -769,8 +770,6 @@ GF_Err Media_UpdateSample(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample *sam
        GF_DataEntryURLBox *Dentry;
        GF_SampleTableBox *stbl;
 
-       GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a);
-
        if (!mdia || !sample || !sampleNumber || !mdia->mediaTrack->moov->mov->editFileMap)
                return GF_BAD_PARAM;
        
@@ -789,7 +788,7 @@ GF_Err Media_UpdateSample(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample *sam
        //then check the data ref
        e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);
        if (e) return e;
-       Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->boxList, drefIndex - 1);
+       Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, drefIndex - 1);
        if (!Dentry) return GF_ISOM_INVALID_FILE;
 
        if (Dentry->flags != 1) return GF_BAD_PARAM;
@@ -814,7 +813,6 @@ GF_Err Media_UpdateSampleReference(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSa
        u8 isEdited;
        GF_DataEntryURLBox *Dentry;
        GF_SampleTableBox *stbl;
-       GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a);
 
        if (!mdia) return GF_BAD_PARAM;
        stbl = mdia->information->sampleTable;
@@ -830,7 +828,7 @@ GF_Err Media_UpdateSampleReference(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSa
        //then check the data ref
        e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);
        if (e) return e;
-       Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->boxList, drefIndex - 1);
+       Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, drefIndex - 1);
        if (!Dentry) return GF_ISOM_INVALID_FILE;
 
        //we only modify self-contained data
index 2c0f554763030c610a99214399dfd4d51222b444..cef8684dc4b6798533cd943a9948d224de3037b9 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
index 5f17c152b0fa8d9b542c68c37a1aaa4b1d6c48be..9e788f1a5539160fdbc75ed42cb819f52ce8ce47 100644 (file)
@@ -2,7 +2,7 @@
  *                                     GPAC Multimedia Framework
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -153,7 +153,7 @@ GF_Err gf_isom_get_meta_item_info(GF_ISOFile *file, Bool root_meta, u32 track_nu
                GF_ItemLocationEntry *iloc = (GF_ItemLocationEntry *)gf_list_get(meta->item_locations->location_entries, i);
                if (iloc->item_ID==iinf->item_ID) {
                        if (iloc->data_reference_index) {
-                               GF_Box *a = (GF_Box *)gf_list_get(meta->file_locations->dref->boxList, iloc->data_reference_index-1);
+                               GF_Box *a = (GF_Box *)gf_list_get(meta->file_locations->dref->other_boxes, iloc->data_reference_index-1);
                                if (a->type==GF_ISOM_BOX_TYPE_URL) {
                                        if (item_url) (*item_url) = ((GF_DataEntryURLBox*)a)->location;
                                } else if (a->type==GF_ISOM_BOX_TYPE_URN) {
@@ -226,7 +226,7 @@ GF_Err gf_isom_extract_meta_item_extended(GF_ISOFile *file, Bool root_meta, u32
        /*FIXME*/
        if (location_entry->data_reference_index) {
                char *item_url = NULL, *item_urn = NULL;
-               GF_Box *a = (GF_Box *)gf_list_get(meta->file_locations->dref->boxList, location_entry->data_reference_index-1);
+               GF_Box *a = (GF_Box *)gf_list_get(meta->file_locations->dref->other_boxes, location_entry->data_reference_index-1);
                if (a->type==GF_ISOM_BOX_TYPE_URL) {
                        item_url = ((GF_DataEntryURLBox*)a)->location;
                } else if (a->type==GF_ISOM_BOX_TYPE_URN) {
index 964ffefe46338cea770f5d1d635ba30dba2c00ca..02c44c028a9aa490a8288fb329750347df4c4acc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -55,8 +56,18 @@ GF_TrackFragmentBox *GetTraf(GF_ISOFile *mov, u32 TrackID)
 
 
 #ifndef GPAC_DISABLE_ISOM_WRITE
+GF_Err gf_isom_set_movie_duration(GF_ISOFile *movie, u64 duration)
+{
+       if (!movie->moov->mvex) return GF_BAD_PARAM;
+       if (!movie->moov->mvex->mehd) {
+               movie->moov->mvex->mehd = (GF_MovieExtendsHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MEHD);
+       }
+       movie->moov->mvex->mehd->fragment_duration = duration;
+       movie->moov->mvhd->duration = 0;
+       return GF_OK;
+}
 
-GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments)
+GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, u32 media_segment_type)
 {
        GF_Err e;
        u32 i;
@@ -82,8 +93,19 @@ GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments)
        if (store_file) {
                /*"dash" brand: this is a DASH Initialization Segment*/
                gf_isom_modify_alternate_brand(movie, GF_4CC('d','a','s','h'), 1);
-               //update durations
-               gf_isom_get_duration(movie);
+
+               if (!movie->moov->mvex->mehd || !movie->moov->mvex->mehd->fragment_duration) {
+                       //update durations
+                       gf_isom_get_duration(movie);
+               } 
+
+               i=0;
+               while ((trex = (GF_TrackExtendsBox *)gf_list_enum(movie->moov->mvex->TrackExList, &i))) {
+                       if (movie->moov->mvex->mehd && movie->moov->mvex->mehd->fragment_duration) {
+                               trex->track->Header->duration = 0;
+                               Media_SetDuration(trex->track);
+                       }
+               }
 
                //write movie
                e = WriteToFile(movie);
@@ -108,7 +130,7 @@ GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments)
        //ok we are fine - note the data map is created at the begining
        if (i) movie->FragmentsFlags |= GF_ISOM_FRAG_WRITE_READY;
 
-       if (use_segments) {
+       if (media_segment_type) {
                movie->use_segments = 1;
                movie->moof_list = gf_list_new();
        }
@@ -192,6 +214,9 @@ GF_Err gf_isom_setup_track_fragment(GF_ISOFile *movie, u32 TrackID,
        } else {
                mvex = movie->moov->mvex;
        }
+       if (!mvex->mehd) {
+               mvex->mehd = (GF_MovieExtendsHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MEHD);
+       }
 
        trex = GetTrex(movie->moov, TrackID);
        if (!trex) {
@@ -364,7 +389,7 @@ u32 UpdateRuns(GF_ISOFile *movie, GF_TrackFragmentBox *traf)
 
 #ifndef USE_BASE_DATA_OFFSET
        if (movie->use_segments) {
-               traf->tfhd->flags = 0;
+               traf->tfhd->flags = GF_ISOM_MOOF_BASE_OFFSET;
        } else 
 #endif
        {
@@ -619,7 +644,10 @@ u32 moof_get_duration(GF_MovieFragmentBox *moof, u32 refTrackID)
        while ((trun = gf_list_enum(traf->TrackRuns, &i))) {
                j=0;
                while ((ent = gf_list_enum(trun->entries, &j))) {
-                       duration += ent->Duration;
+                       if (ent->flags & GF_ISOM_TRAF_SAMPLE_DUR) 
+                               duration += ent->Duration;
+                       else 
+                               duration += traf->trex->def_sample_duration;
                }
        }
        return duration;
@@ -836,7 +864,7 @@ GF_Err gf_isom_allocate_sidx(GF_ISOFile *movie, s32 subsegs_per_sidx, Bool daisy
        /*we don't write anything between sidx and following moov*/
        movie->root_sidx->first_offset = 0;
 
-       /*for now we only store one ref per subsegment*/
+       /*for now we only store one ref per subsegment and don't support daisy-chaining*/
        movie->root_sidx->nb_refs = nb_segs;
 
        movie->root_sidx->refs = gf_malloc(sizeof(GF_SIDXReference) * movie->root_sidx->nb_refs);
@@ -922,7 +950,7 @@ GF_Err gf_isom_close_segment(GF_ISOFile *movie, s32 subsegments_per_sidx, u32 re
        }
 
        /*write STYP if we write to a different file or if we write the last segment*/
-       if ((!movie->append_segment && !movie->segment_start) || last_segment) {
+       if (!movie->append_segment && !movie->segment_start ) {
 
                /*modify brands STYP*/
 
@@ -974,6 +1002,7 @@ GF_Err gf_isom_close_segment(GF_ISOFile *movie, s32 subsegments_per_sidx, u32 re
                        frags_per_subseg = count;
                        frags_per_subsidx = count;
                        subseg_per_sidx = 1;
+                       daisy_chain_sidx = 0;
 
                        idx_offset = movie->root_sidx_index;
                        sidx_end = gf_bs_get_position(movie->editFileMap->bs);
@@ -1331,7 +1360,7 @@ GF_Err gf_isom_start_segment(GF_ISOFile *movie, char *SegName)
        } else {
                assert(gf_list_count(movie->moof_list) == 0);
                movie->segment_start = gf_bs_get_position(movie->editFileMap->bs);
-               /*if movieFileMap is not null, we are concatenating segments to the original move, force a copy*/
+               /*if movieFileMap is not null, we are concatenating segments to the original movie, force a copy*/
                if (movie->movieFileMap)
                        movie->append_segment = 1;
        }
@@ -1407,8 +1436,7 @@ u32 GetRunSize(GF_TrackFragmentRunBox *trun)
 
 
 GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample *sample, u32 DescIndex, 
-                                                                u32 Duration,
-                                                                u8 PaddingBits, u16 DegradationPriority)
+                                                                u32 Duration, u8 PaddingBits, u16 DegradationPriority, Bool redundant_coding)
 {
        u32 count, buffer_size;
        char *buffer;
@@ -1507,7 +1535,7 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample
        ent->size = sample->dataLength;
        ent->flags = GF_ISOM_FORMAT_FRAG_FLAGS(PaddingBits, sample->IsRAP, DegradationPriority);
        if (sample->IsRAP) {
-               ent->flags |= GF_ISOM_GET_FRAG_DEPEND_FLAGS(0, 2, 0, 0);
+               ent->flags |= GF_ISOM_GET_FRAG_DEPEND_FLAGS(0, 2, 0, (redundant_coding ? 1 : 0) );
        }
        gf_list_add(trun->entries, ent);
        
@@ -1599,7 +1627,7 @@ GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSam
 GF_Err gf_isom_fragment_copy_subsample(GF_ISOFile *dest, u32 TrackID, GF_ISOFile *orig, u32 track, u32 sampleNumber)
 {
        u32 i, count, last_sample;
-       GF_SampleEntry *sub_sample;
+       GF_SubSampleInfoEntry *sub_sample;
        GF_Err e;
        GF_TrackBox *trak;
        GF_TrackFragmentBox *traf;
@@ -1727,7 +1755,7 @@ GF_Err gf_isom_set_traf_base_media_decode_time(GF_ISOFile *movie, u32 TrackID, u
 
 #else
 
-GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *the_file)
+GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *the_file, u32 media_segment_type)
 {
        return GF_NOT_SUPPORTED;
 }
@@ -1754,8 +1782,7 @@ GF_Err gf_isom_start_fragment(GF_ISOFile *the_file, u32 free_data_insert_size)
 }
 
 GF_Err gf_isom_fragment_add_sample(GF_ISOFile *the_file, u32 TrackID, GF_ISOSample *sample, u32 DescIndex, 
-                                                                u32 Duration,
-                                                                u8 PaddingBits, u16 DegradationPriority)
+                                                                u32 Duration, u8 PaddingBits, u16 DegradationPriority, Bool redCoded)
 {
        return GF_NOT_SUPPORTED;
 }
index 616cb0b648998f7f6688fac344819b32008e0dfd..c5ed05d8aac6745fc4e639761f7028715767bf33 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
 
 #ifndef GPAC_DISABLE_ISOM
 
+void gf_isom_sample_entry_predestroy(GF_SampleEntryBox *ptr)
+{
+       if (ptr->protections) gf_isom_box_array_del(ptr->protections);
+}
+
+void gf_isom_sample_entry_init(GF_SampleEntryBox *ent)
+{
+       ent->protections = gf_list_new();
+}
+
 void gf_isom_video_sample_entry_init(GF_VisualSampleEntryBox *ent)
 {
+       gf_isom_sample_entry_init((GF_SampleEntryBox*)ent);
        ent->horiz_res = ent->vert_res = 0x00480000;
        ent->frames_per_sample = 1;
        ent->bit_depth = 0x18;
@@ -44,7 +56,7 @@ GF_Err gf_isom_video_sample_entry_read(GF_VisualSampleEntryBox *ptr, GF_BitStrea
        ptr->revision = gf_bs_read_u16(bs);
        ptr->vendor = gf_bs_read_u32(bs);
        ptr->temporal_quality  = gf_bs_read_u32(bs);
-       ptr->spacial_quality = gf_bs_read_u32(bs);
+       ptr->spatial_quality = gf_bs_read_u32(bs);
        ptr->Width = gf_bs_read_u16(bs);
        ptr->Height = gf_bs_read_u16(bs);
        ptr->horiz_res = gf_bs_read_u32(bs);
@@ -69,7 +81,7 @@ void gf_isom_video_sample_entry_write(GF_VisualSampleEntryBox *ptr, GF_BitStream
        gf_bs_write_u16(bs, ptr->revision);
        gf_bs_write_u32(bs, ptr->vendor);
        gf_bs_write_u32(bs, ptr->temporal_quality);
-       gf_bs_write_u32(bs, ptr->spacial_quality);
+       gf_bs_write_u32(bs, ptr->spatial_quality);
        gf_bs_write_u16(bs, ptr->Width);
        gf_bs_write_u16(bs, ptr->Height);
        gf_bs_write_u32(bs, ptr->horiz_res);
@@ -92,6 +104,8 @@ void gf_isom_video_sample_entry_size(GF_VisualSampleEntryBox *ent)
 
 void gf_isom_audio_sample_entry_init(GF_AudioSampleEntryBox *ptr)
 {
+       gf_isom_sample_entry_init((GF_SampleEntryBox*)ptr);
+
        ptr->channel_count = 2;
        ptr->bitspersample = 16;
 }
@@ -163,7 +177,7 @@ GF_3GPConfig *gf_isom_3gp_config_get(GF_ISOFile *the_file, u32 trackNumber, u32
        if (!trak || !StreamDescriptionIndex) return NULL;
 
        config = NULL;
-       entry = (GF_SampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex-1);
+       entry = (GF_SampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, StreamDescriptionIndex-1);
        if (!entry) return NULL;
        switch (entry->type) {
        case GF_ISOM_SUBTYPE_3GP_AMR:
@@ -197,7 +211,7 @@ GF_AC3Config *gf_isom_ac3_config_get(GF_ISOFile *the_file, u32 trackNumber, u32
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak || !StreamDescriptionIndex) return NULL;
 
-       entry = (GF_AC3SampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex-1);
+       entry = (GF_AC3SampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, StreamDescriptionIndex-1);
        if (!entry || !entry->info || (entry->type!=GF_ISOM_BOX_TYPE_AC3) || (entry->info->type!=GF_ISOM_BOX_TYPE_DAC3) ) return NULL;
 
        res = (GF_AC3Config*)gf_malloc(sizeof(GF_AC3Config));
@@ -274,8 +288,8 @@ GF_Err gf_isom_3gp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfi
                memcpy(&entry->info->cfg, cfg, sizeof(GF_3GPConfig));
                entry->samplerate_hi = trak->Media->mediaHeader->timeScale;
                entry->dataReferenceIndex = dataRefIndex;
-               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry);
-               *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
+               *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        }
                break;
        case GF_ISOM_SUBTYPE_3GP_H263:
@@ -289,8 +303,8 @@ GF_Err gf_isom_3gp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfi
                }
                memcpy(&entry->info->cfg, cfg, sizeof(GF_3GPConfig));
                entry->dataReferenceIndex = dataRefIndex;
-               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry);
-               *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+               e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
+               *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        }
                break;
        }
@@ -311,7 +325,7 @@ GF_Err gf_isom_3gp_config_update(GF_ISOFile *the_file, u32 trackNumber, GF_3GPCo
        if (!trak || !trak->Media || !param || !DescriptionIndex) return GF_BAD_PARAM;
 
        cfg = NULL;
-       entry = (GF_3GPPAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       entry = (GF_3GPPAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!entry) return GF_BAD_PARAM;
        switch (entry->type) {
        case GF_ISOM_SUBTYPE_3GP_AMR:
@@ -365,8 +379,8 @@ GF_Err gf_isom_ac3_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AC3Confi
        memcpy(&entry->info->cfg, cfg, sizeof(GF_AC3Config));
        entry->samplerate_hi = trak->Media->mediaHeader->timeScale;
        entry->dataReferenceIndex = dataRefIndex;
-       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry);
-       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry);
+       *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        return e;
 }
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
@@ -381,7 +395,7 @@ GF_Err gf_isom_get_dims_description(GF_ISOFile *movie, u32 trackNumber, u32 desc
        trak = gf_isom_get_track_from_file(movie, trackNumber);
        if (!trak || !descriptionIndex || !desc) return GF_BAD_PARAM;
 
-       dims = (GF_DIMSSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, descriptionIndex-1);
+       dims = (GF_DIMSSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, descriptionIndex-1);
        if (!dims) return GF_BAD_PARAM;
        if (dims->type != GF_ISOM_BOX_TYPE_DIMS) return GF_BAD_PARAM;
 
@@ -429,8 +443,8 @@ GF_Err gf_isom_new_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSD
 
        dims = (GF_DIMSSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DIMS);
        dims->dataReferenceIndex = dataRefIndex;
-       gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, dims);
-       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, dims);
+       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
 
        dims->config = (GF_DIMSSceneConfigBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_DIMC);
        dims->config->profile = desc->profile;
@@ -463,7 +477,7 @@ GF_Err gf_isom_update_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DI
        trak = gf_isom_get_track_from_file(movie, trackNumber);
        if (!trak || !trak->Media || !desc || !DescriptionIndex) return GF_BAD_PARAM;
 
-       dims = (GF_DIMSSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1);
+       dims = (GF_DIMSSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, DescriptionIndex-1);
        if (!dims) return GF_BAD_PARAM;
        if (dims->type != GF_ISOM_BOX_TYPE_DIMS) return GF_BAD_PARAM;
        if (!dims->config)
index 49a239d35f8430d0dd114f5e1eb5cbc78378e9f2..3830c45e13cc9da9ef674709d4d047568c14cc4b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
index 9ed4a7672ba5f48e80ee5597549253bdce35dd9a..aee50e5eeacb0d3c66f8ad86d7e4d6dc2e055b76 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -202,6 +203,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset)
                ctts->entries[ctts->nb_entries].decodingOffset = CTSoffset;
                ctts->entries[ctts->nb_entries].sampleCount = 1;
                ctts->nb_entries++;
+               ctts->w_LastSampleNumber++;
                return GF_OK;
        }
        //check if we're working in order...
@@ -219,6 +221,11 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset)
        sampNum = 0;
        for (i=0; i<ctts->nb_entries; i++) {
                for (j = 0; j<ctts->entries[i].sampleCount; j++) {
+                       if (sampNum > stbl->SampleSize->sampleCount) {
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Too many CTS Offset entries for %d samples\n", stbl->SampleSize->sampleCount ));
+                               gf_free(CTSs);
+                               return GF_ISOM_INVALID_FILE;
+                       }
                        if (sampNum+1==sampleNumber) {
                                CTSs[sampNum] = CTSoffset;
                                sampNum ++;
@@ -899,8 +906,8 @@ GF_Err stbl_RemoveCTS(GF_SampleTableBox *stbl, u32 sampleNumber)
        //first case, we're removing a sample that was not added yet
        if (sampleNumber > ctts->w_LastSampleNumber) return GF_OK;
 
+       memmove(&ctts->entries[sampleNumber-1], &ctts->entries[sampleNumber], sizeof(GF_DttsEntry)* (ctts->nb_entries-sampleNumber) );
        ctts->nb_entries--;
-       memmove(&ctts->entries[sampleNumber-1], &ctts->entries[sampleNumber], sizeof(GF_DttsEntry)*ctts->nb_entries);
 
        ctts->w_LastSampleNumber -= 1;
        return GF_OK;
@@ -1075,7 +1082,7 @@ GF_Err stbl_SetPaddingBits(GF_SampleTableBox *stbl, u32 SampleNumber, u8 bits)
        if (SampleNumber > stbl->SampleSize->sampleCount) return GF_BAD_PARAM;
 
        //create the table
-       if (!stbl->PaddingBits) stbl->PaddingBits = (GF_PaddingBitsBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FADB);
+       if (!stbl->PaddingBits) stbl->PaddingBits = (GF_PaddingBitsBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_PADB);
 
        //alloc
        if (!stbl->PaddingBits->padbits || !stbl->PaddingBits->SampleCount) {
@@ -1415,7 +1422,7 @@ void stbl_AppendPadding(GF_SampleTableBox *stbl, u8 padding)
 {
        u32 i;
        u8 *pad_bits;
-       if (!stbl->PaddingBits) stbl->PaddingBits = (GF_PaddingBitsBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FADB);
+       if (!stbl->PaddingBits) stbl->PaddingBits = (GF_PaddingBitsBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_PADB);
 
        pad_bits = (u8*)gf_malloc(sizeof(u8) * stbl->SampleSize->sampleCount);
        if (!pad_bits) return;
index 3534b8013e938f1bef8a630490b4d4e8b51b8f36..b8b02de7831f3ce8355f27d3e7cbf630dcfea7ab 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -196,8 +197,10 @@ default_sync:
                        } else {
                                esd->decoderConfig->rvc_config = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);
                                if (mime_type && !strcmp(mime_type, "application/rvc-config+xml+gz") ) {
+#ifndef GPAC_DISABLE_CORE_TOOLS
                                        gf_gz_decompress_payload(rvc_cfg_data, rvc_cfg_size, &esd->decoderConfig->rvc_config->data, &esd->decoderConfig->rvc_config->dataLength);
                                        gf_free(rvc_cfg_data);
+#endif
                                } else {
                                        esd->decoderConfig->rvc_config->data = rvc_cfg_data;
                                        esd->decoderConfig->rvc_config->dataLength = rvc_cfg_size;
@@ -314,7 +317,7 @@ GF_Err Track_FindRef(GF_TrackBox *trak, u32 ReferenceType, GF_TrackReferenceType
        }
        ref = trak->References;
        i=0;
-       while ((a = (GF_TrackReferenceTypeBox *)gf_list_enum(ref->boxList, &i))) {
+       while ((a = (GF_TrackReferenceTypeBox *)gf_list_enum(ref->other_boxes, &i))) {
                if (a->reference_type == ReferenceType) {
                        *dpnd = a;
                        return GF_OK;
@@ -426,7 +429,11 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset,
        if (traf->tfdt && is_first_merge) {
 #ifndef GPAC_DISABLE_LOG
                if (trak->sample_count_at_seg_start && (trak->dts_at_seg_start != traf->tfdt->baseMediaDecodeTime)) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error: TFDT timing "LLD" different from track cumulated timing "LLD" - using tfdt\n", traf->tfdt->baseMediaDecodeTime, trak->dts_at_seg_start ));
+                       s32 drift = (s32) ((s64)trak->dts_at_seg_start - (s64) traf->tfdt->baseMediaDecodeTime);
+                       if (drift<0) drift = -drift;
+                       if (drift > 1) {
+                               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Error: TFDT timing "LLD" different from track cumulated timing "LLD" - using tfdt\n", traf->tfdt->baseMediaDecodeTime, trak->dts_at_seg_start ));
+                       }
                }
 #endif
                trak->dts_at_seg_start = traf->tfdt->baseMediaDecodeTime;
@@ -457,8 +464,9 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset,
                        //add chunk on first sample
                        if (!j) {
                                data_offset = base_offset;
-                               //aggregated offset
-                               if (!(traf->tfhd->flags & GF_ISOM_TRAF_BASE_OFFSET)) data_offset += chunk_size;
+                               //aggregated offset if base-data-offset-present is not set AND if default-base-is-moof is not set
+                               if (!(traf->tfhd->flags & GF_ISOM_TRAF_BASE_OFFSET) && !(traf->tfhd->flags & GF_ISOM_MOOF_BASE_OFFSET) ) 
+                                       data_offset += chunk_size;
 
                                if (trun->flags & GF_ISOM_TRUN_DATA_OFFSET) {
                                        data_offset += trun->data_offset;
@@ -598,10 +606,10 @@ GF_Err Track_RemoveRef(GF_TrackBox *trak, u32 ReferenceType)
        if (! trak->References) return GF_OK;
        ref = trak->References;
        i=0;
-       while ((a = (GF_Box *)gf_list_enum(ref->boxList, &i))) {
+       while ((a = (GF_Box *)gf_list_enum(ref->other_boxes, &i))) {
                if (a->type == ReferenceType) {
                        gf_isom_box_del(a);
-                       gf_list_rem(ref->boxList, i-1);
+                       gf_list_rem(ref->other_boxes, i-1);
                        return GF_OK;
                }
        }
@@ -846,7 +854,7 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex,
 
        //we have a streamDescritpionIndex, use it
        if (StreamDescriptionIndex) {
-               entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex - 1);
+               entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, StreamDescriptionIndex - 1);
                if (!entry) return GF_ISOM_INVALID_FILE;
 
                switch (entry->type) {
@@ -884,9 +892,9 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex,
                }
        } else {
                //need to check we're not in URL mode where only ONE description is allowed...
-               StreamDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+               StreamDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
                if (StreamDescriptionIndex) {
-                       entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex - 1);
+                       entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, StreamDescriptionIndex - 1);
                        if (!entry) return GF_ISOM_INVALID_FILE;
                        if (entry->esd && entry->esd->desc->URLString) return GF_BAD_PARAM;
                }
@@ -934,7 +942,7 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex,
                //and add the entry to our table...
                e = stsd_AddBox(trak->Media->information->sampleTable->SampleDescription, (GF_Box *) entry);
                if (e) return e;
-               if(outStreamIndex) *outStreamIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+               if(outStreamIndex) *outStreamIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        }
        return GF_OK;
 }
index 0ee6dfec5b5d9f7e4d10d55c238d27991ec735bc..733e4b2542305ba9677d24cd246c43fa49773d06 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
@@ -51,7 +52,7 @@ GF_Err gf_isom_update_text_description(GF_ISOFile *movie, u32 trackNumber, u32 d
                return GF_BAD_PARAM;
        }
 
-       txt = (GF_Tx3gSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, descriptionIndex - 1);
+       txt = (GF_Tx3gSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, descriptionIndex - 1);
        if (!txt) return GF_BAD_PARAM;
        switch (txt->type) {
        case GF_ISOM_BOX_TYPE_TX3G:
@@ -113,8 +114,8 @@ GF_Err gf_isom_new_text_description(GF_ISOFile *movie, u32 trackNumber, GF_TextS
 
        txt = (GF_Tx3gSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TX3G);
        txt->dataReferenceIndex = dataRefIndex;
-       gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, txt);
-       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, txt);
+       if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
 
        txt->back_color = desc->back_color; 
        txt->default_box = desc->default_pos;
@@ -370,10 +371,10 @@ GF_Err gf_isom_text_has_similar_description(GF_ISOFile *movie, u32 trackNumber,
                return GF_BAD_PARAM;
        }
 
-       count = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);
+       count = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes);
        for (i=0; i<count; i++) {
                Bool same_fonts;
-               txt = (GF_Tx3gSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, i);
+               txt = (GF_Tx3gSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, i);
                if (!txt) continue;
                if ((txt->type != GF_ISOM_BOX_TYPE_TX3G) && (txt->type != GF_ISOM_BOX_TYPE_TEXT)) continue;
                if (txt->back_color != desc->back_color) continue;
@@ -592,7 +593,7 @@ GF_Err gf_isom_get_ttxt_esd(GF_MediaBox *mdia, GF_ESD **out_esd)
        GF_TrackBox *tk;
 
        *out_esd = NULL;
-       sampleDesc = mdia->information->sampleTable->SampleDescription->boxList;
+       sampleDesc = mdia->information->sampleTable->SampleDescription->other_boxes;
        count = gf_list_count(sampleDesc);
        if (!count) return GF_ISOM_INVALID_MEDIA;
        
@@ -705,7 +706,7 @@ GF_Err gf_isom_text_get_encoded_tx3g(GF_ISOFile *file, u32 track, u32 sidx, u32
        trak = gf_isom_get_track_from_file(file, track);
        if (!trak) return GF_BAD_PARAM;
 
-       a = (GF_Tx3gSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sidx-1);
+       a = (GF_Tx3gSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->other_boxes, sidx-1);
        if (!a) return GF_BAD_PARAM;
        if ((a->type != GF_ISOM_BOX_TYPE_TX3G) && (a->type != GF_ISOM_BOX_TYPE_TEXT)) return GF_BAD_PARAM;
        
index 7b5dd8db8d233f3918bc8f49309eed0d80c0cc26..c17c3d2aeacb601bc0a7d9a8f877d763d43563fd 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / LASeR codec sub-project
index 11981da1932a401c542393228923ff1e3bb45ac0..87a39c41b8bc8ac29d56dfc7c9943e99ff8e1e64 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / LASeR codec sub-project
index f0e6cec08c65fac43861387e4c8f693f6f6cbee5..8b962a9a888b8d61db366c555e7bf5a5796133d2 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean Le Feuvre
- *    Copyright (c)2004-200X ENST - All rights reserved
+ *    Copyright (c)2004-200X Telecom ParisTech - All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph sub-project
  *
index ea655642d0c7079383a3b7dec4928939217314a7..df279603b740c014026c80b18b42115775ad7b84 100644 (file)
@@ -432,7 +432,7 @@ static u32 f(DES_KEY * key, register u32 r, register char *subkey)
        register int er;
 
 #ifdef TRACE
-       printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
+       fprintf(stderr, "f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
               r,
               subkey[0], subkey[1], subkey[2],
               subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
@@ -471,7 +471,7 @@ static u32 f(DES_KEY * key, register u32 r, register char *subkey)
        rt |= (r & 1) << 5;
        rval |= spp[((int) rt ^ *subkey) & 0x3f];
 #ifdef TRACE
-       printf(" %08lx\n", rval);
+       fprintf(stderr, " %08lx\n", rval);
 #endif
        return rval;
 }
@@ -555,7 +555,7 @@ static void spinit(DES_KEY * key)
                        key->sp[s][i] = val;
 
 #ifdef DEBUG
-                       printf("sp[%d][%2d] = %08lx\n", s, i,
+                       fprintf(stderr, "sp[%d][%2d] = %08lx\n", s, i,
                               key->sp[s][i]);
 #endif
                }
index a7ef71b7fdf1b2687d91421c03ca94d6025dfb9e..7aefb51e02cac8cedced9d8f892c63f46cb549a3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / crypto lib sub-project
index df1ab6b3e659fdf94c3b969295bf85b5d42928fa..1f6d5ca6a481d8c74488a425512900983d4f590e 100644 (file)
@@ -637,7 +637,7 @@ static u32 f(TRIPLEDES_KEY * key, int pos, register u32 r,
        register int er;
 
 #ifdef TRACE
-       printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
+       fprintf(stderr, "f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
               r,
               subkey[0], subkey[1], subkey[2],
               subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
@@ -676,7 +676,7 @@ static u32 f(TRIPLEDES_KEY * key, int pos, register u32 r,
        rt |= (r & 1) << 5;
        rval |= spp[((int) rt ^ *subkey) & 0x3f];
 #ifdef TRACE
-       printf(" %08lx\n", rval);
+       fprintf(stderr, " %08lx\n", rval);
 #endif
        return rval;
 }
index 112ab704bf25a5d42dcffedad848555081536351..d4f25ace24e3b023b739c9c4fa578eaf1bdaed3d 100644 (file)
@@ -1,10 +1,31 @@
-/* \r
- * Copyright (c) TELECOM ParisTech 2011\r
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Jonathan Sillan\r
+ *                     Copyright (c) Telecom ParisTech 2011-2012\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / media tools sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
  */\r
 \r
 #include <gpac/ait.h>\r
 \r
-#ifndef GPAC_DISABLE_MPEG2TS\r
+#ifdef GPAC_ENABLE_DSMCC\r
 \r
 /* static functions */\r
 static Bool check_ait_already_received(GF_List* ChannelAppList,u32 pid,char* data);\r
@@ -234,7 +255,7 @@ static GF_Err gf_m2ts_decode_ait(GF_M2TS_AIT *ait, char  *data, u32 data_size, u
                                                GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte;\r
                                                GF_SAFEALLOC(Transport_http_selector_byte, GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE);                                       \r
                                                Transport_http_selector_byte->URL_base_length = gf_bs_read_int(bs,8);\r
-                                               //printf("Transport_http_selector_byte->URL_base_length %d \n",Transport_http_selector_byte->URL_base_length);\r
+                                               //fprintf(stderr, "Transport_http_selector_byte->URL_base_length %d \n",Transport_http_selector_byte->URL_base_length);\r
                                                Transport_http_selector_byte->URL_base_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_base_length+1,sizeof(char));\r
                                                gf_bs_read_data(bs,Transport_http_selector_byte->URL_base_byte ,(u32)(Transport_http_selector_byte->URL_base_length));\r
                                                Transport_http_selector_byte->URL_base_byte[Transport_http_selector_byte->URL_base_length] = 0;\r
@@ -765,6 +786,7 @@ void  gf_m2ts_delete_channel_application_info(GF_M2TS_CHANNEL_APPLICATION_INFO*
        gf_list_del(ChannelApp->Application);\r
        gf_free(ChannelApp);\r
 }\r
-#endif //GPAC_DISABLE_MPEG2TS\r
+\r
+#endif //GPAC_ENABLE_DSMCC\r
 \r
 \r
index 92c2b4e2f51c7772c5fb99ecaba32eb5becefc58..d54f1d663a233dab5c1a72e2773938312b6864f3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre, Romain Bouqueau, Cyril Concolato 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
 
 #include <gpac/internal/media_dev.h>
 #include <gpac/constants.h>
-#include <gpac/math.h>
 
 #ifndef GPAC_DISABLE_OGG
 #include <gpac/internal/ogg.h>
+#include <gpac/math.h>
 #endif
 
+static const struct { u32 w, h; } std_par[ ] =
+{
+       { 4, 3}, {3, 2}, {16, 9}, {5, 3}, {5, 4}, {8, 5}, 
+       {0, 0},
+};
+
+GF_EXPORT
+void gf_media_reduce_aspect_ratio(u32 *width, u32 *height)
+{
+       u32 i=0;
+       u32 w = *width;
+       u32 h = *height;
+       while (std_par[i].w) {
+               if (std_par[i].w * h == std_par[i].h * w) {
+                       *width = std_par[i].w;
+                       *height = std_par[i].h;
+                       return;
+               }
+               i++;
+       }
+}
+
+GF_EXPORT
+void gf_media_get_reduced_frame_rate(u32 *timescale, u32 *sample_dur)
+{
+       u32 res;
+       if (! *sample_dur) return;
+       res = *timescale / *sample_dur;
+       if (res * *sample_dur == *timescale) {
+               *timescale = res;
+               *sample_dur = 1;
+       }
+}
+
 GF_EXPORT
 const char *gf_m4v_get_profile_name(u8 video_pl)
 {
@@ -1504,23 +1539,29 @@ u32 AVC_NextStartCode(GF_BitStream *bs)
        return (u32) (end-start);
 }
 
+Bool AVC_SliceIsIntra(AVCState *avc) 
+{
+       switch (avc->s_info.slice_type) {
+               case GF_AVC_TYPE_I:
+               case GF_AVC_TYPE2_I:
+               case GF_AVC_TYPE_SI:
+               case GF_AVC_TYPE2_SI:
+                       return 1;
+               default:
+                       return 0;
+       }
+}
+
 Bool AVC_SliceIsIDR(AVCState *avc) 
 {
-  if (avc->sei.recovery_point.valid)
-  {
-         avc->sei.recovery_point.valid = 0;
-         return 1;
-  }
-  if (avc->s_info.nal_unit_type != GF_AVC_NALU_IDR_SLICE) return 0;
-  switch (avc->s_info.slice_type) {
-  case GF_AVC_TYPE_I:
-  case GF_AVC_TYPE2_I:
-  case GF_AVC_TYPE_SI:
-  case GF_AVC_TYPE2_SI:
-         return 1;
-  default:
-         return 0;
-  }
+       if (avc->sei.recovery_point.valid)
+       {
+               avc->sei.recovery_point.valid = 0;
+               return 1;
+       }
+       if (avc->s_info.nal_unit_type != GF_AVC_NALU_IDR_SLICE)
+               return 0;
+       return AVC_SliceIsIntra(avc);
 }
 
 static const struct { u32 w, h; } avc_sar[14] =
@@ -1531,6 +1572,7 @@ static const struct { u32 w, h; } avc_sar[14] =
        { 64, 33 }, { 160,99 },
 };
 
+
 /*ISO 14496-10 (N11084) E.1.2*/
 static void avc_parse_hrd_parameters(GF_BitStream *bs, AVC_HRD *hrd)
 {
@@ -1696,7 +1738,7 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps,
        AVC_SPS *sps;
        u32 ChromaArrayType = 0;
        s32 mb_width, mb_height, sps_id = -1;
-       u32 profile_idc, level_idc, pcomp, i, chroma_format_idc, cl, cr, ct, cb;
+       u32 profile_idc, level_idc, pcomp, i, chroma_format_idc, cl, cr, ct, cb, luma_bd, chroma_bd;
        GF_BitStream *bs;
        char *sps_data_without_emulation_bytes = NULL;
        u32 sps_data_without_emulation_bytes_size = 0;
@@ -1729,6 +1771,7 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps,
                goto exit;
        }
 
+       chroma_format_idc = luma_bd = chroma_bd = 0;
        sps = &avc->sps[sps_id];
        sps->state |= subseq_sps ? AVC_SUBSPS_PARSED : AVC_SPS_PARSED;
 
@@ -1757,8 +1800,8 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps,
                        */
                        if (separate_colour_plane_flag) ChromaArrayType = 0;
                }
-               /*bit_depth_luma_minus8 = */ avc_get_ue(bs);
-               /*bit_depth_chroma_minus8 = */ avc_get_ue(bs);
+               luma_bd = avc_get_ue(bs);
+               chroma_bd = avc_get_ue(bs);
                /*qpprime_y_zero_transform_bypass_flag = */ gf_bs_read_int(bs, 1);
                /*seq_scaling_matrix_present_flag*/
                if (gf_bs_read_int(bs, 1)) {
@@ -1785,6 +1828,9 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps,
        sps->prof_compat = pcomp;
        sps->log2_max_frame_num = avc_get_ue(bs) + 4;
        sps->poc_type = avc_get_ue(bs);
+       sps->chroma_format = chroma_format_idc;
+       sps->luma_bit_depth_m8 = luma_bd;
+       sps->chroma_bit_depth_m8 = chroma_bd;
 
        if (sps->poc_type == 0) {
                sps->log2_max_poc_lsb = avc_get_ue(bs) + 4;
@@ -1914,9 +1960,9 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps,
 
                                for (i=0; i <= vui_ext_num_entries_minus1; i++) {
                                        u8 vui_ext_nal_hrd_parameters_present_flag, vui_ext_vcl_hrd_parameters_present_flag, vui_ext_timing_info_present_flag;
-                                       /*u8 vui_ext_dependency_id = */gf_bs_read_int(bs, 3);
-                                       /*u8 vui_ext_quality_id = */gf_bs_read_int(bs, 4);
-                                       /*u8 vui_ext_temporal_id = */gf_bs_read_int(bs, 3);
+                                       /*u8 vui_ext_dependency_id =*/ gf_bs_read_int(bs, 3);
+                                       /*u8 vui_ext_quality_id =*/ gf_bs_read_int(bs, 4);
+                                       /*u8 vui_ext_temporal_id =*/ gf_bs_read_int(bs, 3);
                                        vui_ext_timing_info_present_flag = gf_bs_read_int(bs, 1);
                                        if (vui_ext_timing_info_present_flag) {
                                                /*u32 vui_ext_num_units_in_tick = */gf_bs_read_int(bs, 32);
@@ -2016,6 +2062,27 @@ exit:
        return pps_id;
 }
 
+s32 AVC_ReadSeqParamSetExtId(char *spse_data, u32 spse_size)
+{
+       GF_BitStream *bs;
+       char *spse_data_without_emulation_bytes = NULL;
+       u32 spse_data_without_emulation_bytes_size = 0;
+       s32 sps_id;
+
+       /*PPS still contains emulation bytes*/
+       spse_data_without_emulation_bytes = gf_malloc(spse_size*sizeof(char));
+       spse_data_without_emulation_bytes_size = avc_remove_emulation_bytes(spse_data, spse_data_without_emulation_bytes, spse_size);
+       bs = gf_bs_new(spse_data_without_emulation_bytes, spse_data_without_emulation_bytes_size, GF_BITSTREAM_READ);
+       
+       sps_id = -1;
+       if (bs) 
+               sps_id = avc_get_ue(bs);
+
+       gf_bs_del(bs);
+       gf_free(spse_data_without_emulation_bytes);
+       return sps_id;
+}
+
 static s32 SVC_ReadNal_header_extension(GF_BitStream *bs, SVC_NALUHeader *NalHeader)
 {
        gf_bs_read_int(bs, 1); //reserved_one_bits
@@ -2532,7 +2599,9 @@ u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc)
                case 16: /*progressive refinement segment start*/
                case 17: /*progressive refinement segment end*/
                case 18: /*motion constrained slice group*/
+                       break;
                default: /*reserved*/
+                       do_copy = 0;
                        break;
                }
 
@@ -2572,11 +2641,17 @@ u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc)
        if (written) {
                var = avc_emulation_bytes_add_count(new_buffer, written);
                if (var) {
-                       assert(written+var<=nal_size);
-                       written = avc_add_emulation_bytes(new_buffer, buffer, written);
+                       if (written+var<=nal_size) {
+                               written = avc_add_emulation_bytes(new_buffer, buffer, written);
+                       } else {
+                               written = 0;
+                       }
                } else {
-                       assert(written<=nal_size);
-                       memcpy(buffer, new_buffer, sizeof(char)*written);
+                       if (written<=nal_size) {
+                               memcpy(buffer, new_buffer, sizeof(char)*written);
+                       } else {
+                               written = 0;
+                       }
                }
        }
        gf_free(new_buffer);
diff --git a/src/media_tools/dash_client.c b/src/media_tools/dash_client.c
new file mode 100644 (file)
index 0000000..3336f9e
--- /dev/null
@@ -0,0 +1,3153 @@
+/*\r
+*                      GPAC - Multimedia Framework C SDK\r
+*\r
+*                      Authors: Jean Le Feuvre, Cyril Concolato\r
+*                      Copyright (c) Telecom ParisTech 2010-\r
+*                                      All rights reserved\r
+*\r
+*  This file is part of GPAC / Adaptive HTTP Streaming \r
+*\r
+*  GPAC is free software; you can redistribute it and/or modify\r
+*  it under the terms of the GNU Lesser General Public License as published by\r
+*  the Free Software Foundation; either version 2, or (at your option)\r
+*  any later version.\r
+*\r
+*  GPAC is distributed in the hope that it will be useful,\r
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*  GNU Lesser General Public License for more details.\r
+*\r
+*  You should have received a copy of the GNU Lesser General Public\r
+*  License along with this library; see the file COPYING.  If not, write to\r
+*  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\r
+*\r
+*/\r
+\r
+#include <gpac/thread.h>\r
+#include <gpac/network.h>\r
+#include <gpac/dash.h>\r
+#include <gpac/internal/mpd.h>\r
+#include <gpac/internal/m3u8.h>\r
+#include <string.h>\r
+\r
+#ifndef GPAC_DISABLE_DASH_CLIENT\r
+\r
+/*set to 1 if you want MPD to use SegmentTemplate if possible instead of SegmentList*/\r
+#define M3U8_TO_MPD_USE_TEMPLATE       0\r
+\r
+\r
+typedef enum {\r
+       GF_DASH_STATE_STOPPED = 0,\r
+       /*period setup and playback chain creation*/\r
+       GF_DASH_STATE_SETUP,\r
+       /*request to start playback chain*/\r
+       GF_DASH_STATE_CONNECTING,\r
+       GF_DASH_STATE_RUNNING,\r
+} GF_DASH_STATE;\r
+\r
+\r
+typedef struct __dash_group GF_DASH_Group;\r
+\r
+struct __dash_client\r
+{\r
+       GF_DASHFileIO *dash_io;\r
+\r
+       /*interface to mpd parser - get rid of this and use the DASHIO instead ?*/\r
+       GF_FileDownload getter;\r
+\r
+       char *base_url;\r
+\r
+       u32 max_cache_duration;\r
+       u32 auto_switch_count;\r
+       Bool keep_files, disable_switching, allow_local_mpd_update;\r
+\r
+       GF_DASHInitialSelectionMode first_select_mode;\r
+\r
+       /* MPD downloader*/\r
+       GF_DASHFileIOSession mpd_dnload;\r
+       /* MPD */\r
+       GF_MPD *mpd;\r
+       /* number of time the MPD has been reloaded and last update time*/\r
+       u32 reload_count, last_update_time;\r
+       /*signature of last MPD*/\r
+       u8 lastMPDSignature[20];\r
+       /*mime type of media segments (m3u8)*/\r
+       char *mimeTypeForM3U8Segments;\r
+\r
+       /* active period in MPD (only one currently supported) */\r
+       u32 active_period_index;\r
+       u32 request_period_switch;\r
+\r
+       u64 start_time_in_active_period;\r
+\r
+       /*list of groups in the active period*/\r
+       GF_List *groups;\r
+\r
+       /*Main Thread handling segment downloads and MPD/M3U8 update*/\r
+       GF_Thread *dash_thread;\r
+       /*mutex for group->cache file name access and MPD update*/\r
+       GF_Mutex *dl_mutex;\r
+\r
+       /* one of the above state*/\r
+       GF_DASH_STATE dash_state;\r
+       Bool mpd_stop_request;\r
+       Bool in_period_setup;\r
+\r
+\r
+       /* TODO - handle playback status for SPEED/SEEK through SIDX */\r
+       Double playback_start_range;\r
+       Double start_range_in_segment_at_next_period;\r
+};\r
+\r
+static void gf_dash_seek_group(GF_DashClient *dash, GF_DASH_Group *group);\r
+\r
+\r
+typedef struct\r
+{\r
+       char *cache;\r
+       char *url;\r
+       u64 start_range, end_range;\r
+       /*representation index in adaptation_set->representations*/\r
+       u32 representation_index;\r
+       Bool do_not_delete;\r
+} segment_cache_entry;\r
+\r
+typedef enum\r
+{\r
+       /*set if group cannot be selected (wrong MPD)*/\r
+       GF_DASH_GROUP_NOT_SELECTABLE = 0,\r
+       GF_DASH_GROUP_NOT_SELECTED,\r
+       GF_DASH_GROUP_SELECTED,\r
+} GF_DASHGroupSelection;\r
+\r
+/*this structure Group is the implementation of the adaptationSet element of the MPD.*/\r
+struct __dash_group\r
+{\r
+       GF_DashClient *dash;\r
+\r
+       /*pointer to adaptation set*/\r
+       GF_MPD_AdaptationSet *adaptation_set;\r
+       /*pointer to active period*/\r
+       GF_MPD_Period *period;\r
+\r
+       /*active representation index in adaptation_set->representations*/\r
+       u32 active_rep_index;\r
+\r
+       u32 prev_active_rep_index;\r
+\r
+       GF_DASHGroupSelection selection;\r
+\r
+\r
+       Bool bitstream_switching, dont_delete_first_segment;\r
+\r
+       Bool done;\r
+       Bool force_switch_bandwidth, min_bandwidth_selected;\r
+       u32 nb_bw_check;\r
+       u32 active_bitrate, max_bitrate, min_bitrate;\r
+\r
+       u32 nb_segments_in_rep;\r
+       Double segment_duration;\r
+\r
+       /*local file playback, do not delete them*/\r
+       Bool local_files;\r
+       /*next segment to download for this group*/\r
+       u32 download_segment_index;\r
+       /*number of segments pruged since the start of the period*/\r
+       u32 nb_segments_purged;\r
+\r
+       /*next file (cached) to delete at next GF_NET_SERVICE_QUERY_NEXT for this group*/\r
+       char * urlToDeleteNext;\r
+       volatile u32 max_cached_segments, nb_cached_segments;\r
+       segment_cache_entry *cached;\r
+\r
+       GF_DASHFileIOSession segment_download;\r
+\r
+       const char *segment_local_url;\r
+       /*usually 0-0 (no range) but can be non-zero when playing local MPD/DASH sessions*/\r
+       u64 local_url_start_range, local_url_end_range;\r
+\r
+       u32 nb_segments_done;\r
+\r
+       Bool segment_must_be_streamed;\r
+\r
+       u32 force_representation_idx_plus_one;\r
+\r
+       Bool force_segment_switch;\r
+\r
+       /*set when switching segment, indicates the current downloaded segment duration*/\r
+       u64 current_downloaded_segment_duration;\r
+\r
+       char *service_mime;\r
+\r
+       void *udta;\r
+};\r
+\r
+static const char *gf_dash_get_mime_type(GF_MPD_SubRepresentation *subrep, GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set)\r
+{\r
+       if (subrep && subrep->mime_type) return subrep->mime_type;\r
+       if (rep && rep->mime_type) return rep->mime_type;\r
+       if (set && set->mime_type) return set->mime_type;\r
+       return NULL;\r
+}\r
+\r
+GF_EXPORT\r
+Bool gf_dash_check_mpd_root_type(const char *local_url)\r
+{\r
+       if (local_url) {\r
+               char *rtype = gf_xml_get_root_type(local_url, NULL);\r
+               if (rtype) {\r
+                       Bool handled = 0;\r
+                       if (!strcmp(rtype, "MPD")) {\r
+                               handled = 1;\r
+                       }\r
+                       gf_free(rtype);\r
+                       return handled;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+void gf_dash_group_check_switch(GF_DASHFileIO *dash_io, GF_DASH_Group *group, Bool download_active)\r
+{\r
+       u32 download_rate;\r
+\r
+       if (group->dash->disable_switching) return;\r
+       download_rate = dash_io->get_bytes_per_sec(dash_io, group->segment_download);\r
+       if (!download_rate) return;\r
+\r
+       download_rate *= 8;\r
+       if (download_rate<group->min_bitrate) group->min_bitrate = download_rate;\r
+       if (download_rate>group->max_bitrate) group->max_bitrate = download_rate;\r
+\r
+       if (download_rate && (download_rate < group->active_bitrate)) {\r
+               u32 set_idx = gf_list_find(group->period->adaptation_sets, group->adaptation_set)+1;\r
+               group->nb_bw_check ++;\r
+               if (group->min_bandwidth_selected) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Downloading from set #%d at rate %d kbps but media bitrate is %d kbps - no lower bitrate available ...\n", set_idx, download_rate/1024, group->active_bitrate/1024 ));\r
+               } else if (group->nb_bw_check>2) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Downloading from set #%d at rate %d kbps but media bitrate is %d kbps - switching\n", set_idx, download_rate/1024, group->active_bitrate/1024 ));\r
+                       group->force_switch_bandwidth = 1;\r
+                       if (download_active) \r
+                               if (group->segment_download) dash_io->abort(dash_io, group->segment_download);\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Downloading from set #%ds at rate %d kbps but media bitrate is %d kbps\n", set_idx, download_rate/1024, group->active_bitrate/1024 ));\r
+               }\r
+       } else {\r
+               group->nb_bw_check = 0;\r
+       }\r
+}\r
+\r
+\r
+\r
+/*!\r
+* Returns true if given mime type is a MPD file\r
+* \param mime the mime-type to check\r
+* \return true if mime-type if MPD-OK\r
+*/\r
+static Bool gf_dash_is_dash_mime(const char * mime) {\r
+       u32 i;\r
+       if (!mime)\r
+               return 0;\r
+       for (i = 0 ; GF_DASH_MPD_MIME_TYPES[i] ; i++){\r
+               if ( !stricmp(mime, GF_DASH_MPD_MIME_TYPES[i]))\r
+                       return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+/*!\r
+* Returns true if mime type is an M3U8 mime-type\r
+* \param mime The mime-type to check\r
+* \return true if mime-type is OK for M3U8\r
+*/\r
+static Bool gf_dash_is_m3u8_mime(const char * mime) {\r
+       u32 i;\r
+       if (!mime)\r
+               return 0;\r
+       for (i = 0 ; GF_DASH_M3U8_MIME_TYPES[i] ; i++) {\r
+               if ( !stricmp(mime, GF_DASH_M3U8_MIME_TYPES[i]))\r
+                       return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+\r
+/*!\r
+* Download a file with possible retry if GF_IP_CONNECTION_FAILURE|GF_IP_NETWORK_FAILURE\r
+* (I discovered that with my WIFI connection, I had many issues with BFM-TV downloads)\r
+* Similar to gf_term_download_new() and gf_dm_sess_process().\r
+* Parameters are identical to the ones of gf_term_download_new.\r
+* \see gf_term_download_new()\r
+*/\r
+GF_Err gf_dash_download_resource(GF_DASHFileIO *dash_io, GF_DASHFileIOSession *sess, const char *url, u64 start_range, u64 end_range, Bool persistent, GF_DASH_Group *group)\r
+{\r
+       Bool had_sess = 0;\r
+       Bool retry = 1;\r
+       GF_Err e;\r
+\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Downloading %s...\n", url));\r
+\r
+       if (! *sess) {\r
+               *sess = dash_io->create(dash_io, persistent, url);\r
+               if (!(*sess)){\r
+                       assert(0);\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot try to download %s... OUT of memory ?\n", url));\r
+                       return GF_OUT_OF_MEM;\r
+               }\r
+       } else {\r
+               had_sess = 1;\r
+               e = dash_io->setup_from_url(dash_io, *sess, url);\r
+               if (e) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot resetup session for url %s: %s\n", url, gf_error_to_string(e) ));\r
+                       return e;\r
+               }\r
+       }\r
+\r
+retry:\r
+\r
+       if (end_range) {\r
+               e = dash_io->set_range(dash_io, *sess, start_range, end_range);\r
+               if (e) {\r
+                       if (had_sess) {\r
+                               dash_io->del(dash_io, *sess);\r
+                               *sess = NULL;\r
+                               return gf_dash_download_resource(dash_io, sess, url, start_range, end_range, persistent, group);\r
+                       }\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot setup byte-range download for %s: %s\n", url, gf_error_to_string(e) ));\r
+                       return e;\r
+               }\r
+       }\r
+               assert(*sess);\r
+\r
+       /*issue HTTP GET for headers only*/\r
+       e = dash_io->init(dash_io, *sess);\r
+\r
+       if (e>=GF_OK) {\r
+               /*check mime type of the adaptation set if not provided*/\r
+               if (group) {\r
+                       const char *mime = dash_io->get_mime(dash_io, *sess);\r
+                       if (mime && !group->service_mime) {\r
+                               group->service_mime = gf_strdup(mime);\r
+                       } \r
+                       /*we allow servers to give us broken mim types for the representation served ...*/\r
+#if 0\r
+                       else if (mime && stricmp(group->service_mime, mime)) {\r
+                               GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+                               if (! gf_dash_get_mime_type(NULL, rep, group->adaptation_set) ) \r
+                                       rep->mime_type = gf_strdup(mime);\r
+                               rep->disabled = 1;\r
+                               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Disabling representation since mime does not match: expected %s, but had %s for %s!\n", group->service_mime, mime, url));\r
+                               group->force_switch_bandwidth = 1;\r
+                               if (group->segment_download) dash_io->abort(dash_io, group->segment_download);\r
+                               return GF_OK;\r
+                       }\r
+#endif\r
+               }\r
+\r
+               /*file cannot be cached on disk !*/\r
+               if (group) {\r
+                       if (dash_io->get_cache_name(dash_io, group->segment_download) == NULL) {\r
+                               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] Segment %s cannot be cached on disk, will use direct streaming\n", url));\r
+                               group->segment_must_be_streamed = 1;\r
+                               if (group->segment_download) dash_io->abort(dash_io, group->segment_download);\r
+                               return GF_OK;\r
+                       } \r
+                       group->segment_must_be_streamed = 0;\r
+               } \r
+\r
+               /*we can download the file*/\r
+               e = dash_io->run(dash_io, *sess);\r
+       }\r
+       switch (e) {\r
+case GF_IP_CONNECTION_FAILURE:\r
+case GF_IP_NETWORK_FAILURE:\r
+       {\r
+               dash_io->del(dash_io, *sess);\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] failed to download, retrying once with %s...\n", url));\r
+               *sess = dash_io->create(dash_io, 0, url);\r
+               if (! (*sess)) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot retry to download %s... OUT of memory ?\n", url));\r
+                       return GF_OUT_OF_MEM;\r
+               }\r
+\r
+               if (retry) {\r
+                       retry = 0;\r
+                       goto retry;\r
+               }\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] two consecutive failures, aborting the download %s.\n", url));\r
+               return e;\r
+       }\r
+case GF_OK:\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Download %s complete\n", url));\r
+       break;\r
+default:\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] FAILED to download %s = %s...\n", url, gf_error_to_string(e)));\r
+       return e;\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+static void gf_dash_get_timeline_duration(GF_MPD_SegmentTimeline *timeline, u32 *nb_segments, Double *max_seg_duration)\r
+{\r
+       u32 i, count;\r
+\r
+       *nb_segments = 0;\r
+       if (max_seg_duration) *max_seg_duration = 0;\r
+       count = gf_list_count(timeline->entries);\r
+       for (i=0; i<count; i++) {\r
+               GF_MPD_SegmentTimelineEntry *ent = gf_list_get(timeline->entries, i);\r
+               *nb_segments += 1 + ent->repeat_count;\r
+               if (max_seg_duration && (*max_seg_duration < ent->duration)) *max_seg_duration = ent->duration;\r
+       }\r
+}\r
+\r
+static void gf_dash_get_segment_duration(GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set, GF_MPD_Period *period, GF_MPD *mpd, u32 *nb_segments, Double *max_seg_duration)\r
+{\r
+       Double mediaDuration;\r
+       Bool single_segment = 0;\r
+       u32 timescale;\r
+       u64 duration;\r
+       GF_MPD_SegmentTimeline *timeline = NULL;\r
+       *nb_segments = timescale = 0;\r
+       duration = 0;\r
+\r
+       /*single segment*/\r
+       if (rep->segment_base || set->segment_base || period->segment_base) {\r
+               *max_seg_duration = mpd->media_presentation_duration;\r
+               *max_seg_duration /= 1000;\r
+               *nb_segments = 1;\r
+               return;\r
+       }\r
+       if (rep->segment_list || set->segment_list || period->segment_list) {\r
+               GF_List *segments = NULL;\r
+               if (period->segment_list) {\r
+                       if (period->segment_list->duration) duration = period->segment_list->duration;\r
+                       if (period->segment_list->timescale) timescale = period->segment_list->timescale;\r
+                       if (period->segment_list->segment_URLs) segments = period->segment_list->segment_URLs;\r
+                       if (period->segment_list->segment_timeline) timeline = period->segment_list->segment_timeline;\r
+               }\r
+               if (set->segment_list) {\r
+                       if (set->segment_list->duration) duration = set->segment_list->duration;\r
+                       if (set->segment_list->timescale) timescale = set->segment_list->timescale;\r
+                       if (set->segment_list->segment_URLs) segments = set->segment_list->segment_URLs;\r
+                       if (set->segment_list->segment_timeline) timeline = set->segment_list->segment_timeline;\r
+               }\r
+               if (rep->segment_list) {\r
+                       if (rep->segment_list->duration) duration = rep->segment_list->duration;\r
+                       if (rep->segment_list->timescale) timescale = rep->segment_list->timescale;\r
+                       if (rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;\r
+                       if (rep->segment_list->segment_timeline) timeline = rep->segment_list->segment_timeline;\r
+               }\r
+               if (! timescale) timescale=1;\r
+\r
+               if (timeline) {\r
+                       gf_dash_get_timeline_duration(timeline, nb_segments, max_seg_duration);\r
+                       if (max_seg_duration) *max_seg_duration /= timescale;\r
+               } else {\r
+                       if (segments) \r
+                               *nb_segments = gf_list_count(segments);\r
+                       if (max_seg_duration) {\r
+                               *max_seg_duration = (Double) duration;\r
+                               *max_seg_duration /= timescale;\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+\r
+       single_segment = 1;\r
+       if (period->segment_template) {\r
+               single_segment = 0;\r
+               if (period->segment_template->duration) duration = period->segment_template->duration;\r
+               if (period->segment_template->timescale) timescale = period->segment_template->timescale;\r
+               if (period->segment_template->segment_timeline) timeline = period->segment_template->segment_timeline;\r
+       }\r
+       if (set->segment_template) {\r
+               single_segment = 0;\r
+               if (set->segment_template->duration) duration = set->segment_template->duration;\r
+               if (set->segment_template->timescale) timescale = set->segment_template->timescale;\r
+               if (set->segment_template->segment_timeline) timeline = set->segment_template->segment_timeline;\r
+       }\r
+       if (rep->segment_template) {\r
+               single_segment = 0;\r
+               if (rep->segment_template->duration) duration = rep->segment_template->duration;\r
+               if (rep->segment_template->timescale) timescale = rep->segment_template->timescale;\r
+               if (rep->segment_template->segment_timeline) timeline = rep->segment_template->segment_timeline;\r
+       }\r
+       if (!timescale) timescale=1;\r
+\r
+       /*if no SegmentXXX is found, this is a single segment representation (onDemand profile)*/\r
+       if (single_segment) {\r
+               *max_seg_duration = mpd->media_presentation_duration;\r
+               *max_seg_duration /= 1000;\r
+               *nb_segments = 1;\r
+               return;\r
+       }\r
+\r
+       if (timeline) {\r
+               gf_dash_get_timeline_duration(timeline, nb_segments, max_seg_duration);\r
+               if (max_seg_duration) *max_seg_duration /= timescale;\r
+       } else {\r
+               if (max_seg_duration) {\r
+                       *max_seg_duration = (Double) duration;\r
+                       *max_seg_duration /= timescale;\r
+               }\r
+               mediaDuration = period->duration;\r
+               if (!mediaDuration) mediaDuration = mpd->media_presentation_duration;\r
+               if (mediaDuration && duration) {\r
+                       Double nb_seg = (Double) mediaDuration;\r
+                       /*duration is given in ms*/\r
+                       nb_seg /= 1000;\r
+                       nb_seg *= timescale;\r
+                       nb_seg /= duration;\r
+                       *nb_segments = (u32) nb_seg;\r
+                       if (*nb_segments < nb_seg) (*nb_segments)++;\r
+               }\r
+       }\r
+}\r
+\r
+static u64 gf_dash_segment_timeline_start(GF_MPD_SegmentTimeline *timeline, u32 segment_index)\r
+{\r
+       u64 start_time = 0;\r
+       u32 i, idx, k;\r
+       idx = 0;\r
+       for (i=0; i<gf_list_count(timeline->entries); i++) {\r
+               GF_MPD_SegmentTimelineEntry *ent = gf_list_get(timeline->entries, i);\r
+               if (ent->start_time) start_time = ent->start_time;              \r
+               for (k=0; k<ent->repeat_count+1; k++) {\r
+                       if (idx==segment_index) \r
+                               return start_time;\r
+                       idx ++;\r
+                       start_time += ent->duration;\r
+               }\r
+       }\r
+       return start_time;\r
+}\r
+\r
+static Double gf_dash_get_segment_start_time(GF_DASH_Group *group)\r
+{\r
+       GF_MPD_Representation *rep;\r
+       GF_MPD_AdaptationSet *set;\r
+       GF_MPD_Period *period;\r
+       Double start_time;\r
+       u32 timescale, segment_index;\r
+       u64 duration;\r
+       GF_MPD_SegmentTimeline *timeline = NULL;\r
+       timescale = 0;\r
+       duration = 0;\r
+       start_time = 0;\r
+\r
+       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+       set = group->adaptation_set;\r
+       period = group->period;\r
+       segment_index = group->download_segment_index - group->nb_cached_segments;\r
+\r
+       /*single segment: return nothing*/\r
+       if (rep->segment_base || set->segment_base || period->segment_base) {\r
+               return start_time;\r
+       }\r
+       if (rep->segment_list || set->segment_list || period->segment_list) {\r
+               if (period->segment_list) {\r
+                       if (period->segment_list->duration) duration = period->segment_list->duration;\r
+                       if (period->segment_list->timescale) timescale = period->segment_list->timescale;\r
+                       if (period->segment_list->segment_timeline) timeline = period->segment_list->segment_timeline;\r
+               }\r
+               if (set->segment_list) {\r
+                       if (set->segment_list->duration) duration = set->segment_list->duration;\r
+                       if (set->segment_list->timescale) timescale = set->segment_list->timescale;\r
+                       if (set->segment_list->segment_timeline) timeline = set->segment_list->segment_timeline;\r
+               }\r
+               if (rep->segment_list) {\r
+                       if (rep->segment_list->duration) duration = rep->segment_list->duration;\r
+                       if (rep->segment_list->timescale) timescale = rep->segment_list->timescale;\r
+                       if (rep->segment_list->segment_timeline) timeline = rep->segment_list->segment_timeline;\r
+               }\r
+               if (! timescale) timescale=1;\r
+\r
+               if (timeline) {\r
+                       start_time = (Double) gf_dash_segment_timeline_start(timeline, segment_index);\r
+               } else {\r
+                       start_time = segment_index * (Double) duration;\r
+               }\r
+               start_time /= timescale;\r
+               return start_time;\r
+       }\r
+\r
+       if (period->segment_template) {\r
+               if (period->segment_template->duration) duration = period->segment_template->duration;\r
+               if (period->segment_template->timescale) timescale = period->segment_template->timescale;\r
+               if (period->segment_template->segment_timeline) timeline = period->segment_template->segment_timeline;\r
+       }\r
+       if (set->segment_template) {\r
+               if (set->segment_template->duration) duration = set->segment_template->duration;\r
+               if (set->segment_template->timescale) timescale = set->segment_template->timescale;\r
+               if (set->segment_template->segment_timeline) timeline = set->segment_template->segment_timeline;\r
+       }\r
+       if (rep->segment_template) {\r
+               if (rep->segment_template->duration) duration = rep->segment_template->duration;\r
+               if (rep->segment_template->timescale) timescale = rep->segment_template->timescale;\r
+               if (rep->segment_template->segment_timeline) timeline = rep->segment_template->segment_timeline;\r
+       }\r
+       if (!timescale) timescale=1;\r
+\r
+       if (timeline) {\r
+               start_time = (Double) gf_dash_segment_timeline_start(timeline, segment_index);\r
+       } else {\r
+               start_time = segment_index * (Double) duration;\r
+       }\r
+       start_time /= timescale;\r
+       return start_time;\r
+}\r
+\r
+static void gf_dash_resolve_duration(GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set, GF_MPD_Period *period, u64 *out_duration, u32 *out_timescale, u64 *out_pts_offset, GF_MPD_SegmentTimeline **out_segment_timeline)\r
+{\r
+       u32 timescale = 0;\r
+       u64 pts_offset = 0;\r
+       GF_MPD_SegmentTimeline *segment_timeline;\r
+       GF_MPD_MultipleSegmentBase *mbase_rep, *mbase_set, *mbase_period;\r
+\r
+       if (out_segment_timeline) *out_segment_timeline = NULL;\r
+       if (out_pts_offset) *out_pts_offset = 0;\r
+\r
+       /*single media segment - duration is not known unless indicated in period*/\r
+       if (rep->segment_base || set->segment_base || period->segment_base) {\r
+               *out_duration = period ? period->duration : 0;\r
+               timescale = 0;\r
+               if (rep->segment_base && rep->segment_base->presentation_time_offset) pts_offset = rep->segment_base->presentation_time_offset;\r
+               if (rep->segment_base && rep->segment_base->timescale) timescale = rep->segment_base->timescale;\r
+               if (!pts_offset && set->segment_base && set->segment_base->presentation_time_offset) pts_offset = set->segment_base->presentation_time_offset;\r
+               if (!timescale && set->segment_base && set->segment_base->timescale) timescale = set->segment_base->timescale;\r
+               if (!pts_offset && period->segment_base && period->segment_base->presentation_time_offset) pts_offset = period->segment_base->presentation_time_offset;\r
+               if (!timescale && period->segment_base && period->segment_base->timescale) timescale = period->segment_base->timescale;\r
+\r
+               if (out_pts_offset) *out_pts_offset = pts_offset;\r
+               *out_timescale = timescale ? timescale : 1;\r
+               return;\r
+       }\r
+       /*we have a segment template list or template*/\r
+       mbase_rep = rep->segment_list ? (GF_MPD_MultipleSegmentBase *) rep->segment_list : (GF_MPD_MultipleSegmentBase *) rep->segment_template;\r
+       mbase_set = set->segment_list ? (GF_MPD_MultipleSegmentBase *)set->segment_list : (GF_MPD_MultipleSegmentBase *)set->segment_template;\r
+       mbase_period = period->segment_list ? (GF_MPD_MultipleSegmentBase *)period->segment_list : (GF_MPD_MultipleSegmentBase *)period->segment_template;\r
+\r
+       segment_timeline = NULL;\r
+       if (mbase_period) segment_timeline =  mbase_period->segment_timeline;\r
+       if (mbase_set && mbase_set->segment_timeline) segment_timeline =  mbase_set->segment_timeline;\r
+       if (mbase_rep && mbase_rep->segment_timeline) segment_timeline =  mbase_rep->segment_timeline;\r
+\r
+       timescale = mbase_rep ? mbase_rep->timescale : 0;\r
+       if (!timescale && mbase_set && mbase_set->timescale) timescale = mbase_set->timescale;\r
+       if (!timescale && mbase_period && mbase_period->timescale) timescale  = mbase_period->timescale;\r
+       if (!timescale) timescale = 1;\r
+       *out_timescale = timescale;\r
+\r
+       if (out_pts_offset) {\r
+               pts_offset = mbase_rep ? mbase_rep->presentation_time_offset : 0;\r
+               if (!pts_offset && mbase_set && mbase_set->presentation_time_offset) pts_offset = mbase_set->presentation_time_offset;\r
+               if (!pts_offset && mbase_period && mbase_period->presentation_time_offset) pts_offset = mbase_period->presentation_time_offset;\r
+               *out_pts_offset = pts_offset;\r
+       }\r
+\r
+       if (mbase_rep && mbase_rep->duration) *out_duration = mbase_rep->duration;\r
+       else if (mbase_set && mbase_set->duration) *out_duration = mbase_set->duration;\r
+       else if (mbase_period && mbase_period->duration) *out_duration = mbase_period->duration;\r
+\r
+       if (out_segment_timeline) *out_segment_timeline = segment_timeline;\r
+\r
+       /*for SegmentTimeline, just pick the first one as an indication (exact timeline solving is not done here)*/\r
+       if (segment_timeline) {\r
+               GF_MPD_SegmentTimelineEntry *ent = gf_list_get(segment_timeline->entries, 0);\r
+               if (ent) *out_duration = ent->duration;\r
+       }\r
+}\r
+\r
+static GF_Err gf_dash_merge_segment_timeline(GF_MPD_SegmentList *old_list, GF_MPD_SegmentTemplate *old_template, GF_MPD_SegmentList *new_list, GF_MPD_SegmentTemplate *new_template, Double min_start_time)\r
+{\r
+       GF_MPD_SegmentTimeline *old_timeline, *new_timeline;\r
+       u32 idx;\r
+       u64 start_time;\r
+       GF_MPD_SegmentTimelineEntry *first_new_entry;\r
+\r
+       old_timeline = new_timeline = NULL;\r
+       if (old_list && old_list->segment_timeline) {\r
+               if (!new_list || !new_list->segment_timeline) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: segment timeline not present in new MPD segmentList\n"));\r
+                       return GF_NON_COMPLIANT_BITSTREAM;\r
+               }\r
+               old_timeline = old_list->segment_timeline;\r
+               new_timeline = new_list->segment_timeline;\r
+       } else if (old_template && old_template->segment_timeline) {\r
+               if (!new_template || !new_template->segment_timeline) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: segment timeline not present in new MPD segmentTemplate\n"));\r
+                       return GF_NON_COMPLIANT_BITSTREAM;\r
+               }\r
+               old_timeline = old_template->segment_timeline;\r
+               new_timeline = new_template->segment_timeline;\r
+       }\r
+       if (!old_timeline && !new_timeline) return GF_OK;\r
+\r
+       first_new_entry  = gf_list_get(new_timeline->entries, 0);\r
+       idx = 0;\r
+       start_time=0;\r
+       while (1) {\r
+               GF_MPD_SegmentTimelineEntry *ent = gf_list_get(old_timeline->entries, 0);\r
+               if (!ent) break;\r
+               if (ent->start_time) \r
+                       start_time = ent->start_time;\r
+               /*if starttime is equal or greater than first entry in new timeline, we're done*/\r
+               if (start_time >= first_new_entry->start_time)\r
+                       break;\r
+\r
+               /*if entry overlaps first entry in new timeline, remove segments*/\r
+               while (start_time + ent->duration * (1 + ent->repeat_count) > first_new_entry->start_time) {\r
+                       ent->repeat_count--;\r
+               }\r
+               /*we will insert the first entry in the new timeline, make sure we have a start*/\r
+               if (!idx && !ent->start_time) \r
+                       ent->start_time = start_time;\r
+\r
+               start_time += ent->duration * (1 + ent->repeat_count);\r
+\r
+               gf_list_insert(new_timeline->entries, ent, idx);\r
+               idx ++;\r
+               gf_list_rem(old_timeline->entries, 0);\r
+\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+static u32 gf_dash_purge_segment_timeline(GF_DASH_Group *group, Double min_start_time)\r
+{\r
+       u32 nb_removed, time_scale;\r
+       u64 start_time, min_start, duration;\r
+       GF_MPD_SegmentTimeline *timeline=NULL;\r
+       GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+\r
+       if (!min_start_time) return 0;\r
+       gf_dash_resolve_duration(rep, group->adaptation_set, group->period, &duration, &time_scale, NULL, &timeline);\r
+       if (!timeline) return 0;\r
+\r
+       min_start = (u64) (min_start_time*time_scale);\r
+       start_time = 0;\r
+       nb_removed=0;\r
+       while (1) {\r
+               GF_MPD_SegmentTimelineEntry *ent = gf_list_get(timeline->entries, 0);\r
+               if (!ent) break;\r
+               if (ent->start_time) start_time = ent->start_time;\r
+\r
+               while (start_time + ent->duration < min_start) {\r
+                       if (! ent->repeat_count) break;\r
+                       ent->repeat_count--;\r
+                       nb_removed++;\r
+                       start_time += ent->duration;\r
+               }\r
+               /*this entry is in our range, keep it and make sure it has a start time*/\r
+               if (start_time + ent->duration >= min_start) {\r
+                       if (!ent->start_time) ent->start_time = start_time;\r
+                       break;\r
+               }\r
+               start_time += ent->duration;\r
+               gf_list_rem(timeline->entries, 0);\r
+               gf_free(ent);\r
+               nb_removed++;\r
+       }\r
+       if (nb_removed) {\r
+               GF_MPD_SegmentList *segment_list;\r
+               /*update next download index*/\r
+               group->download_segment_index -= nb_removed;\r
+               /*clean segmentList*/\r
+               segment_list = NULL;\r
+               if (group->period && group->period->segment_list) segment_list = group->period->segment_list;\r
+               if (group->adaptation_set && group->adaptation_set->segment_list) segment_list = group->adaptation_set->segment_list;\r
+               if (rep && rep->segment_list) segment_list = rep->segment_list;\r
+\r
+               if (segment_list) {\r
+                       u32 i = nb_removed;\r
+                       while (i) {\r
+                               GF_MPD_SegmentURL *seg_url = gf_list_get(segment_list->segment_URLs, 0);\r
+                               gf_list_rem(segment_list->segment_URLs, 0);\r
+                               gf_mpd_segment_url_free(seg_url);\r
+                       }\r
+               }\r
+               group->nb_segments_purged += nb_removed;\r
+       }\r
+       return nb_removed;\r
+}\r
+\r
+static GF_Err gf_dash_update_manifest(GF_DashClient *dash)\r
+{\r
+       GF_Err e;\r
+       u32 group_idx, rep_idx, i, j;\r
+       GF_DOMParser *mpd_parser;\r
+       GF_MPD_Period *period, *new_period;\r
+       const char *local_url;\r
+       char mime[128];\r
+       char * purl;\r
+\r
+       if (!dash->mpd_dnload) {\r
+               local_url = purl = NULL;\r
+               if (!gf_list_count(dash->mpd->locations)) {\r
+                       FILE *t = fopen(dash->base_url, "rt");\r
+                       if (t) {\r
+                               local_url = dash->base_url;\r
+                               fclose(t);\r
+                       }\r
+                       if (!local_url) {\r
+                               /*we will no longer attempt to update the MPD ...*/\r
+                               dash->mpd->minimum_update_period = 0;\r
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: no HTTP source for MPD could be found\n"));\r
+                               return GF_BAD_PARAM;\r
+                       }\r
+               }\r
+               if (!local_url) {\r
+                       purl = gf_strdup(gf_list_get(dash->mpd->locations, 0));\r
+\r
+                       /*if no absolute URL, use <Location> to get MPD in case baseURL is relative...*/\r
+                       if (!strstr(dash->base_url, "://")) {\r
+                               gf_free(dash->base_url);\r
+                               dash->base_url = gf_strdup(purl);\r
+                       } \r
+               }\r
+       } else {\r
+               local_url = dash->dash_io->get_cache_name(dash->dash_io, dash->mpd_dnload);\r
+               if (!local_url) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: wrong cache file %s\n", local_url));\r
+                       return GF_IO_ERR;\r
+               }\r
+               gf_delete_file(local_url);\r
+               purl = gf_strdup( dash->dash_io->get_url(dash->dash_io, dash->mpd_dnload) );\r
+       }\r
+\r
+       /*if update location is specified, update - spec does not say whether location is a relative or absoute URL*/\r
+       if (gf_list_count(dash->mpd->locations)) {\r
+               char *update_loc = gf_list_get(dash->mpd->locations, 0);\r
+               char *update_url = gf_url_concatenate(purl, update_loc);\r
+               if (update_url) {\r
+                       gf_free(purl);\r
+                       purl = update_url;\r
+               }\r
+       }\r
+\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Updating Playlist %s...\n", purl ? purl : local_url));\r
+       if (purl) {\r
+               /*use non-persistent connection for MPD*/\r
+               e = gf_dash_download_resource(dash->dash_io, &(dash->mpd_dnload), purl, 0, 0, 0, NULL);\r
+               if (e!=GF_OK) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: download problem %s for MPD file\n", gf_error_to_string(e)));\r
+                       gf_free(purl);\r
+                       return e;\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Playlist %s updated with success\n", purl));\r
+               }\r
+               strcpy(mime, dash->dash_io->get_mime(dash->dash_io, dash->mpd_dnload) );\r
+               strlwr(mime);\r
+\r
+               /*in case the session has been restarted, local_url may have been destroyed - get it back*/\r
+               local_url = dash->dash_io->get_cache_name(dash->dash_io, dash->mpd_dnload);\r
+\r
+               /* Some servers, for instance http://tv.freebox.fr, serve m3u8 as text/plain */\r
+               if (gf_dash_is_m3u8_mime(mime) || strstr(purl, ".m3u8")) {\r
+                       gf_m3u8_to_mpd(local_url, purl, NULL, dash->reload_count, dash->mimeTypeForM3U8Segments, 0, M3U8_TO_MPD_USE_TEMPLATE, &dash->getter);\r
+               } else if (!gf_dash_is_dash_mime(mime)) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] mime '%s' should be m3u8 or mpd\n", mime));\r
+               }\r
+\r
+               gf_free(purl);\r
+               purl = NULL;\r
+       }\r
+\r
+       if (!gf_dash_check_mpd_root_type(local_url)) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: MPD file type is not correct %s\n", local_url));\r
+               return GF_NON_COMPLIANT_BITSTREAM;\r
+       }\r
+       {\r
+               u8 signature[sizeof(dash->lastMPDSignature)];\r
+               if (gf_sha1_file( local_url, signature)) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] : cannot SHA1 file %s\n", local_url));\r
+               } else {\r
+                       if (! memcmp( signature, dash->lastMPDSignature, sizeof(dash->lastMPDSignature))) {\r
+                               dash->reload_count++;\r
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] MPD file did not change for %d consecutive reloads\n", dash->reload_count));\r
+                               /*if the MPD did not change, we should refresh "soon" but cannot wait a full refresh cycle in case of \r
+                               low latencies as we could miss a segment*/\r
+                               dash->last_update_time += dash->mpd->minimum_update_period/2;\r
+                       } else {\r
+                               Double timeline_start_time;\r
+                               GF_MPD *new_mpd;\r
+                               dash->reload_count = 0;\r
+                               memccpy(dash->lastMPDSignature, signature, sizeof(char), sizeof(dash->lastMPDSignature));\r
+\r
+                               /* It means we have to reparse the file ... */\r
+                               /* parse the MPD */\r
+                               mpd_parser = gf_xml_dom_new();\r
+                               e = gf_xml_dom_parse(mpd_parser, local_url, NULL, NULL);\r
+                               if (e != GF_OK) {\r
+                                       gf_xml_dom_del(mpd_parser);\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: error in XML parsing %s\n", gf_error_to_string(e)));\r
+                                       return GF_NON_COMPLIANT_BITSTREAM;\r
+                               }\r
+                               new_mpd = gf_mpd_new();\r
+                               e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), new_mpd, purl);\r
+                               gf_xml_dom_del(mpd_parser);\r
+                               if (e) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: error in MPD creation %s\n", gf_error_to_string(e)));\r
+                                       gf_mpd_del(new_mpd);\r
+                                       return GF_NON_COMPLIANT_BITSTREAM;\r
+                               }\r
+\r
+                               /*TODO - check periods are the same !!*/\r
+                               period = gf_list_get(dash->mpd->periods, dash->active_period_index);\r
+                               new_period = gf_list_get(new_mpd->periods, dash->active_period_index);\r
+                               if (!new_period) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: missing period\n"));\r
+                                       gf_mpd_del(new_mpd);\r
+                                       return GF_NON_COMPLIANT_BITSTREAM;\r
+                               }\r
+\r
+                               if (gf_list_count(period->adaptation_sets) != gf_list_count(new_period->adaptation_sets)) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: missing AdaptationSet\n"));\r
+                                       gf_mpd_del(new_mpd);\r
+                                       return GF_NON_COMPLIANT_BITSTREAM;\r
+                               }\r
+\r
+                               timeline_start_time = 0;\r
+                               /*if not infinity for timeShift, compute min media time before merge and adjust it*/\r
+                               if (dash->mpd->time_shift_buffer_depth != (u32) -1) {\r
+                                       Double timeshift = dash->mpd->time_shift_buffer_depth;\r
+                                       timeshift /= 1000;\r
+\r
+                                       for (group_idx=0; group_idx<gf_list_count(dash->groups); group_idx++) {\r
+                                               GF_DASH_Group *group = gf_list_get(dash->groups, group_idx);\r
+                                               Double group_start = gf_dash_get_segment_start_time(group);\r
+                                               if (!group_idx || (timeline_start_time > group_start) ) timeline_start_time = group_start;\r
+                                       }\r
+                                       /*we can rewind our segments from timeshift*/\r
+                                       if (timeline_start_time > timeshift) timeline_start_time -= timeshift;\r
+                                       /*we can rewind all segments*/\r
+                                       else timeline_start_time = 0;\r
+                               }\r
+\r
+                               /*update segmentTimeline at Period level*/\r
+                               e = gf_dash_merge_segment_timeline(period->segment_list, period->segment_template, new_period->segment_list, new_period->segment_template, timeline_start_time);\r
+                               if (e) {\r
+                                       gf_mpd_del(new_mpd);\r
+                                       return e;\r
+                               }\r
+\r
+                               for (group_idx=0; group_idx<gf_list_count(dash->groups); group_idx++) {\r
+                                       GF_MPD_AdaptationSet *set, *new_set;\r
+                                       GF_DASH_Group *group = gf_list_get(dash->groups, group_idx);\r
+                                       if (group->selection != GF_DASH_GROUP_SELECTED) continue;\r
+                                       set = group->adaptation_set;\r
+                                       new_set = gf_list_get(new_period->adaptation_sets, group_idx);\r
+\r
+                                       if (gf_list_count(new_set->representations) != gf_list_count(group->adaptation_set->representations)) {\r
+                                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: missing representation in adaptation set\n"));\r
+                                               gf_mpd_del(new_mpd);\r
+                                               return GF_NON_COMPLIANT_BITSTREAM;\r
+                                       }\r
+\r
+                                       /*get all representations in both periods*/\r
+                                       for (rep_idx = 0; rep_idx <gf_list_count(group->adaptation_set->representations); rep_idx++) {\r
+                                               GF_List *segments, *new_segments;\r
+                                               GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, rep_idx);\r
+                                               GF_MPD_Representation *new_rep = gf_list_get(new_set->representations, rep_idx);\r
+\r
+                                               if (rep->segment_base || group->adaptation_set->segment_base || period->segment_base) {\r
+                                                       if (!new_rep->segment_base && !new_set->segment_base && !new_period->segment_base) {\r
+                                                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: representation does not use segment base as previous version\n"));\r
+                                                               gf_mpd_del(new_mpd);\r
+                                                               return GF_NON_COMPLIANT_BITSTREAM;\r
+                                                       }\r
+                                                       /*what else should we check ??*/\r
+\r
+                                                       /*OK, this rep is fine*/\r
+                                               }\r
+\r
+                                               else if (rep->segment_template || group->adaptation_set->segment_template || period->segment_template) {\r
+                                                       u32 start;\r
+                                                       if (!new_rep->segment_template && !new_set->segment_template && !new_period->segment_template) {\r
+                                                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: representation does not use segment template as previous version\n"));\r
+                                                               gf_mpd_del(new_mpd);\r
+                                                               return GF_NON_COMPLIANT_BITSTREAM;\r
+                                                       }\r
+                                                       start = 0;\r
+                                                       /*override new startNum with old one - otherwise we would need to get rid of the entries before the start number in the MPD ...*/\r
+                                                       if (period->segment_template && (period->segment_template->start_number != (u32) -1) ) start = period->segment_template->start_number;\r
+                                                       if (set->segment_template && (set->segment_template->start_number != (u32) -1) ) start = set->segment_template->start_number;\r
+                                                       if (rep->segment_template && (rep->segment_template->start_number != (u32) -1) ) start = rep->segment_template->start_number;\r
+\r
+                                                       if (new_period->segment_template && (new_period->segment_template->start_number != (u32) -1) ) new_period->segment_template->start_number = start;\r
+                                                       if (new_set->segment_template && (new_set->segment_template->start_number != (u32) -1) ) new_set->segment_template->start_number = start;\r
+                                                       if (new_rep->segment_template && (new_rep->segment_template->start_number != (u32) -1) ) new_rep->segment_template->start_number = start;\r
+\r
+                                                       /*OK, this rep is fine*/\r
+                                               }\r
+                                               else {\r
+                                                       /*we're using segment list*/\r
+                                                       assert(rep->segment_list || group->adaptation_set->segment_list || period->segment_list);\r
+\r
+                                                       if (!new_rep->segment_list && !new_set->segment_list && !new_period->segment_list) {\r
+                                                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update playlist: representation does not use segment list as previous version\n"));\r
+                                                               gf_mpd_del(new_mpd);\r
+                                                               return GF_NON_COMPLIANT_BITSTREAM;\r
+                                                       }\r
+                                                       /*get the segment list*/\r
+                                                       segments = new_segments = NULL;\r
+                                                       if (period->segment_list && period->segment_list->segment_URLs) segments = period->segment_list->segment_URLs;\r
+                                                       if (set->segment_list && set->segment_list->segment_URLs) segments = set->segment_list->segment_URLs;\r
+                                                       if (rep->segment_list && rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;\r
+\r
+                                                       if (new_period->segment_list && new_period->segment_list->segment_URLs) new_segments = new_period->segment_list->segment_URLs;\r
+                                                       if (new_set->segment_list && new_set->segment_list->segment_URLs) new_segments = new_set->segment_list->segment_URLs;\r
+                                                       if (new_rep->segment_list && new_rep->segment_list->segment_URLs) new_segments = new_rep->segment_list->segment_URLs;\r
+\r
+\r
+                                                       for (i=0; i<gf_list_count(new_segments); i++) {\r
+                                                               GF_MPD_SegmentURL *new_seg = gf_list_get(new_segments, i);\r
+                                                               Bool found = 0;\r
+                                                               for (j=0; j<gf_list_count(segments); j++) {\r
+                                                                       GF_MPD_SegmentURL *seg = gf_list_get(segments, j);\r
+                                                                       if (seg->media && new_seg->media && !strcmp(seg->media, new_seg->media)) {\r
+                                                                               found=1;\r
+                                                                               break;\r
+                                                                       }\r
+                                                                       if (seg->media_range && new_seg->media_range && (seg->media_range->start_range==new_seg->media_range->start_range) && (seg->media_range->end_range==new_seg->media_range->end_range) ) {\r
+                                                                               found=1;\r
+                                                                               break;\r
+                                                                       }\r
+                                                               }\r
+                                                               /*this is a new segment, merge it: we remove from new list and push to old one, before doing a final swap\r
+                                                               this ensures that indexing in the segment_list is still correct after merging*/\r
+                                                               if (!found) {\r
+                                                                       gf_list_rem(new_segments, i);\r
+                                                                       i--;\r
+                                                                       gf_list_add(segments, new_seg);\r
+                                                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Representation #%d: Adding new segment %s\n", rep_idx+1, new_seg->media));\r
+                                                               }\r
+                                                       }\r
+\r
+                                                       /*what else should we check ?*/\r
+\r
+                                                       /*swap segment list content*/\r
+                                                       gf_list_swap(new_segments, segments);\r
+\r
+                                                       /*current representation is the active one in the group - update the number of segments*/\r
+                                                       if (group->active_rep_index==rep_idx) {\r
+                                                               group->nb_segments_in_rep = gf_list_count(new_segments);\r
+                                                       }\r
+                                               }\r
+\r
+                                               e = gf_dash_merge_segment_timeline(rep->segment_list, rep->segment_template, new_rep->segment_list, new_rep->segment_template, timeline_start_time);\r
+                                               if (e) {\r
+                                                       gf_mpd_del(new_mpd);\r
+                                                       return e;\r
+                                               }\r
+\r
+                                               /*what else should we check ??*/\r
+\r
+\r
+                                               /*switch all intertnal GPAC stuff*/\r
+                                               memcpy(&new_rep->playback, &rep->playback, sizeof(GF_DASH_RepresentationPlayback));\r
+                                               if (rep->playback.cached_init_segment_url) rep->playback.cached_init_segment_url = NULL;\r
+\r
+                                               if (!new_rep->mime_type) {\r
+                                                       new_rep->mime_type = rep->mime_type;\r
+                                                       rep->mime_type = NULL;\r
+                                               }\r
+                                       }\r
+                                       /*update group/period to new period*/\r
+                                       j = gf_list_find(group->period->adaptation_sets, group->adaptation_set);\r
+                                       group->adaptation_set = gf_list_get(new_period->adaptation_sets, j);\r
+                                       group->period = new_period;\r
+\r
+                                       /*update segmentTimeline at AdaptationSet level*/\r
+                                       e = gf_dash_merge_segment_timeline(set->segment_list, set->segment_template, new_set->segment_list, new_set->segment_template, timeline_start_time);\r
+                                       if (e) {\r
+                                               gf_mpd_del(new_mpd);\r
+                                               return e;\r
+                                       }\r
+\r
+                                       /*now that all possible SegmentXXX have been updated, purge them if needed: all segments ending before timeline_start_time\r
+                                       will be removed from MPD*/\r
+                                       if (timeline_start_time) {\r
+                                               u32 nb_segments_removed = gf_dash_purge_segment_timeline(group, timeline_start_time);\r
+                                               if (nb_segments_removed) {\r
+                                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] AdaptationSet %d - removed %d segments from timeline (%d since start of the period)\n", group_idx+1, nb_segments_removed, group->nb_segments_purged));\r
+                                               }\r
+                                       }\r
+\r
+                                       /*update number of segments in active rep*/\r
+                                       gf_dash_get_segment_duration(gf_list_get(group->adaptation_set->representations, group->active_rep_index), group->adaptation_set, group->period, new_mpd, &group->nb_segments_in_rep, NULL);\r
+\r
+                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Updated AdaptationSet %d - %d segments\n", group_idx+1, group->nb_segments_in_rep));\r
+\r
+                               }\r
+                               /*swap representations - we don't need to update download_segment_index as it still points to the right entry in the merged list*/\r
+                               if (dash->mpd)\r
+                                       gf_mpd_del(dash->mpd);\r
+                               dash->mpd = new_mpd;\r
+                               dash->last_update_time = gf_sys_clock();\r
+                       }\r
+               }\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+\r
+static void gf_dash_set_group_representation(GF_DASH_Group *group, GF_MPD_Representation *rep)\r
+{\r
+#ifndef GPAC_DISABLE_LOG\r
+       u32 width=0, height=0, samplerate=0;\r
+       GF_MPD_Fractional *framerate=NULL;\r
+#endif\r
+       u32 k;\r
+       GF_MPD_AdaptationSet *set;\r
+       GF_MPD_Period *period;\r
+       u32 i = gf_list_find(group->adaptation_set->representations, rep);\r
+       assert((s32) i >= 0);\r
+\r
+       group->active_rep_index = i;\r
+       group->active_bitrate = rep->bandwidth;\r
+       group->nb_segments_in_rep = 1;\r
+\r
+       group->min_bandwidth_selected = 1;\r
+       for (k=0; k<gf_list_count(group->adaptation_set->representations); k++) {\r
+               GF_MPD_Representation *arep = gf_list_get(group->adaptation_set->representations, k);\r
+               if (group->active_bitrate > arep->bandwidth) {\r
+                       group->min_bandwidth_selected = 0;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       set = group->adaptation_set;\r
+       period = group->period;\r
+\r
+#ifndef GPAC_DISABLE_LOG\r
+\r
+#define GET_REP_ATTR(_a)       _a = rep->_a; if (!_a) _a = set->_a;\r
+\r
+       GET_REP_ATTR(width);\r
+       GET_REP_ATTR(height);\r
+       GET_REP_ATTR(samplerate);\r
+       GET_REP_ATTR(framerate);\r
+\r
+       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] Switched to representation bandwidth %d kbps\n", rep->bandwidth/1024));\r
+       if (group->max_bitrate) GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("\tmax download bandwidth: %d kbps\n", group->max_bitrate/1024));\r
+       if (width&&height) {\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("\tWidth %d Height %d", width, height));\r
+               if (framerate) GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("framerate %d/%d", framerate->num, framerate->den));\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("\n"));\r
+       } else if (samplerate) {\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("\tsamplerate %d\n", samplerate));\r
+       }\r
+#endif\r
+\r
+\r
+       gf_dash_get_segment_duration(rep, set, period, group->dash->mpd, &group->nb_segments_in_rep, &group->segment_duration);\r
+}\r
+\r
+static void gf_dash_switch_group_representation(GF_DashClient *mpd, GF_DASH_Group *group)\r
+{\r
+       u32 i, bandwidth, min_bandwidth;\r
+       GF_MPD_Representation *rep_sel = NULL;\r
+       GF_MPD_Representation *min_rep_sel = NULL;\r
+       Bool min_bandwidth_selected = 0;\r
+       bandwidth = 0;\r
+       min_bandwidth = (u32) -1;\r
+\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Checking representations between %d and %d kbps\n", group->min_bitrate/1024, group->max_bitrate/1024));\r
+\r
+       if (group->force_representation_idx_plus_one) {\r
+               rep_sel = gf_list_get(group->adaptation_set->representations, group->force_representation_idx_plus_one - 1);\r
+               group->force_representation_idx_plus_one = 0;\r
+       } \r
+\r
+       if (!rep_sel) {\r
+               for (i=0; i<gf_list_count(group->adaptation_set->representations); i++) {\r
+                       GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, i);\r
+                       if (rep->playback.disabled) continue;\r
+                       if ((rep->bandwidth > bandwidth) && (rep->bandwidth < group->max_bitrate )) {\r
+                               rep_sel = rep;\r
+                               bandwidth = rep->bandwidth;\r
+                       }\r
+                       if (rep->bandwidth < min_bandwidth) {\r
+                               min_rep_sel = rep;\r
+                               min_bandwidth = rep->bandwidth;\r
+                       }\r
+               }\r
+       }\r
+\r
+       if (!rep_sel) {\r
+               if (!min_rep_sel) {\r
+                       min_rep_sel = gf_list_get(group->adaptation_set->representations, 0);\r
+               }\r
+               rep_sel = min_rep_sel;\r
+               min_bandwidth_selected = 1;\r
+       }\r
+       assert(rep_sel);\r
+       i = gf_list_find(group->adaptation_set->representations, rep_sel);\r
+\r
+       assert((s32) i >= 0);\r
+\r
+       group->force_switch_bandwidth = 0;\r
+       group->max_bitrate = 0;\r
+       group->min_bitrate = (u32) -1;\r
+\r
+       if (i != group->active_rep_index) {\r
+               if (min_bandwidth_selected) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] No representation found with bandwidth below %d kbps - using representation @ %d kbps\n", group->max_bitrate/1024, rep_sel->bandwidth/1024));\r
+               }\r
+               gf_dash_set_group_representation(group, rep_sel);\r
+       }\r
+}\r
+\r
+\r
+\r
+typedef enum\r
+{\r
+       GF_DASH_RESOLVE_URL_MEDIA,\r
+       GF_DASH_RESOLVE_URL_INIT,\r
+       GF_DASH_RESOLVE_URL_INDEX,\r
+} GF_DASHURLResolveType;\r
+\r
+\r
+GF_Err gf_dash_resolve_url(GF_MPD *mpd, GF_MPD_Representation *rep, GF_DASH_Group *group, char *mpd_url, GF_DASHURLResolveType resolve_type, u32 item_index, char **out_url, u64 *out_range_start, u64 *out_range_end, u64 *segment_duration)\r
+{\r
+       GF_MPD_BaseURL *url_child;\r
+       GF_MPD_SegmentTimeline *timeline = NULL;\r
+       u32 start_number = 1;\r
+       GF_MPD_AdaptationSet *set = group->adaptation_set;\r
+       GF_MPD_Period *period = group->period;\r
+       u32 timescale;\r
+       char *url;\r
+       char *url_to_solve, *solved_template, *first_sep, *media_url;\r
+       char *init_template, *index_template;\r
+\r
+       *out_range_start = *out_range_end = 0;\r
+       *out_url = NULL;\r
+\r
+       /*resolve base URLs from document base (download location) to representation (media)*/\r
+       url = gf_strdup(mpd_url);\r
+\r
+       url_child = gf_list_get(mpd->base_URLs, 0);\r
+       if (url_child) {\r
+               char *t_url = gf_url_concatenate(url, url_child->URL);\r
+               gf_free(url);\r
+               url = t_url;\r
+       }\r
+\r
+       url_child = gf_list_get(period->base_URLs, 0);\r
+       if (url_child) {\r
+               char *t_url = gf_url_concatenate(url, url_child->URL);\r
+               gf_free(url);\r
+               url = t_url;\r
+       }\r
+\r
+       url_child = gf_list_get(set->base_URLs, 0);\r
+       if (url_child) {\r
+               char *t_url = gf_url_concatenate(url, url_child->URL);\r
+               gf_free(url);\r
+               url = t_url;\r
+       }\r
+\r
+       url_child = gf_list_get(rep->base_URLs, 0);\r
+       if (url_child) {\r
+               char *t_url = gf_url_concatenate(url, url_child->URL);\r
+               gf_free(url);\r
+               url = t_url;\r
+       }\r
+\r
+       gf_dash_resolve_duration(rep, set, period, segment_duration, &timescale, NULL, NULL);\r
+       *segment_duration = (u32) ((Double) (*segment_duration) * 1000.0 / timescale);\r
+\r
+       /*single URL*/\r
+       if (rep->segment_base || set->segment_base || period->segment_base) {\r
+               GF_MPD_URL *res_url;\r
+               if (item_index>0) return GF_EOS;\r
+               switch (resolve_type) {\r
+               case GF_DASH_RESOLVE_URL_MEDIA:\r
+                       if (!url) return GF_NON_COMPLIANT_BITSTREAM;\r
+                       *out_url = url;\r
+                       return GF_OK;\r
+               case GF_DASH_RESOLVE_URL_INIT:\r
+               case GF_DASH_RESOLVE_URL_INDEX:\r
+                       res_url = NULL;\r
+                       if (resolve_type == GF_DASH_RESOLVE_URL_INDEX) {\r
+                               if (period->segment_base) res_url = period->segment_base->representation_index;\r
+                               if (set->segment_base) res_url = set->segment_base->representation_index;\r
+                               if (rep->segment_base) res_url = rep->segment_base->representation_index;\r
+                       } else {\r
+                               if (period->segment_base) res_url = period->segment_base->initialization_segment;\r
+                               if (set->segment_base) res_url = set->segment_base->initialization_segment;\r
+                               if (rep->segment_base) res_url = rep->segment_base->initialization_segment;\r
+                       }\r
+                       /*no initialization segment / index*/\r
+                       if (!res_url) {\r
+                               gf_free(url);\r
+                               return GF_OK;\r
+                       }\r
+                       if (res_url->sourceURL) {\r
+                               *out_url = gf_url_concatenate(url, res_url->sourceURL);\r
+                               gf_free(url);\r
+                       } else {\r
+                               *out_url = url;\r
+                       }\r
+                       if (res_url->byte_range) {\r
+                               *out_range_start = res_url->byte_range->start_range;\r
+                               *out_range_end = res_url->byte_range->end_range;\r
+                       }\r
+                       return GF_OK;\r
+               default:\r
+                       break;\r
+               }\r
+               gf_free(url);\r
+               return GF_BAD_PARAM;\r
+       }\r
+\r
+       /*segmentList*/\r
+       if (rep->segment_list || set->segment_list || period->segment_list) {   \r
+               GF_MPD_URL *init_url, *index_url;\r
+               GF_MPD_SegmentURL *segment;\r
+               GF_List *segments = NULL;\r
+               u32 segment_count;\r
+\r
+               init_url = index_url = NULL;\r
+\r
+               /*apply inheritance of attributes, lowest level having preceedence*/\r
+               if (period->segment_list) {\r
+                       if (period->segment_list->initialization_segment) init_url = period->segment_list->initialization_segment;\r
+                       if (period->segment_list->representation_index) index_url = period->segment_list->representation_index;\r
+                       if (period->segment_list->segment_URLs) segments = period->segment_list->segment_URLs;\r
+                       if (period->segment_list->start_number != (u32) -1) start_number = period->segment_list->start_number;\r
+                       if (period->segment_list->segment_timeline) timeline = period->segment_list->segment_timeline;\r
+               }\r
+               if (set->segment_list) {\r
+                       if (set->segment_list->initialization_segment) init_url = set->segment_list->initialization_segment;\r
+                       if (set->segment_list->representation_index) index_url = set->segment_list->representation_index;\r
+                       if (set->segment_list->segment_URLs) segments = set->segment_list->segment_URLs;\r
+                       if (set->segment_list->start_number != (u32) -1) start_number = set->segment_list->start_number;\r
+                       if (set->segment_list->segment_timeline) timeline = set->segment_list->segment_timeline;\r
+               }\r
+               if (rep->segment_list) {\r
+                       if (rep->segment_list->initialization_segment) init_url = rep->segment_list->initialization_segment;\r
+                       if (rep->segment_list->representation_index) index_url = rep->segment_list->representation_index;\r
+                       if (rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;\r
+                       if (rep->segment_list->start_number != (u32) -1) start_number = rep->segment_list->start_number;\r
+                       if (rep->segment_list->segment_timeline) timeline = rep->segment_list->segment_timeline;\r
+               }\r
+\r
+\r
+               segment_count = gf_list_count(segments);\r
+\r
+               switch (resolve_type) {\r
+               case GF_DASH_RESOLVE_URL_INIT:\r
+                       if (init_url) {\r
+                               if (init_url->sourceURL) {\r
+                                       *out_url = gf_url_concatenate(url, init_url->sourceURL);\r
+                                       gf_free(url);\r
+                               } else {\r
+                                       *out_url = url;\r
+                               }\r
+                               if (init_url->byte_range) {\r
+                                       *out_range_start = init_url->byte_range->start_range;\r
+                                       *out_range_end = init_url->byte_range->end_range;\r
+                               }\r
+                       } else {\r
+                               gf_free(url);\r
+                       }\r
+                       return GF_OK;\r
+               case GF_DASH_RESOLVE_URL_MEDIA:\r
+                       if (!url) {\r
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Media URL is not set in segment list\n"));\r
+                               return GF_SERVICE_ERROR;\r
+                       }\r
+                       if (item_index >= segment_count) {\r
+                               gf_free(url);\r
+                               return GF_EOS;\r
+                       }\r
+                       *out_url = url;\r
+                       segment = gf_list_get(segments, item_index);\r
+                       if (segment->media) {\r
+                               *out_url = gf_url_concatenate(url, segment->media);\r
+                               gf_free(url);\r
+                       }\r
+                       if (segment->media_range) {\r
+                               *out_range_start = segment->media_range->start_range;\r
+                               *out_range_end = segment->media_range->end_range;\r
+                       }\r
+                       return GF_OK;\r
+               case GF_DASH_RESOLVE_URL_INDEX:\r
+                       if (item_index >= segment_count) {\r
+                               gf_free(url);\r
+                               return GF_EOS;\r
+                       }\r
+                       *out_url = url;\r
+                       segment = gf_list_get(segments, item_index);\r
+                       if (segment->index) {\r
+                               *out_url = gf_url_concatenate(url, segment->index);\r
+                               gf_free(url);\r
+                       }\r
+                       if (segment->index_range) {\r
+                               *out_range_start = segment->index_range->start_range;\r
+                               *out_range_end = segment->index_range->end_range;\r
+                       }\r
+                       return GF_OK;\r
+               default:\r
+                       break;\r
+               }\r
+               gf_free(url);\r
+               return GF_BAD_PARAM;\r
+       }\r
+\r
+       /*segmentTemplate*/\r
+       media_url = init_template = index_template = NULL;\r
+\r
+       /*apply inheritance of attributes, lowest level having preceedence*/\r
+       if (period->segment_template) {\r
+               if (period->segment_template->initialization) init_template = period->segment_template->initialization;\r
+               if (period->segment_template->index) index_template = period->segment_template->index;\r
+               if (period->segment_template->media) media_url = period->segment_template->media;\r
+               if (period->segment_template->start_number != (u32) -1) start_number = period->segment_template->start_number;\r
+               if (period->segment_template->segment_timeline) timeline = period->segment_template->segment_timeline;\r
+       }\r
+       if (set->segment_template) {\r
+               if (set->segment_template->initialization) init_template = set->segment_template->initialization;\r
+               if (set->segment_template->index) index_template = set->segment_template->index;\r
+               if (set->segment_template->media) media_url = set->segment_template->media;\r
+               if (set->segment_template->start_number != (u32) -1) start_number = set->segment_template->start_number;\r
+               if (set->segment_template->segment_timeline) timeline = set->segment_template->segment_timeline;\r
+       }\r
+       if (rep->segment_template) {\r
+               if (rep->segment_template->initialization) init_template = rep->segment_template->initialization;\r
+               if (rep->segment_template->index) index_template = rep->segment_template->index;\r
+               if (rep->segment_template->media) media_url = rep->segment_template->media;\r
+               if (rep->segment_template->start_number != (u32) -1) start_number = rep->segment_template->start_number;\r
+               if (rep->segment_template->segment_timeline) timeline = rep->segment_template->segment_timeline;\r
+       }\r
+\r
+       /*offset the start_number with the number of discarded segments (no longer in our lists)*/\r
+       start_number += group->nb_segments_purged;\r
+\r
+       if (!media_url) {\r
+               GF_MPD_BaseURL *base = gf_list_get(rep->base_URLs, 0);\r
+               if (!base) return GF_BAD_PARAM;\r
+               media_url = base->URL;\r
+       }\r
+       url_to_solve = NULL;\r
+       switch (resolve_type) {\r
+       case GF_DASH_RESOLVE_URL_INIT:\r
+               url_to_solve = init_template;\r
+               break;\r
+       case GF_DASH_RESOLVE_URL_MEDIA:\r
+               url_to_solve = media_url;\r
+               break;\r
+       case GF_DASH_RESOLVE_URL_INDEX:\r
+               url_to_solve = index_template;\r
+               break;\r
+       default:\r
+               gf_free(url);\r
+               return GF_BAD_PARAM;\r
+       }\r
+       if (!url_to_solve) {\r
+               gf_free(url);\r
+               return GF_OK;\r
+       }\r
+       /*let's solve the template*/\r
+       solved_template = gf_malloc(sizeof(char)*strlen(url_to_solve)*2);\r
+       solved_template[0] = 0;\r
+       strcpy(solved_template, url_to_solve);\r
+       first_sep = strchr(solved_template, '$');\r
+       if (first_sep) first_sep[0] = 0;\r
+\r
+       first_sep = strchr(url_to_solve, '$');\r
+       while (first_sep) {\r
+               char szPrintFormat[50];\r
+               char szFormat[100];\r
+               char *format_tag;\r
+               char *second_sep = strchr(first_sep+1, '$');\r
+               if (!second_sep) {\r
+                       gf_free(url);\r
+                       gf_free(solved_template);\r
+                       return GF_NON_COMPLIANT_BITSTREAM;\r
+               }\r
+               second_sep[0] = 0;\r
+               format_tag = strchr(first_sep+1, '%');\r
+               \r
+               if (format_tag) {\r
+                       strcpy(szPrintFormat, format_tag);\r
+                       format_tag[0] = 0;\r
+               } else {\r
+                       strcpy(szPrintFormat, "%d");\r
+               }\r
+               /* identifier is $$ -> replace by $*/\r
+               if (!strlen(first_sep+1)) {\r
+                       strcat(solved_template, "$");\r
+               }\r
+               else if (!strcmp(first_sep+1, "RepresentationID")) {\r
+                       strcat(solved_template, rep->id);\r
+               }\r
+               else if (!strcmp(first_sep+1, "Number")) {\r
+                       sprintf(szFormat, szPrintFormat, start_number + item_index);\r
+                       strcat(solved_template, szFormat);\r
+               }\r
+               else if (!strcmp(first_sep+1, "Index")) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Wrong template identifier Index detected - using Number instead\n\n"));\r
+                       sprintf(szFormat, szPrintFormat, start_number + item_index);\r
+                       strcat(solved_template, szFormat);\r
+               }\r
+               else if (!strcmp(first_sep+1, "Bandwidth")) {\r
+                       sprintf(szFormat, szPrintFormat, rep->bandwidth);\r
+                       strcat(solved_template, szFormat);\r
+               }\r
+               else if (!strcmp(first_sep+1, "Time")) {\r
+                       if (timeline) {\r
+                               /*uses segment timeline*/\r
+                               u32 k, nb_seg, cur_idx, nb_repeat;\r
+                               u64 time, start_time;\r
+                               nb_seg = gf_list_count(timeline->entries);\r
+                               cur_idx = 0;\r
+                               start_time=0;\r
+                               for (k=0; k<nb_seg; k++) {\r
+                                       GF_MPD_SegmentTimelineEntry *ent = gf_list_get(timeline->entries, k);\r
+                                       if (item_index>cur_idx+ent->repeat_count) {\r
+                                               cur_idx += 1 + ent->repeat_count;\r
+                                               if (ent->start_time) start_time = ent->start_time;\r
+\r
+                                               start_time += ent->duration * (1 + ent->repeat_count);\r
+                                               continue;\r
+                                       }\r
+                                       *segment_duration = ent->duration;\r
+                                       *segment_duration = (u32) ((Double) (*segment_duration) * 1000.0 / timescale);\r
+                                       nb_repeat = item_index - cur_idx;\r
+                                       time = ent->start_time ? ent->start_time : start_time;\r
+                                       time += nb_repeat * ent->duration;\r
+\r
+                                       /*replace final 'd' with LLD (%lld or I64d)*/\r
+                                       szPrintFormat[strlen(szPrintFormat)-1] = 0;\r
+                                       strcat(szPrintFormat, &LLD[1]);\r
+                                       sprintf(szFormat, szPrintFormat, time);\r
+                                       strcat(solved_template, szFormat);\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+               else {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Unknown template identifier %s - disabling rep\n\n", first_sep+1));\r
+                       *out_url = NULL;\r
+                       gf_free(url);\r
+                       gf_free(solved_template);\r
+                       group->selection = GF_DASH_GROUP_NOT_SELECTABLE;\r
+                       return GF_NON_COMPLIANT_BITSTREAM;\r
+               }\r
+               if (format_tag) format_tag[0] = '%';\r
+               second_sep[0] = '$';\r
+               /*look for next keyword - copy over remaining text if any*/\r
+               first_sep = strchr(second_sep+1, '$');\r
+               if (first_sep) first_sep[0] = 0;\r
+               if (strlen(second_sep+1)) \r
+                       strcat(solved_template, second_sep+1);\r
+               if (first_sep) first_sep[0] = '$';\r
+       }\r
+       *out_url = gf_url_concatenate(url, solved_template);\r
+       gf_free(url);\r
+       gf_free(solved_template);\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err gf_dash_download_init_segment(GF_DashClient *dash, GF_DASH_Group *group)\r
+{\r
+       GF_Err e;\r
+       char *base_init_url;\r
+       GF_MPD_Representation *rep;\r
+       u64 start_range, end_range;\r
+       /* This variable is 0 if there is a initURL, the index of first segment downloaded otherwise */\r
+       u32 nb_segment_read = 0;\r
+       if (!dash || !group)\r
+               return GF_BAD_PARAM;\r
+       gf_mx_p(dash->dl_mutex);\r
+\r
+       assert( group->adaptation_set && group->adaptation_set->representations );\r
+       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+       if (!rep) {\r
+               gf_mx_v(dash->dl_mutex);\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Unable to find any representation, aborting.\n"));\r
+               return GF_IO_ERR;\r
+       }\r
+       start_range = end_range = 0;\r
+\r
+       e = gf_dash_resolve_url(dash->mpd, rep, group, dash->base_url, GF_DASH_RESOLVE_URL_INIT, 0, &base_init_url, &start_range, &end_range, &group->current_downloaded_segment_duration);\r
+       if (e) {\r
+               gf_mx_v(dash->dl_mutex);\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Unable to resolve initialization URL: %s\n", gf_error_to_string(e) ));\r
+               return e;\r
+       }\r
+\r
+       /*no error and no init segment, go for media segment*/\r
+       if (!base_init_url) {\r
+               e = gf_dash_resolve_url(dash->mpd, rep, group, dash->base_url, GF_DASH_RESOLVE_URL_MEDIA, group->download_segment_index, &base_init_url, &start_range, &end_range, &group->current_downloaded_segment_duration);\r
+               if (e) {\r
+                       gf_mx_v(dash->dl_mutex);\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Unable to resolve media URL: %s\n", gf_error_to_string(e) ));\r
+                       return e;\r
+               }\r
+               nb_segment_read = 1;\r
+       } else if (!group->bitstream_switching) {\r
+               group->dont_delete_first_segment = 1;\r
+       }\r
+\r
+       if (!strstr(base_init_url, "://") || !strnicmp(base_init_url, "file://", 7) || !strnicmp(base_init_url, "views://", 8)) {\r
+               assert(!group->nb_cached_segments);\r
+               group->cached[0].cache = gf_strdup(base_init_url);\r
+               group->cached[0].url = gf_strdup(base_init_url);\r
+               group->cached[0].representation_index = group->active_rep_index;\r
+               group->prev_active_rep_index = group->active_rep_index;\r
+\r
+               group->nb_cached_segments = 1;\r
+               /*do not erase local files*/\r
+               group->local_files = 1;\r
+               group->download_segment_index += nb_segment_read;\r
+               group->segment_local_url = group->cached[0].cache;\r
+               group->local_url_start_range = start_range;\r
+               group->local_url_end_range = end_range;\r
+               rep->playback.cached_init_segment_url = gf_strdup(group->segment_local_url);\r
+               rep->playback.init_start_range = start_range;\r
+               rep->playback.init_end_range = end_range;\r
+\r
+\r
+               /*finally download all init segments if any*/\r
+               if (!group->bitstream_switching) {\r
+                       u32 k;\r
+                       for (k=0; k<gf_list_count(group->adaptation_set->representations); k++) {\r
+                               char *a_base_init_url = NULL;\r
+                               u64 a_start, a_end, a_dur;\r
+                               GF_MPD_Representation *a_rep = gf_list_get(group->adaptation_set->representations, k);\r
+                               if (a_rep==rep) continue;\r
+                               if (a_rep->playback.disabled) continue;\r
+\r
+                               e = gf_dash_resolve_url(dash->mpd, a_rep, group, dash->base_url, GF_DASH_RESOLVE_URL_INIT, 0, &a_base_init_url, &a_start, &a_end, &a_dur);\r
+                               if (!e && a_base_init_url) {\r
+                                       a_rep->playback.cached_init_segment_url = a_base_init_url;\r
+                                       rep->playback.init_start_range = a_start;\r
+                                       rep->playback.init_end_range =a_end ;\r
+                               } else if (e) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot solve initialization segment for representation: %s - discarding representation\n", gf_error_to_string(e) ));\r
+                                       a_rep->playback.disabled = 1;\r
+                               }\r
+                       }\r
+               }\r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] First segment is %s \n", group->segment_local_url));\r
+               gf_mx_v(dash->dl_mutex);\r
+               gf_free(base_init_url);\r
+               return GF_OK;\r
+       }\r
+\r
+       group->max_bitrate = 0;\r
+       group->min_bitrate = (u32)-1;\r
+       /*use persistent connection for segment downloads*/\r
+       e = gf_dash_download_resource(dash->dash_io, &(group->segment_download), base_init_url, start_range, end_range, 1, group);\r
+\r
+       if ((e==GF_OK) && group->force_switch_bandwidth && !dash->auto_switch_count) {\r
+               gf_dash_switch_group_representation(dash, group);\r
+               gf_mx_v(dash->dl_mutex);\r
+               return gf_dash_download_init_segment(dash, group);\r
+       }\r
+\r
+\r
+       if (e == GF_URL_ERROR && !base_init_url) { /* We have a 404 and started with segments */\r
+               /* It is possible that the first segment has been deleted while we made the first request...\r
+               * so we try with the next segment on some M3U8 servers */\r
+\r
+               gf_free(base_init_url);\r
+\r
+               e = gf_dash_resolve_url(dash->mpd, rep, group, dash->base_url, GF_DASH_RESOLVE_URL_MEDIA, group->download_segment_index + 1, &base_init_url, &start_range, &end_range, &group->current_downloaded_segment_duration);\r
+               if (!e) {\r
+                       gf_mx_v(dash->dl_mutex);\r
+                       return e;\r
+               }\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Download of first segment failed... retrying with second one : %s\n", base_init_url));\r
+               nb_segment_read = 2;\r
+               /*use persistent connection for segment downloads*/\r
+               e = gf_dash_download_resource(dash->dash_io, &(group->segment_download), base_init_url, 0, 0, 1, group);\r
+       } /* end of 404 */\r
+\r
+       if (e!= GF_OK && !group->segment_must_be_streamed) {\r
+               dash->mpd_stop_request = 1;\r
+               gf_mx_v(dash->dl_mutex);\r
+               gf_free(base_init_url);\r
+               return e;\r
+       } else {\r
+               char mime[128];\r
+               const char *mime_type;\r
+               if (!group->nb_segments_in_rep) {\r
+                       if (dash->mpd->type==GF_MPD_TYPE_STATIC) {\r
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] 0 segments in static representation, aborting\n"));\r
+                               gf_free(base_init_url);\r
+                               gf_mx_v(dash->dl_mutex);\r
+                               return GF_BAD_PARAM;\r
+                       }\r
+               } else if (group->nb_segments_in_rep < group->max_cached_segments) {\r
+                       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] Resizing to %u max_cached_segments elements instead of %u.\n", group->nb_segments_in_rep, group->max_cached_segments));\r
+                       /* OK, we have a problem, it may ends download */\r
+                       group->max_cached_segments = group->nb_segments_in_rep;\r
+               }\r
+\r
+               /* Mime-Type check */\r
+               mime_type = dash->dash_io->get_mime(dash->dash_io, group->segment_download) ;\r
+               strcpy(mime, mime_type ? mime_type : "");\r
+               strlwr(mime);\r
+\r
+               if (dash->mimeTypeForM3U8Segments) \r
+                       gf_free(dash->mimeTypeForM3U8Segments);\r
+               dash->mimeTypeForM3U8Segments = gf_strdup( mime );\r
+               mime_type = gf_dash_get_mime_type(NULL, rep, group->adaptation_set);\r
+\r
+               if (!rep->mime_type) {\r
+                       rep->mime_type = gf_strdup( mime_type ? mime_type : mime );\r
+                       mime_type = gf_dash_get_mime_type(NULL, rep, group->adaptation_set);\r
+               }\r
+\r
+               if (stricmp(mime, mime_type)) {\r
+                       Bool valid = 0;\r
+                       char *stype1, *stype2;\r
+                       stype1 = strchr(mime_type, '/');\r
+                       stype2 = strchr(mime, '/');\r
+                       if (stype1 && stype2 && !strcmp(stype1, stype2)) valid = 1;\r
+\r
+                       if (!valid && 0) {\r
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Mime '%s' is not correct for '%s', it should be '%s'\n", mime, base_init_url, mime_type));\r
+                               dash->mpd_stop_request = 0;\r
+                               gf_mx_v(dash->dl_mutex);\r
+                               gf_free(base_init_url);\r
+                               base_init_url = NULL;\r
+                               return GF_BAD_PARAM;\r
+                       }\r
+               }\r
+\r
+               if (group->segment_must_be_streamed ) {\r
+                       group->segment_local_url = dash->dash_io->get_url(dash->dash_io, group->segment_download);\r
+                       e = GF_OK;\r
+               } else {\r
+                       group->segment_local_url = dash->dash_io->get_cache_name(dash->dash_io, group->segment_download);\r
+               }\r
+\r
+               if ((e!=GF_OK) || !group->segment_local_url) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error with initialization segment: download result:%s, cache file:%s\n", gf_error_to_string(e), group->segment_local_url));\r
+                       dash->mpd_stop_request = 1;\r
+                       gf_mx_v(dash->dl_mutex);\r
+                       gf_free(base_init_url);\r
+                       return GF_BAD_PARAM;\r
+               } \r
+\r
+               assert(!group->nb_cached_segments);\r
+               group->cached[0].cache = gf_strdup(group->segment_local_url);\r
+               group->cached[0].url = gf_strdup( dash->dash_io->get_url(dash->dash_io, group->segment_download) );\r
+               group->cached[0].representation_index = group->active_rep_index;\r
+               rep->playback.cached_init_segment_url = gf_strdup(group->segment_local_url);\r
+               rep->playback.init_start_range = 0;\r
+               rep->playback.init_end_range = 0;\r
+\r
+               group->nb_cached_segments = 1;\r
+               group->download_segment_index += nb_segment_read;\r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Adding initialization segment %s to cache: %s\n", group->segment_local_url, group->cached[0].url ));\r
+               gf_mx_v(dash->dl_mutex);\r
+               gf_free(base_init_url);\r
+\r
+               /*finally download all init segments if any*/\r
+               if (!group->bitstream_switching) {\r
+                       u32 k;\r
+                       for (k=0; k<gf_list_count(group->adaptation_set->representations); k++) {\r
+                               char *a_base_init_url = NULL;\r
+                               u64 a_start, a_end, a_dur;\r
+                               GF_MPD_Representation *a_rep = gf_list_get(group->adaptation_set->representations, k);\r
+                               if (a_rep==rep) continue;\r
+                               if (a_rep->playback.disabled) continue;\r
+\r
+                               e = gf_dash_resolve_url(dash->mpd, a_rep, group, dash->base_url, GF_DASH_RESOLVE_URL_INIT, 0, &a_base_init_url, &a_start, &a_end, &a_dur);\r
+                               if (!e && a_base_init_url) {\r
+                                       e = gf_dash_download_resource(dash->dash_io, &(group->segment_download), a_base_init_url, a_start, a_end, 1, group);\r
+                                       if (e) {\r
+                                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot retrieve initialization segment %s for representation: %s - discarding representation\n", a_base_init_url, gf_error_to_string(e) ));\r
+                                               a_rep->playback.disabled = 1;\r
+                                       } else {\r
+                                               a_rep->playback.cached_init_segment_url = gf_strdup( dash->dash_io->get_cache_name(dash->dash_io, group->segment_download) );\r
+                                               rep->playback.init_start_range = 0;\r
+                                               rep->playback.init_end_range = 0;\r
+                                       }\r
+                                       gf_free(a_base_init_url);\r
+                               } else if (e) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Cannot solve initialization segment for representation: %s - discarding representation\n", gf_error_to_string(e) ));\r
+                                       a_rep->playback.disabled = 1;\r
+                               }\r
+\r
+                       }\r
+               }\r
+\r
+               return GF_OK;\r
+       }\r
+}\r
+\r
+static void gf_dash_skip_disabled_representation(GF_DASH_Group *group, GF_MPD_Representation *rep)\r
+{\r
+       s32 rep_idx = gf_list_find(group->adaptation_set->representations, rep);\r
+       while (1) {\r
+               rep_idx++;\r
+               if (rep_idx==gf_list_count(group->adaptation_set->representations)) rep_idx = 0;\r
+               rep = gf_list_get(group->adaptation_set->representations, rep_idx);\r
+               if (!rep->playback.disabled) break;\r
+       }\r
+       assert(rep && !rep->playback.disabled);\r
+       gf_dash_set_group_representation(group, rep);\r
+}\r
+\r
+static void gf_dash_reset_groups(GF_DashClient *dash)\r
+{\r
+       /*send playback destroy event*/\r
+       dash->dash_io->on_dash_event(dash->dash_io, GF_DASH_EVENT_DESTROY_PLAYBACK, GF_OK);\r
+\r
+       while (gf_list_count(dash->groups)) {\r
+               GF_DASH_Group *group = gf_list_last(dash->groups);\r
+               gf_list_rem_last(dash->groups);\r
+\r
+               if (group->urlToDeleteNext) {\r
+                       if (!dash->keep_files && !group->local_files)\r
+                               dash->dash_io->delete_cache_file(dash->dash_io, group->segment_download, group->urlToDeleteNext);\r
+\r
+                       gf_free(group->urlToDeleteNext);\r
+                       group->urlToDeleteNext = NULL;\r
+               }\r
+               if (group->segment_download) {\r
+                       dash->dash_io->del(dash->dash_io, group->segment_download);\r
+                       group->segment_download = NULL;\r
+               }\r
+               while (group->nb_cached_segments) {\r
+                       group->nb_cached_segments --;\r
+                       if (!dash->keep_files && !group->local_files)\r
+                               gf_delete_file(group->cached[group->nb_cached_segments].cache);\r
+\r
+                       gf_free(group->cached[group->nb_cached_segments].cache);\r
+                       gf_free(group->cached[group->nb_cached_segments].url);\r
+               }\r
+               gf_free(group->cached);\r
+\r
+               if (group->service_mime) \r
+                       gf_free(group->service_mime);\r
+               gf_free(group);\r
+       }\r
+       gf_list_del(dash->groups);\r
+       dash->groups = NULL;\r
+}\r
+\r
+\r
+/* create groups (implemntation of adaptations set) */\r
+GF_Err gf_dash_setup_groups(GF_DashClient *dash)\r
+{\r
+       GF_Err e;\r
+       u32 i, j, count;\r
+       GF_MPD_Period *period;\r
+\r
+       if (!dash->groups) {\r
+               dash->groups = gf_list_new();\r
+               if (!dash->groups) return GF_OUT_OF_MEM;\r
+       }\r
+\r
+       period = gf_list_get(dash->mpd->periods, dash->active_period_index);\r
+       if (!period) return GF_BAD_PARAM;\r
+\r
+       count = gf_list_count(period->adaptation_sets);\r
+       for (i=0; i<count; i++) {\r
+               u32 cache_duration;\r
+               Double seg_dur;\r
+               GF_DASH_Group *group;\r
+               Bool found = 0;\r
+               GF_MPD_AdaptationSet *set = gf_list_get(period->adaptation_sets, i);\r
+               for (j=0; j<gf_list_count(dash->groups); j++) {\r
+                       GF_DASH_Group *group = gf_list_get(dash->groups, j);\r
+                       if (group->adaptation_set==set) {\r
+                               found = 1;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               if (found) continue;\r
+\r
+\r
+               GF_SAFEALLOC(group, GF_DASH_Group);\r
+               if (!group) return GF_OUT_OF_MEM;\r
+               group->dash = dash;\r
+               group->adaptation_set = set;\r
+               group->period = period;\r
+\r
+               group->bitstream_switching = (set->bitstream_switching || period->bitstream_switching) ? 1 : 0;\r
+\r
+               seg_dur = 0;\r
+               for (j=0; j<gf_list_count(set->representations); j++) {\r
+                       Double dur;\r
+                       u32 nb_seg;\r
+                       gf_dash_get_segment_duration(gf_list_get(set->representations, j), set, period, dash->mpd, &nb_seg, &dur);\r
+                       if (dur>seg_dur) seg_dur = dur;\r
+               }\r
+\r
+               if (!seg_dur) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Cannot compute default segment duration\n"));\r
+               }\r
+\r
+               cache_duration = dash->max_cache_duration * 1000;\r
+               if (dash->mpd->min_buffer_time)\r
+                       cache_duration = dash->mpd->min_buffer_time;\r
+               group->max_cached_segments = 1;\r
+               if (seg_dur) {\r
+                       while (group->max_cached_segments * seg_dur * 1000 < cache_duration)\r
+                               group->max_cached_segments ++;\r
+\r
+                       /*we need one more entry in cache for segment being currently played*/\r
+                       group->max_cached_segments ++;\r
+               }\r
+\r
+               group->cached = gf_malloc(sizeof(segment_cache_entry)*group->max_cached_segments);\r
+               memset(group->cached, 0, sizeof(segment_cache_entry)*group->max_cached_segments);\r
+               if (!group->cached) {\r
+                       gf_free(group);\r
+                       return GF_OUT_OF_MEM;\r
+               }\r
+               e = gf_list_add(dash->groups, group);\r
+               if (e) {\r
+                       gf_free(group->cached);\r
+                       gf_free(group);\r
+                       return e;\r
+               }\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err gf_dash_setup_period(GF_DashClient *dash)\r
+{\r
+       u32 rep_i, group_i, nb_groups_ok;\r
+\r
+       /*setup all groups*/\r
+       gf_dash_setup_groups(dash);\r
+\r
+       nb_groups_ok = 0;\r
+       for (group_i=0; group_i<gf_list_count(dash->groups); group_i++) {\r
+               GF_MPD_Representation *rep_sel;\r
+               u32 active_rep, nb_rep;\r
+               const char *mime_type;\r
+               GF_DASH_Group *group = gf_list_get(dash->groups, group_i);\r
+\r
+               nb_rep = gf_list_count(group->adaptation_set->representations);\r
+\r
+               if ((nb_rep>1) && !group->adaptation_set->segment_alignment && !group->adaptation_set->subsegment_alignment) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] AdaptationSet without segmentAlignment flag set - ignoring because not supported\n"));\r
+                       continue;\r
+               }\r
+               if (group->adaptation_set->xlink_href) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] AdaptationSet with xlink:href to %s - ignoring because not supported\n", group->adaptation_set->xlink_href));\r
+                       continue;\r
+               }\r
+\r
+               /* Select the appropriate representation in the given period */\r
+               active_rep = 0;\r
+               for (rep_i = 0; rep_i < nb_rep; rep_i++) {\r
+                       GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, rep_i);\r
+                       rep_sel = gf_list_get(group->adaptation_set->representations, active_rep);\r
+\r
+                       if (rep_i) {\r
+                               Bool ok;\r
+                               char *sep;\r
+                               if ( !rep->codecs || !rep_sel->codecs ) continue;\r
+                               sep = strchr(rep_sel->codecs, '.');\r
+                               if (sep) sep[0] = 0;\r
+                               ok = !strnicmp(rep->codecs, rep_sel->codecs, strlen(rep_sel->codecs) );\r
+                               if (sep) sep[0] = '.';\r
+                               if (!ok) {\r
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Different codec types (%s vs %s) in same AdaptationSet - disabling %s\n", rep_sel->codecs, rep->codecs, rep->codecs));\r
+                                       rep->playback.disabled = 1;\r
+                                       continue;\r
+                               }\r
+                               if (rep->dependency_id) {\r
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Representation dependent on representation %d - not supported\n", rep->dependency_id));\r
+                                       rep->playback.disabled = 1;\r
+                                       continue;\r
+                               }\r
+                               if (rep->segment_list && rep->segment_list->xlink_href) {\r
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Representation SegmentList uses xlink:href to %s - disabling because not supported\n", rep->segment_list->xlink_href));\r
+                                       rep->playback.disabled = 1;\r
+                                       continue;\r
+                               }\r
+                       }\r
+\r
+                       switch (dash->first_select_mode) {\r
+                       case GF_DASH_SELECT_QUALITY_LOWEST:\r
+                               if (rep->quality_ranking && (rep->quality_ranking < rep_sel->quality_ranking)) {\r
+                                       active_rep = rep_i;\r
+                                       break;\r
+                               }/*fallthrough if quality is not indicated*/\r
+                       case GF_DASH_SELECT_BANDWIDTH_LOWEST:\r
+                               if (rep->bandwidth < rep_sel->bandwidth) {\r
+                                       active_rep = rep_i;\r
+                               }\r
+                               break;\r
+                       case GF_DASH_SELECT_QUALITY_HIGHEST:\r
+                               if (rep->quality_ranking > rep_sel->quality_ranking) {\r
+                                       active_rep = rep_i;\r
+                                       break;\r
+                               }/*fallthrough if quality is not indicated*/\r
+                       case GF_DASH_SELECT_BANDWIDTH_HIGHEST:\r
+                               if (rep->bandwidth > rep_sel->bandwidth) {\r
+                                       active_rep = rep_i;\r
+                               }\r
+                               break;\r
+                       default:\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               rep_sel = gf_list_get(group->adaptation_set->representations, active_rep);\r
+               gf_dash_set_group_representation(group, rep_sel);\r
+\r
+               if (dash->playback_start_range>=0) \r
+                       gf_dash_seek_group(dash, group);\r
+\r
+               mime_type = gf_dash_get_mime_type(NULL, rep_sel, group->adaptation_set);\r
+\r
+               if (!mime_type) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Missing MIME type for AdaptationSet - skipping\n"));\r
+                       continue;\r
+               }\r
+\r
+               /* TODO: Generate segment names if urltemplates are used */\r
+               if (!rep_sel->segment_base && !rep_sel->segment_list && !rep_sel->segment_template\r
+                       && !group->adaptation_set->segment_base && !group->adaptation_set->segment_list && !group->adaptation_set->segment_template\r
+                       && !group->period->segment_base && !group->period->segment_list && !group->period->segment_template\r
+                       && !gf_list_count(rep_sel->base_URLs)\r
+                       ) {\r
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Segment URLs are not present for AdaptationSet - skipping\n"));\r
+                               continue;\r
+               }\r
+\r
+               group->selection = GF_DASH_GROUP_NOT_SELECTED;\r
+               nb_groups_ok++;\r
+       }\r
+       if (!nb_groups_ok) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] No AdaptationSet could be selected in the MPD - Cannot play\n"));\r
+               return GF_NON_COMPLIANT_BITSTREAM;\r
+       }\r
+\r
+       /*and seek if needed*/\r
+       return GF_OK;\r
+}\r
+\r
+\r
+static u32 dash_main_thread_proc(void *par)\r
+{\r
+       GF_Err e;\r
+       GF_DashClient *dash = (GF_DashClient*) par;\r
+       GF_MPD_Representation *rep;\r
+       u32 i, group_count, ret = 0;\r
+       Bool go_on = 1;\r
+       char *new_base_seg_url;\r
+       assert(dash);\r
+       if (!dash->mpd) {\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Incorrect state, no dash->mpd for URL=%s, already stopped ?\n", dash->base_url));\r
+               return 1;\r
+       }\r
+\r
+restart_period:\r
+\r
+       /* Setting the download status in exclusive code */\r
+       gf_mx_p(dash->dl_mutex);\r
+       dash->dash_state = GF_DASH_STATE_SETUP;\r
+       gf_mx_v(dash->dl_mutex);\r
+\r
+       dash->in_period_setup = 1;\r
+\r
+       dash->dash_io->on_dash_event(dash->dash_io, GF_DASH_EVENT_SELECT_GROUPS, GF_OK);\r
+\r
+       e = GF_OK;\r
+       group_count = gf_list_count(dash->groups);\r
+       for (i=0; i<group_count; i++) {\r
+               GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+               if (group->selection != GF_DASH_GROUP_SELECTED) continue;\r
+               e = gf_dash_download_init_segment(dash, group);\r
+               if (e) break;\r
+       }\r
+       dash->mpd_stop_request=0;\r
+\r
+       /*if error signal to the user*/\r
+       if (e != GF_OK) {\r
+               dash->dash_io->on_dash_event(dash->dash_io, GF_DASH_EVENT_PERIOD_SETUP_ERROR, e);\r
+               ret = 1;\r
+               goto exit;\r
+       }\r
+\r
+\r
+       dash->last_update_time = gf_sys_clock();\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+       dash->dash_state = GF_DASH_STATE_CONNECTING;\r
+       gf_mx_v(dash->dl_mutex);\r
+\r
+\r
+       /*ask the user to connect to desired groups*/\r
+       e = dash->dash_io->on_dash_event(dash->dash_io, GF_DASH_EVENT_CREATE_PLAYBACK, GF_OK);\r
+       if (e) {\r
+               ret = 1;\r
+               goto exit;\r
+       }\r
+       if (dash->mpd_stop_request) {\r
+               ret = 1;\r
+               goto exit;\r
+       }\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+       dash->in_period_setup = 0;\r
+       dash->dash_state = GF_DASH_STATE_RUNNING;\r
+       gf_mx_v(dash->dl_mutex);\r
+\r
+       while (go_on) {\r
+               const char *local_file_name = NULL;\r
+               const char *resource_name = NULL;\r
+               /*wait until next segment is needed*/\r
+               while (!dash->mpd_stop_request) {\r
+                       u32 timer = gf_sys_clock() - dash->last_update_time;\r
+                       Bool shouldParsePlaylist = dash->mpd->minimum_update_period && (timer > dash->mpd->minimum_update_period); \r
+\r
+                       if (shouldParsePlaylist) {\r
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Time to update the playlist (%u ms ellapsed since last refresh and min reoad rate is %u)\n", timer, dash->mpd->minimum_update_period));\r
+                               e = gf_dash_update_manifest(dash);\r
+                               group_count = gf_list_count(dash->groups);\r
+                               if (e) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error updating MPD %s\n", gf_error_to_string(e)));\r
+                               }\r
+                       } else {\r
+                               Bool all_groups_done = 1;\r
+                               Bool cache_full = 1;\r
+                               gf_mx_p(dash->dl_mutex);\r
+                               for (i=0; i<group_count; i++) {\r
+                                       GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+                                       if ((group->selection != GF_DASH_GROUP_SELECTED) || group->done) continue;\r
+                                       all_groups_done = 0;\r
+                                       if (group->nb_cached_segments<group->max_cached_segments) {\r
+                                               cache_full = 0;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               gf_mx_v(dash->dl_mutex);\r
+                               if (!cache_full) break;\r
+\r
+                               if (dash->request_period_switch==2) all_groups_done = 1;\r
+\r
+                               if (all_groups_done && dash->request_period_switch) {\r
+                                       gf_dash_reset_groups(dash);\r
+                                       if (dash->request_period_switch == 1) \r
+                                               dash->active_period_index++;\r
+\r
+                                       gf_dash_setup_period(dash);\r
+                                       dash->request_period_switch = 0;\r
+\r
+                                       goto restart_period;\r
+                               }\r
+\r
+                               gf_sleep(16);\r
+                       }\r
+               }\r
+\r
+               /* stop the thread if requested */\r
+               if (dash->mpd_stop_request) {\r
+                       go_on = 0;\r
+                       break;\r
+               }\r
+\r
+               /*for each selected groups*/\r
+               for (i=0; i<group_count; i++) {         \r
+                       u64 start_range, end_range;\r
+                       Bool use_byterange;\r
+                       u32 representation_index;\r
+                       GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+                       if (group->selection != GF_DASH_GROUP_SELECTED) continue;\r
+                       if (group->done) continue;\r
+\r
+\r
+                       if (group->nb_cached_segments>=group->max_cached_segments) {\r
+                               continue;\r
+                       }\r
+\r
+                       /*remember the active rep index, since group->active_rep_index may change because of bandwidth control algorithm*/\r
+                       representation_index = group->active_rep_index;\r
+                       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+\r
+                       /* if the index of the segment to be downloaded is greater or equal to the last segment (as seen in the playlist),\r
+                       we need to check if a new playlist is ready */\r
+                       if (group->nb_segments_in_rep && (group->download_segment_index>=group->nb_segments_in_rep)) {\r
+                               u32 timer = gf_sys_clock() - dash->last_update_time;\r
+                               /* update of the playlist, only if indicated */\r
+                               if (dash->mpd->minimum_update_period && timer > dash->mpd->minimum_update_period) {\r
+                                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Last segment in current playlist downloaded, checking updates after %u ms\n", timer));\r
+                                       e = gf_dash_update_manifest(dash);\r
+                                       if (e) {\r
+                                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error updating MPD %s\n", gf_error_to_string(e)));\r
+                                       }\r
+                                       group_count = gf_list_count(dash->groups);\r
+                                       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+                               } else {\r
+                                       gf_sleep(16);\r
+                               }\r
+                               /* Now that the playlist is up to date, we can check again */\r
+                               if (group->download_segment_index >= group->nb_segments_in_rep) {\r
+                                       if (dash->mpd->minimum_update_period) {\r
+                                               /* if there is a specified update period, we redo the whole process */\r
+                                               continue;\r
+                                       } else {\r
+                                               /* if not, we are really at the end of the playlist, we can quit */\r
+                                               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] End of playlist reached... downloading remaining elements..."));\r
+                                               group->done = 1;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       gf_mx_p(dash->dl_mutex);\r
+\r
+                       /*todo for live - check we don't attempt to request segments before their availabilityStartTime !*/\r
+\r
+                       /* At this stage, there are some segments left to be downloaded */\r
+                       e = gf_dash_resolve_url(dash->mpd, rep, group, dash->base_url, GF_DASH_RESOLVE_URL_MEDIA, group->download_segment_index, &new_base_seg_url, &start_range, &end_range, &group->current_downloaded_segment_duration);\r
+                       gf_mx_v(dash->dl_mutex);\r
+                       if (e) {\r
+                               /*do something!!*/\r
+                               break;\r
+                       }\r
+                       use_byterange = (start_range || end_range) ? 1 : 0;\r
+\r
+                       if (use_byterange) {\r
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Downloading new segment: %s (range: "LLD"-"LLD")\n", new_base_seg_url, start_range, end_range));\r
+                       }\r
+\r
+                       /*local file*/\r
+                       if (!strstr(new_base_seg_url, "://") || !strnicmp(new_base_seg_url, "file://", 7)) {\r
+                               resource_name = local_file_name = (char *) new_base_seg_url; \r
+                               e = GF_OK;\r
+                               /*do not erase local files*/\r
+                               group->local_files = 1;\r
+                               if (group->force_switch_bandwidth && !dash->auto_switch_count) {\r
+                                       gf_dash_switch_group_representation(dash, group);\r
+                                       /*restart*/\r
+                                       i--;\r
+                                       continue;\r
+                               }\r
+\r
+                       } else {\r
+                               u32 total_size, bytes_per_sec;\r
+\r
+                               group->max_bitrate = 0;\r
+                               group->min_bitrate = (u32)-1;\r
+                               /*use persistent connection for segment downloads*/\r
+                               if (use_byterange) {\r
+                                       e = gf_dash_download_resource(dash->dash_io, &(group->segment_download), new_base_seg_url, start_range, end_range, 1, group);\r
+                               } else {\r
+                                       e = gf_dash_download_resource(dash->dash_io, &(group->segment_download), new_base_seg_url, 0, 0, 1, group);\r
+                               }\r
+\r
+                               /*TODO decide what is the best, fetch from another representation or ignore ...*/\r
+                               if (e != GF_OK) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error in downloading new segment: %s %s\n", new_base_seg_url, gf_error_to_string(e)));\r
+                                       group->download_segment_index++;\r
+                                       continue;\r
+                               }\r
+\r
+                               if ((e==GF_OK) && group->force_switch_bandwidth) {\r
+                                       if (!dash->auto_switch_count) {\r
+                                               gf_dash_switch_group_representation(dash, group);\r
+                                               /*restart*/\r
+                                               i--;\r
+                                               continue;\r
+                                       }\r
+                                       if (rep->playback.disabled) {\r
+                                               gf_dash_skip_disabled_representation(group, rep);\r
+                                               /*restart*/\r
+                                               i--;\r
+                                               continue;\r
+                                       }\r
+                               }\r
+\r
+                               if (group->segment_must_be_streamed) local_file_name = dash->dash_io->get_url(dash->dash_io, group->segment_download);\r
+                               else local_file_name = dash->dash_io->get_cache_name(dash->dash_io, group->segment_download);\r
+\r
+                               resource_name = dash->dash_io->get_url(dash->dash_io, group->segment_download);\r
+\r
+                               total_size = dash->dash_io->get_total_size(dash->dash_io, group->segment_download);\r
+                               bytes_per_sec = dash->dash_io->get_bytes_per_sec(dash->dash_io, group->segment_download);\r
+\r
+                               if (total_size && bytes_per_sec && group->current_downloaded_segment_duration) {\r
+                                       Double bitrate, time;\r
+                                       bitrate = 8*total_size;\r
+                                       bitrate *= 1000;\r
+                                       bitrate /= group->current_downloaded_segment_duration;\r
+                                       bitrate /= 1024;\r
+                                       time = total_size;\r
+                                       time /= bytes_per_sec;\r
+\r
+                                       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] Downloaded segment %d bytes in %g seconds - duration %g sec - Bandwidth (kbps): indicated %d - computed %d - download %d\n", total_size, time, group->current_downloaded_segment_duration/1000.0, rep->bandwidth/1024, (u32) bitrate, 8*bytes_per_sec/1024));\r
+\r
+                                       if (rep->bandwidth < 8*bytes_per_sec) {\r
+                                               u32 k;\r
+                                               /*find highest bandwidth that fits our bitrate*/\r
+                                               GF_MPD_Representation *new_rep = NULL;\r
+                                               for (k=0; k<gf_list_count(group->adaptation_set->representations); k++) {\r
+                                                       GF_MPD_Representation *arep = gf_list_get(group->adaptation_set->representations, k);\r
+                                                       if (8*bytes_per_sec > arep->bandwidth) {\r
+                                                               if (!new_rep) new_rep = arep;\r
+                                                               else if (arep->bandwidth > new_rep->bandwidth) {\r
+                                                                       new_rep = arep;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                               if (!dash->disable_switching && new_rep && (new_rep!=rep)) {\r
+                                                       gf_dash_set_group_representation(group, new_rep);\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       if (local_file_name && (e == GF_OK || group->segment_must_be_streamed )) {\r
+                               gf_mx_p(dash->dl_mutex);\r
+                               assert(group->nb_cached_segments<group->max_cached_segments);\r
+                               assert( local_file_name );\r
+                               group->cached[group->nb_cached_segments].cache = gf_strdup(local_file_name);\r
+                               group->cached[group->nb_cached_segments].url = gf_strdup( resource_name );\r
+                               group->cached[group->nb_cached_segments].start_range = 0;\r
+                               group->cached[group->nb_cached_segments].end_range = 0;\r
+                               group->cached[group->nb_cached_segments].representation_index = representation_index;\r
+                               if (group->local_files && use_byterange) {\r
+                                       group->cached[group->nb_cached_segments].start_range = start_range;\r
+                                       group->cached[group->nb_cached_segments].end_range = end_range;\r
+                               }\r
+                               if (!group->local_files) {\r
+                                       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] Added file to cache (%u/%u in cache): %s\n", group->nb_cached_segments+1, group->max_cached_segments, group->cached[group->nb_cached_segments].url));\r
+                               }\r
+                               group->nb_cached_segments++;\r
+                               group->download_segment_index++;\r
+                               if (dash->auto_switch_count) {\r
+                                       group->nb_segments_done++;\r
+                                       if (group->nb_segments_done==dash->auto_switch_count) {\r
+                                               group->nb_segments_done=0;\r
+                                               gf_dash_skip_disabled_representation(group, rep);\r
+                                       }\r
+                               }\r
+                               gf_mx_v(dash->dl_mutex);\r
+                       }\r
+                       gf_free(new_base_seg_url);\r
+                       new_base_seg_url = NULL;\r
+               }\r
+       }\r
+\r
+exit:\r
+       /* Signal that the download thread has ended */\r
+       gf_mx_p(dash->dl_mutex);\r
+\r
+       /*an error occured during playback chain creation and we couldn't release our plyayback chain in time, do it now*/\r
+       if (dash->dash_state == GF_DASH_STATE_CONNECTING)\r
+               gf_dash_reset_groups(dash);\r
+\r
+       dash->dash_state = GF_DASH_STATE_STOPPED;\r
+       gf_mx_v(dash->dl_mutex);\r
+       return ret;\r
+}\r
+\r
+static u32 gf_dash_period_index_from_time(GF_DashClient *dash, u32 time)\r
+{\r
+       u32 i, count, cumul_start=0;\r
+       GF_MPD_Period *period;\r
+       count = gf_list_count(dash->mpd->periods);\r
+       for (i = 0; i<count; i++) {\r
+               period = gf_list_get(dash->mpd->periods, i);\r
+               if ((period->start > time) || (cumul_start > time)) {\r
+                       break;\r
+               }\r
+               cumul_start+=period->duration;\r
+       }\r
+       return (i-1 >= 0 ? (i-1) : 0);\r
+}\r
+\r
+static void gf_dash_download_stop(GF_DashClient *dash)\r
+{\r
+       u32 i;\r
+       assert( dash );\r
+       if (dash->groups) {\r
+               for (i=0; i<gf_list_count(dash->groups); i++) {\r
+                       GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+                       assert( group );\r
+                       if ((group->selection == GF_DASH_GROUP_SELECTED) && group->segment_download) {\r
+                               if (group->segment_download)\r
+                                       dash->dash_io->abort(dash->dash_io, group->segment_download);\r
+                               group->done = 1;\r
+                       }\r
+               }\r
+       }\r
+       /* stop the download thread */\r
+       gf_mx_p(dash->dl_mutex);\r
+       if (dash->dash_state != GF_DASH_STATE_STOPPED) {\r
+               dash->mpd_stop_request = 1;\r
+               gf_mx_v(dash->dl_mutex);\r
+               while (1) {\r
+                       /* waiting for the download thread to stop */\r
+                       gf_sleep(16);\r
+                       gf_mx_p(dash->dl_mutex);\r
+                       if (dash->dash_state != GF_DASH_STATE_RUNNING) {\r
+                               /* it's stopped we can continue */\r
+                               gf_mx_v(dash->dl_mutex);\r
+                               break;\r
+                       }\r
+                       gf_mx_v(dash->dl_mutex);\r
+               }\r
+       } else {\r
+               gf_mx_v(dash->dl_mutex);\r
+       }\r
+}\r
+\r
+\r
+\r
+Bool gf_dash_seek_periods(GF_DashClient *dash)\r
+{\r
+       Double start_time;\r
+       u32 i, period_idx;\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+\r
+       dash->start_range_in_segment_at_next_period = 0;\r
+       start_time = 0;\r
+       period_idx = 0;\r
+       for (i=0; i<=gf_list_count(dash->mpd->periods); i++) {\r
+               GF_MPD_Period *period = gf_list_get(dash->mpd->periods, i);\r
+               Double dur = period->duration;\r
+               dur /= 1000;\r
+               if (dash->playback_start_range >= start_time) {\r
+                       if ((i+1==gf_list_count(dash->mpd->periods)) || (dash->playback_start_range < start_time + dur) ) {\r
+                               period_idx = i;\r
+                               break;\r
+                       }\r
+               }\r
+               start_time += dur;\r
+       }\r
+       if (period_idx != dash->active_period_index) {\r
+               dash->playback_start_range -= start_time;\r
+               dash->active_period_index = period_idx;\r
+               dash->request_period_switch = 2;\r
+\r
+               /*figure out default segment duration and substract from our start range request*/\r
+               if (dash->playback_start_range) {\r
+                       Double duration;\r
+                       u32 nb_segs;\r
+                       GF_MPD_Period *period = gf_list_get(dash->mpd->periods, period_idx);\r
+                       GF_MPD_AdaptationSet *set = gf_list_get(period->adaptation_sets, 0);\r
+                       GF_MPD_Representation *rep = gf_list_get(set->representations, 0);\r
+\r
+                       gf_dash_get_segment_duration(rep, set, period, dash->mpd, &nb_segs, &duration);\r
+\r
+                       if (duration) {\r
+                               while (dash->playback_start_range - dash->start_range_in_segment_at_next_period >= duration)\r
+                                       dash->start_range_in_segment_at_next_period += duration;\r
+                       }\r
+\r
+               }\r
+       }\r
+       gf_mx_v(dash->dl_mutex);\r
+\r
+       return dash->request_period_switch ? 1 : 0;\r
+}\r
+\r
+static void gf_dash_seek_group(GF_DashClient *dash, GF_DASH_Group *group)\r
+{\r
+       Double seg_start;\r
+       u32 first_downloaded, last_downloaded, segment_idx;\r
+\r
+       group->force_segment_switch = 0;\r
+       if (!group->segment_duration) return;\r
+\r
+       /*figure out where to seek*/\r
+       segment_idx = 0;\r
+       seg_start = 0.0;\r
+       while (1) {\r
+               if ((dash->playback_start_range >= seg_start) && (dash->playback_start_range < seg_start + group->segment_duration)) \r
+                       break;\r
+               seg_start += group->segment_duration;\r
+               segment_idx++;\r
+       }\r
+       /*todo - seek to given duration*/\r
+       dash->playback_start_range -= seg_start;\r
+\r
+       first_downloaded = last_downloaded = group->download_segment_index;\r
+       if (group->download_segment_index +1 >= group->nb_cached_segments) {\r
+               first_downloaded = group->download_segment_index + 1 - group->nb_cached_segments;\r
+       }\r
+       /*we are seeking in our download range, just go on*/\r
+       if ((segment_idx >= first_downloaded) && (segment_idx<=last_downloaded)) return;\r
+\r
+       group->force_segment_switch = 1;\r
+       group->download_segment_index = segment_idx;\r
+\r
+       if (group->segment_download) \r
+               dash->dash_io->abort(dash->dash_io, group->segment_download);\r
+\r
+       if (group->urlToDeleteNext) {\r
+               if (!dash->keep_files && !group->local_files)\r
+                       dash->dash_io->delete_cache_file(dash->dash_io, group->segment_download, group->urlToDeleteNext);\r
+\r
+               gf_free(group->urlToDeleteNext);\r
+               group->urlToDeleteNext = NULL;\r
+       }\r
+       if (group->segment_download) {\r
+               dash->dash_io->del(dash->dash_io, group->segment_download);\r
+               group->segment_download = NULL;\r
+       }\r
+       while (group->nb_cached_segments) {\r
+               group->nb_cached_segments --;\r
+               if (!dash->keep_files && !group->local_files && !group->segment_must_be_streamed)\r
+                       gf_delete_file(group->cached[group->nb_cached_segments].cache);\r
+\r
+               gf_free(group->cached[group->nb_cached_segments].cache);\r
+               gf_free(group->cached[group->nb_cached_segments].url);\r
+               memset(&group->cached[group->nb_cached_segments], 0, sizeof(segment_cache_entry));\r
+       }\r
+}\r
+\r
+void gf_dash_seek_groups(GF_DashClient *dash)\r
+{\r
+       u32 i;\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+\r
+       if (dash->active_period_index) {\r
+               Double dur = 0;\r
+               u32 i;\r
+               for (i=0; i<dash->active_period_index; i++) {\r
+                       GF_MPD_Period *period = gf_list_get(dash->mpd->periods, dash->active_period_index-1);\r
+                       dur += period->duration/1000.0;\r
+               }\r
+               dash->playback_start_range -= dur;\r
+       }\r
+       for (i=0; i<gf_list_count(dash->groups); i++) {\r
+               GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+               gf_dash_seek_group(dash, group);\r
+       }\r
+       gf_mx_v(dash->dl_mutex);\r
+}\r
+\r
+\r
+static GF_Err http_ifce_get(GF_FileDownload *getter, char *url)\r
+{\r
+       GF_Err e;\r
+       GF_DashClient *dash = (GF_DashClient*) getter->udta;\r
+       GF_DASHFileIOSession *sess = dash->dash_io->create(dash->dash_io, 0, url);\r
+       if (!sess) return GF_IO_ERR;\r
+       getter->session = sess;\r
+       e = dash->dash_io->init(dash->dash_io, sess);\r
+       if (e) return e;\r
+       return dash->dash_io->run(dash->dash_io, sess);\r
+}\r
+\r
+static void http_ifce_clean(GF_FileDownload *getter)\r
+{\r
+       GF_DashClient *dash = (GF_DashClient*) getter->udta;\r
+       if (getter->session) dash->dash_io->del(dash->dash_io, getter->session);\r
+       getter->session = NULL;\r
+}\r
+\r
+static const char *http_ifce_cache_name(GF_FileDownload *getter)\r
+{\r
+       GF_DashClient *dash = (GF_DashClient*) getter->udta;\r
+       if (getter->session) return dash->dash_io->get_cache_name(dash->dash_io, getter->session);\r
+       return NULL;\r
+}\r
+\r
+GF_EXPORT\r
+GF_Err gf_dash_open(GF_DashClient *dash, const char *manifest_url)\r
+{\r
+       char local_path[GF_MAX_PATH];\r
+       const char *local_url;\r
+       GF_Err e;\r
+       GF_MPD_Period *period;\r
+       GF_DOMParser *mpd_parser;\r
+       Bool is_m3u8 = 0;\r
+       Bool is_local = 0;\r
+\r
+       if (!dash || !manifest_url) return GF_BAD_PARAM;\r
+\r
+       memset( dash->lastMPDSignature, 0, sizeof(dash->last_update_time));\r
+       dash->reload_count = 0;\r
+\r
+       if (dash->base_url) gf_free(dash->base_url);\r
+       dash->base_url = gf_strdup(manifest_url);\r
+\r
+       dash->getter.udta = dash;\r
+       dash->getter.new_session = http_ifce_get;\r
+       dash->getter.del_session = http_ifce_clean;\r
+       dash->getter.get_cache_name = http_ifce_cache_name;\r
+       dash->getter.session = NULL;\r
+\r
+\r
+\r
+       if (dash->mpd_dnload) dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+       dash->mpd_dnload = NULL;\r
+       local_url = NULL;\r
+\r
+       if (!strnicmp(manifest_url, "file://", 7)) {\r
+               local_url = manifest_url + 7;\r
+               is_local = 1;\r
+               if (strstr(manifest_url, ".m3u8")) {\r
+                       is_m3u8 = 1;\r
+               }\r
+       } else if (strstr(manifest_url, "://")) {\r
+               const char *reloc_url, *mtype;\r
+               char mime[128];\r
+               e = gf_dash_download_resource(dash->dash_io, &(dash->mpd_dnload), manifest_url, 0, 0, 1, NULL);\r
+               if (e!=GF_OK) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot connect service: MPD downloading problem %s for %s\n", gf_error_to_string(e), manifest_url));\r
+                       dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+                       dash->mpd_dnload = NULL;\r
+                       return e;\r
+               }\r
+\r
+               mtype = dash->dash_io->get_mime(dash->dash_io, dash->mpd_dnload);\r
+               strcpy(mime, mtype ? mtype : "");\r
+               strlwr(mime);\r
+\r
+               reloc_url = dash->dash_io->get_url(dash->dash_io, dash->mpd_dnload);\r
+               /* Some servers, for instance http://tv.freebox.fr, serve m3u8 as text/plain */\r
+               if (gf_dash_is_m3u8_mime(mime) || strstr(reloc_url, ".m3u8") || strstr(reloc_url, ".M3U8")) {\r
+                       is_m3u8 = 1;\r
+               } else if (!gf_dash_is_dash_mime(mime) && !strstr(reloc_url, ".mpd") && !strstr(reloc_url, ".MPD")) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] mime '%s' for '%s' should be m3u8 or mpd\n", mime, reloc_url));\r
+                       dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+                       dash->mpd_dnload = NULL;\r
+                       return GF_REMOTE_SERVICE_ERROR;\r
+               }\r
+\r
+               local_url = dash->dash_io->get_cache_name(dash->dash_io, dash->mpd_dnload);\r
+               if (!local_url) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot connect service: cache problem %s\n", local_url));\r
+                       dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+                       dash->mpd_dnload = NULL;\r
+                       return GF_IO_ERR;\r
+               }\r
+       } else {\r
+               local_url = manifest_url;\r
+               is_local = 1;\r
+               if (strstr(manifest_url, ".m3u8"))\r
+                       is_m3u8 = 1;\r
+       }\r
+\r
+       if (is_local) {\r
+               FILE *f = fopen(local_url, "rt");\r
+               if (!f) return GF_URL_ERROR;\r
+               fclose(f);\r
+       }\r
+\r
+       if (is_m3u8) {\r
+               if (is_local) {\r
+                       char *sep;\r
+                       strcpy(local_path, local_url);\r
+                       sep = strrchr(local_path, '.');\r
+                       if (sep) sep[0]=0;\r
+                       strcat(local_path, ".mpd");\r
+\r
+                       gf_m3u8_to_mpd(local_url, manifest_url, local_path, dash->reload_count, dash->mimeTypeForM3U8Segments, 0, M3U8_TO_MPD_USE_TEMPLATE, &dash->getter);\r
+                       local_url = local_path;\r
+               } else {\r
+                       gf_m3u8_to_mpd(local_url, manifest_url, NULL, dash->reload_count, dash->mimeTypeForM3U8Segments, 0, M3U8_TO_MPD_USE_TEMPLATE, &dash->getter);\r
+               }\r
+       }\r
+\r
+       if (!gf_dash_check_mpd_root_type(local_url)) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot connect service: wrong file type %s\n", local_url));\r
+               dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+               dash->mpd_dnload = NULL;\r
+               return GF_URL_ERROR;\r
+       }\r
+\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] parsing MPD %s\n", local_url));\r
+\r
+       /* parse the MPD */\r
+       mpd_parser = gf_xml_dom_new();\r
+       e = gf_xml_dom_parse(mpd_parser, local_url, NULL, NULL);\r
+       if (e != GF_OK) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot connect service: MPD parsing problem %s\n", gf_xml_dom_get_error(mpd_parser) ));\r
+               gf_xml_dom_del(mpd_parser);\r
+               dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+               dash->mpd_dnload = NULL;\r
+               return GF_URL_ERROR;\r
+       }\r
+       if (dash->mpd)\r
+               gf_mpd_del(dash->mpd);\r
+\r
+       dash->mpd = gf_mpd_new();\r
+       if (!dash->mpd) {\r
+               e = GF_OUT_OF_MEM;\r
+       } else {\r
+               e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), dash->mpd, manifest_url);\r
+       }\r
+       gf_xml_dom_del(mpd_parser);\r
+\r
+       if (e != GF_OK) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot connect service: MPD creation problem %s\n", gf_error_to_string(e)));\r
+               goto exit;\r
+       }\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] DASH client initialized from MPD\n"));\r
+       if (is_local && dash->mpd->minimum_update_period) {\r
+               e = gf_dash_update_manifest(dash);\r
+               if (e != GF_OK) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot update MPD: %s\n", gf_error_to_string(e)));\r
+                       goto exit;\r
+               }\r
+       }\r
+\r
+       /* Get the right period from the given time */\r
+       dash->active_period_index = gf_dash_period_index_from_time(dash, 0);\r
+       period = gf_list_get(dash->mpd->periods, dash->active_period_index);\r
+       if (!period || !gf_list_count(period->adaptation_sets) ) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error - cannot start: not enough periods or representations in MPD\n"));\r
+               e = GF_URL_ERROR;\r
+               goto exit;\r
+       }\r
+\r
+       e = gf_dash_setup_period(dash);\r
+       if (e) goto exit;\r
+\r
+       e = gf_th_run(dash->dash_thread, dash_main_thread_proc, dash);\r
+       gf_sleep(0);\r
+       return e;\r
+exit:\r
+       dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+       dash->mpd_dnload = NULL;\r
+\r
+       if (dash->mpd)\r
+               gf_mpd_del(dash->mpd);\r
+       dash->mpd = NULL;\r
+       return e;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_close(GF_DashClient *dash)\r
+{\r
+       assert( dash );\r
+\r
+       gf_dash_download_stop(dash);\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+       if (dash->mpd_dnload) {\r
+               dash->dash_io->del(dash->dash_io, dash->mpd_dnload);\r
+               dash->mpd_dnload = NULL;\r
+       }\r
+       if (dash->mpd)\r
+               gf_mpd_del(dash->mpd);\r
+       dash->mpd = NULL;\r
+\r
+       gf_mx_v(dash->dl_mutex);\r
+\r
+       if (dash->dash_state != GF_DASH_STATE_CONNECTING)\r
+               gf_dash_reset_groups(dash);\r
+}\r
+\r
+GF_EXPORT\r
+GF_DashClient *gf_dash_new(GF_DASHFileIO *dash_io, u32 max_cache_duration_sec, u32 auto_switch_count, Bool keep_files, Bool disable_switching, GF_DASHInitialSelectionMode first_select_mode)\r
+{\r
+       GF_DashClient *dash;\r
+       GF_SAFEALLOC(dash, GF_DashClient);\r
+       dash->dash_io = dash_io;\r
+\r
+       dash->dash_thread = gf_th_new("MPD Segment Downloader Thread");\r
+       dash->dl_mutex = gf_mx_new("MPD Segment Downloader Mutex");\r
+       dash->mimeTypeForM3U8Segments = gf_strdup( M3U8_UNKOWN_MIME_TYPE );\r
+\r
+       dash->max_cache_duration = max_cache_duration_sec;\r
+\r
+       dash->auto_switch_count = auto_switch_count;\r
+       dash->keep_files = keep_files;\r
+       dash->disable_switching = disable_switching;\r
+       dash->first_select_mode = first_select_mode;    \r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH] Client created\n"));\r
+       return dash;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_del(GF_DashClient *dash)\r
+{\r
+       gf_dash_close(dash);\r
+\r
+       gf_th_del(dash->dash_thread);\r
+       gf_mx_del(dash->dl_mutex);      \r
+\r
+       if (dash->mimeTypeForM3U8Segments) gf_free(dash->mimeTypeForM3U8Segments);\r
+       if (dash->base_url) gf_free(dash->base_url);\r
+\r
+       gf_free(dash);\r
+}\r
+\r
+GF_EXPORT\r
+u32 gf_dash_get_group_count(GF_DashClient *dash)\r
+{\r
+       return gf_list_count(dash->groups);\r
+}\r
+\r
+\r
+GF_EXPORT\r
+void *gf_dash_get_group_udta(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (!group) return NULL;\r
+       return group->udta;\r
+}\r
+\r
+GF_EXPORT\r
+GF_Err gf_dash_set_group_udta(GF_DashClient *dash, u32 idx, void *udta)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (!group) return GF_BAD_PARAM;\r
+       group->udta = udta;\r
+       return GF_OK;\r
+}\r
+\r
+GF_EXPORT\r
+Bool gf_dash_is_group_selected(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (!group) return 0;\r
+       return (group->selection == GF_DASH_GROUP_SELECTED) ? 1 : 0;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_get_info(GF_DashClient *dash, const char **title, const char **source)\r
+{\r
+       GF_MPD_ProgramInfo *info = gf_list_get(dash->mpd->program_infos, 0);\r
+       if (info) {\r
+               *title = info->title;\r
+               *source = info->source;\r
+       }\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_switch_quality(GF_DashClient *dash, Bool switch_up)\r
+{\r
+       u32 i;\r
+       for (i=0; i<gf_list_count(dash->groups); i++) {\r
+               Bool do_switch = 0;\r
+               GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+               u32 current_idx = group->active_rep_index;\r
+               if (group->selection != GF_DASH_GROUP_SELECTED) continue;\r
+\r
+               if (group->force_representation_idx_plus_one) current_idx = group->force_representation_idx_plus_one - 1;\r
+               if (switch_up) {\r
+                       if (current_idx + 1 < gf_list_count(group->adaptation_set->representations)) {\r
+                               group->force_representation_idx_plus_one = 1 + current_idx+1;\r
+                               do_switch = 1;\r
+                       }\r
+               } else {\r
+                       if (current_idx) {\r
+                               group->force_representation_idx_plus_one = 1 + current_idx - 1;\r
+                               do_switch = 1;\r
+                       }\r
+               }\r
+               if (do_switch) {\r
+                       gf_mx_p(dash->dl_mutex);\r
+                       group->force_switch_bandwidth = 1;\r
+                       /*in local playback just switch at the end of the current segment\r
+                       for remote, we should let the user decide*/\r
+                       while (group->nb_cached_segments>1) {\r
+                               group->nb_cached_segments--;\r
+                               gf_free(group->cached[group->nb_cached_segments].url);\r
+                               group->cached[group->nb_cached_segments].url = NULL;\r
+                               if (!group->local_files && group->cached[group->nb_cached_segments].cache) {\r
+                                       gf_delete_file( group->cached[group->nb_cached_segments].cache );\r
+                                       gf_free(group->cached[group->nb_cached_segments].cache);\r
+                                       group->cached[group->nb_cached_segments].cache = NULL;\r
+                               }\r
+                               group->cached[group->nb_cached_segments].representation_index = 0;\r
+                               group->cached[group->nb_cached_segments].start_range = 0;\r
+                               group->cached[group->nb_cached_segments].end_range = 0;\r
+                               assert(group->download_segment_index>1);\r
+                               group->download_segment_index--;\r
+                       }\r
+                       gf_mx_v(dash->dl_mutex);\r
+               }\r
+       }\r
+}\r
+\r
+GF_EXPORT\r
+Double gf_dash_get_duration(GF_DashClient *dash)\r
+{\r
+       Double duration;\r
+       duration = (Double)dash->mpd->media_presentation_duration;\r
+       if (!duration) {\r
+               u32 i;\r
+               for (i=0; i<gf_list_count(dash->mpd->periods); i++) {\r
+                       GF_MPD_Period *period = gf_list_get(dash->mpd->periods, i);\r
+                       duration += (Double)period->duration;\r
+               }\r
+       }\r
+       duration /= 1000;\r
+       return duration;\r
+}\r
+\r
+GF_EXPORT\r
+const char *gf_dash_get_url(GF_DashClient *dash)\r
+{\r
+       return dash->base_url;\r
+}\r
+\r
+GF_EXPORT\r
+const char *gf_dash_group_get_segment_mime(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_MPD_Representation *rep;\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (!group) return NULL;\r
+\r
+       rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+       return gf_dash_get_mime_type(NULL, rep, group->adaptation_set);\r
+}\r
+\r
+GF_EXPORT\r
+const char *gf_dash_group_get_segment_init_url(GF_DashClient *dash, u32 idx, u64 *start_range, u64 *end_range)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (!group) return NULL;\r
+\r
+       if (start_range) *start_range = group->local_url_start_range;\r
+       if (end_range) *end_range = group->local_url_end_range;         \r
+       return group->segment_local_url;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_group_select(GF_DashClient *dash, u32 idx, Bool select)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (!group) return;\r
+       if (group->selection == GF_DASH_GROUP_NOT_SELECTABLE)\r
+               return;\r
+\r
+       group->selection = select ? GF_DASH_GROUP_SELECTED : GF_DASH_GROUP_NOT_SELECTED;\r
+       /*this set is part of a group, make sure no all other sets from the indicated group are unselected*/\r
+       if (select && (group->adaptation_set->group>=0)) {\r
+               u32 i;\r
+               for (i=0; i<gf_dash_get_group_count(dash); i++) {\r
+                       GF_DASH_Group *agroup = gf_list_get(dash->groups, i);\r
+                       if (agroup==group) continue;\r
+\r
+                       /*either one Representation from group 0, if present,*/\r
+                       if ((group->adaptation_set->group==0)\r
+                               /*or the combination of at most one Representation from each non-zero group*/\r
+                               || (group->adaptation_set->group==agroup->adaptation_set->group) \r
+                               ) {\r
+                                       agroup->selection = GF_DASH_GROUP_NOT_SELECTED;\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_groups_set_language(GF_DashClient *dash, const char *lang_3cc)\r
+{\r
+       u32 i;\r
+       if (!lang_3cc) return;\r
+       for (i=0; i<gf_list_count(dash->groups); i++) {\r
+               GF_DASH_Group *group = gf_list_get(dash->groups, i);\r
+               if (group->selection==GF_DASH_GROUP_NOT_SELECTABLE) continue;\r
+               if (group->adaptation_set->lang && !stricmp(group->adaptation_set->lang, lang_3cc)) {\r
+                       gf_dash_group_select(dash, i, 1);\r
+               }\r
+       }\r
+}\r
+\r
+GF_EXPORT\r
+Bool gf_dash_is_running(GF_DashClient *dash) \r
+{\r
+       return dash->dash_state;\r
+}\r
+\r
+GF_EXPORT\r
+u32 gf_dash_get_period_switch_status(GF_DashClient *dash) \r
+{\r
+       return dash->request_period_switch;\r
+}\r
+GF_EXPORT\r
+void gf_dash_request_period_switch(GF_DashClient *dash)\r
+{\r
+       dash->request_period_switch = 1;\r
+}\r
+GF_EXPORT\r
+Bool gf_dash_in_last_period(GF_DashClient *dash) \r
+{\r
+       return (dash->active_period_index+1 < gf_list_count(dash->mpd->periods)) ? 0 : 1;\r
+}\r
+GF_EXPORT\r
+Bool gf_dash_in_period_setup(GF_DashClient *dash) \r
+{\r
+       return dash->in_period_setup;\r
+}\r
+\r
+GF_EXPORT\r
+u32 gf_dash_group_get_max_segments_in_cache(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       return group->max_cached_segments;\r
+}\r
+\r
+\r
+GF_EXPORT\r
+u32 gf_dash_group_get_num_segments_ready(GF_DashClient *dash, u32 idx, Bool *group_is_done)\r
+{\r
+       u32 res = 0;\r
+       GF_DASH_Group *group;\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+       group = gf_list_get(dash->groups, idx);\r
+\r
+       *group_is_done = 0;\r
+       if (!group) {\r
+               *group_is_done = 1;\r
+       } else {\r
+               *group_is_done = group->done;\r
+               res = group->nb_cached_segments;\r
+       }\r
+       gf_mx_v(dash->dl_mutex);\r
+       return res;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_group_discard_segment(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_DASH_Group *group;\r
+\r
+       gf_mx_p(dash->dl_mutex);\r
+       group = gf_list_get(dash->groups, idx);\r
+\r
+       if (!group->nb_cached_segments) {\r
+               gf_mx_v(dash->dl_mutex);        \r
+               return;\r
+       }\r
+       if (group->cached[0].cache) {\r
+               if (group->urlToDeleteNext) {\r
+                       if (!group->local_files && !dash->keep_files)\r
+                               dash->dash_io->delete_cache_file(dash->dash_io, group->segment_download, group->urlToDeleteNext);\r
+\r
+                       gf_free( group->urlToDeleteNext);\r
+                       group->urlToDeleteNext = NULL;\r
+               }\r
+               assert( group->cached[0].url );\r
+\r
+               if (group->dont_delete_first_segment) {\r
+                       group->dont_delete_first_segment = 0;\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] deleting cache file %s : %s\n", group->cached[0].url, group->cached[0].cache));\r
+                       group->urlToDeleteNext = gf_strdup( group->cached[0].url );\r
+               }\r
+\r
+               gf_free(group->cached[0].cache);\r
+               gf_free(group->cached[0].url);\r
+               group->cached[0].url = NULL;\r
+               group->cached[0].cache = NULL;\r
+               group->cached[0].representation_index = 0;\r
+       }\r
+       memmove(&group->cached[0], &group->cached[1], sizeof(segment_cache_entry)*(group->nb_cached_segments-1));\r
+       memset(&(group->cached[group->nb_cached_segments-1]), 0, sizeof(segment_cache_entry));\r
+       group->nb_cached_segments--;\r
+\r
+       gf_mx_v(dash->dl_mutex);\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_set_group_done(GF_DashClient *dash, u32 idx, Bool done)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (group) {\r
+               group->done = done;\r
+               if (done && group->segment_download) dash->dash_io->abort(dash->dash_io, group->segment_download);\r
+       }\r
+}\r
+\r
+GF_EXPORT\r
+GF_Err gf_dash_group_get_presentation_time_offset(GF_DashClient *dash, u32 idx, u64 *presentation_time_offset, u32 *timescale)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       if (group) {\r
+               u64 duration;\r
+               GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, group->active_rep_index);\r
+               gf_dash_resolve_duration(rep, group->adaptation_set, group->period, &duration, timescale, presentation_time_offset, NULL);\r
+               return GF_OK;\r
+       }\r
+       return GF_BAD_PARAM;\r
+}\r
+\r
+GF_EXPORT\r
+GF_Err gf_dash_group_get_next_segment_location(GF_DashClient *dash, u32 idx, const char **url, u64 *start_range, u64 *end_range, const char **switching_url, u64 *switching_start_range, u64 *switching_end_range, const char **original_url)\r
+{\r
+       GF_DASH_Group *group;\r
+\r
+       *url = NULL;\r
+       if (switching_url) *switching_url = NULL;\r
+       if (start_range) *start_range = 0;\r
+       if (end_range) *end_range = 0;\r
+       if (switching_start_range) *switching_start_range = 0;\r
+       if (switching_end_range) *switching_end_range = 0;\r
+       if (original_url) *original_url = NULL;\r
+\r
+       gf_mx_p(dash->dl_mutex);        \r
+       group = gf_list_get(dash->groups, idx);\r
+       if (!group->nb_cached_segments) {\r
+               gf_mx_v(dash->dl_mutex);        \r
+               return GF_BAD_PARAM;\r
+       }\r
+       *url = group->cached[0].cache;\r
+       if (start_range) \r
+               *start_range = group->cached[0].start_range;\r
+       if (end_range)\r
+               *end_range = group->cached[0].end_range;\r
+       if (original_url) *original_url = group->cached[0].url;\r
+\r
+       if (group->cached[0].representation_index != group->prev_active_rep_index) {\r
+               GF_MPD_Representation *rep = gf_list_get(group->adaptation_set->representations, group->cached[0].representation_index);\r
+               if (switching_start_range)\r
+                       *switching_start_range = rep->playback.init_start_range;\r
+               if (switching_end_range)\r
+                       *switching_end_range = rep->playback.init_end_range;\r
+               if (switching_url)\r
+                       *switching_url = rep->playback.cached_init_segment_url;\r
+       }\r
+       group->force_segment_switch = 0;\r
+       group->prev_active_rep_index = group->cached[0].representation_index;\r
+       gf_mx_v(dash->dl_mutex);        \r
+       return GF_OK;\r
+}\r
+\r
+GF_EXPORT\r
+void gf_dash_seek(GF_DashClient *dash, Double start_range)\r
+{\r
+       gf_mx_p(dash->dl_mutex);        \r
+       \r
+       dash->playback_start_range = start_range;\r
+       /*first check if we seek to another period*/\r
+       if (! gf_dash_seek_periods(dash)) {\r
+               /*if no, seek in group*/\r
+               gf_dash_seek_groups(dash);\r
+       }\r
+       gf_mx_v(dash->dl_mutex);        \r
+}\r
+\r
+GF_EXPORT\r
+Double gf_dash_get_playback_start_range(GF_DashClient *dash)\r
+{\r
+       return dash->playback_start_range;\r
+}\r
+\r
+GF_EXPORT\r
+Bool gf_dash_group_segment_switch_forced(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       return group->force_segment_switch;\r
+}\r
+\r
+GF_EXPORT\r
+Double gf_dash_group_current_segment_start_time(GF_DashClient *dash, u32 idx)\r
+{\r
+       GF_DASH_Group *group = gf_list_get(dash->groups, idx);\r
+       return gf_dash_get_segment_start_time(group);\r
+}\r
+\r
+#endif //GPAC_DISABLE_DASH_CLIENT\r
+\r
diff --git a/src/media_tools/dash_segmenter.c b/src/media_tools/dash_segmenter.c
new file mode 100644 (file)
index 0000000..f82e725
--- /dev/null
@@ -0,0 +1,3678 @@
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Jean Le Feuvre , Cyril Concolato\r
+ *                     Copyright (c) Telecom ParisTech 2000-2012\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / Media Tools sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *\r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ *\r
+ */\r
+\r
+#include <gpac/internal/media_dev.h>\r
+#include <gpac/constants.h>\r
+#include <gpac/mpegts.h>\r
+#include <gpac/config_file.h>\r
+#include <gpac/network.h>\r
+#ifndef _WIN32_WCE\r
+#include <time.h>\r
+#endif\r
+#include <gpac/internal/isomedia_dev.h>\r
+\r
+#ifdef GPAC_DISABLE_ISOM\r
+/*we should need a better way to work with sidx when no isom is defined*/\r
+#define GPAC_DISABLE_MPEG2TS\r
+#endif\r
+\r
+\r
+typedef struct _dash_segment_input GF_DashSegInput;\r
+\r
+struct _dash_component\r
+{\r
+       u32 ID;/*audio/video/text/ ...*/\r
+       u32 media_type;/*audio/video/text/ ...*/\r
+       char szCodec[50];\r
+       /*for video */\r
+       u32 width, height, fps_num, fps_denum, sar_num, sar_denum, max_sap;\r
+\r
+       /*for audio*/\r
+       u32 sample_rate, channels;\r
+       /*for anything*/\r
+       char szLang[4];\r
+};     \r
+\r
+typedef struct\r
+{\r
+       Double segment_duration;\r
+       Bool segments_start_with_rap;\r
+       FILE *mpd;\r
+       const char *mpd_name, *seg_rad_name, *seg_ext;\r
+       s32 subsegs_per_sidx;\r
+       Bool daisy_chain_sidx;\r
+       Bool use_url_template;\r
+       u32 single_file_mode;\r
+       s32 time_shift_depth;\r
+       Double subduration;\r
+       const char *bs_switch_segment_file;\r
+\r
+       /*set if seg_rad_name depends on input file name (had %s in it). In this case, SegmentTemplate cannot be used at adaptation set level*/\r
+       Bool variable_seg_rad_name;\r
+\r
+       Bool fragments_start_with_rap;\r
+       Double fragment_duration;\r
+\r
+       GF_Config *dash_ctx;\r
+\r
+       const char *tmpdir;\r
+} GF_DASHSegmenterOptions;\r
+\r
+struct _dash_segment_input\r
+{\r
+       char *file_name;\r
+       char representationID[100];\r
+       char periodID[100];\r
+       u32 bandwidth;\r
+\r
+       /*if 0, input is disabled*/\r
+       u32 adaptation_set;\r
+       /*if 0, input is disabled*/\r
+       u32 period;\r
+       u32 group_id;\r
+       /*only set for the first representation in the AdaptationSet*/\r
+       u32 nb_rep_in_adaptation_set;\r
+       Double period_duration;\r
+\r
+       /*media-format specific functions*/\r
+       /*assigns the different media to the same adaptation set or group than the input_idx one*/\r
+       GF_Err (* dasher_input_classify) (GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 input_idx, u32 *current_group_id, u32 *max_sap_type);\r
+       GF_Err ( *dasher_get_components_info) (GF_DashSegInput *dash_input, GF_DASHSegmenterOptions *opts);\r
+       GF_Err ( *dasher_create_init_segment) (GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 adaptation_set, char *szInitName, const char *tmpdir, Bool *disable_bs_switching);\r
+       GF_Err ( *dasher_segment_file) (GF_DashSegInput *dash_input, const char *szOutName, GF_DASHSegmenterOptions *opts, Bool first_in_set);\r
+\r
+       /*shall be set after call to dasher_input_classify*/\r
+       char szMime[50];\r
+\r
+       /*all these shall be set after call to dasher_get_components_info*/\r
+       Double duration;\r
+       struct _dash_component components[20];\r
+       u32 nb_components;\r
+};\r
+\r
+\r
+\r
+#define EXTRACT_FORMAT(_nb_chars)      \\r
+                       strcpy(szFmt, "%d");    \\r
+                       char_template+=_nb_chars;       \\r
+                       if (seg_rad_name[char_template]=='%') { \\r
+                               char *sep = strchr(seg_rad_name+char_template, '$');    \\r
+                               if (sep) {      \\r
+                                       sep[0] = 0;     \\r
+                                       strcpy(szFmt, seg_rad_name+char_template);      \\r
+                                       char_template += strlen(seg_rad_name+char_template);    \\r
+                                       sep[0] = '$';   \\r
+                               }       \\r
+                       }       \\r
+                       char_template+=1;       \\r
+\r
+GF_EXPORT\r
+GF_Err gf_media_mpd_format_segment_name(GF_DashTemplateSegmentType seg_type, Bool is_bs_switching, char *segment_name, const char *output_file_name, const char *rep_id, const char *seg_rad_name, const char *seg_ext, u64 start_time, u32 bandwidth, u32 segment_number)\r
+{\r
+       char szFmt[20];\r
+       Bool has_number=0;\r
+       Bool is_index = (seg_type==GF_DASH_TEMPLATE_REPINDEX) ? 1 : 0;\r
+       Bool is_init = (seg_type==GF_DASH_TEMPLATE_INITIALIZATION) ? 1 : 0;\r
+       Bool is_template = (seg_type==GF_DASH_TEMPLATE_TEMPLATE) ? 1 : 0;\r
+       Bool is_init_template = (seg_type==GF_DASH_TEMPLATE_INITIALIZATION_TEMPLATE) ? 1 : 0;\r
+       Bool needs_init=((is_init || is_init_template) && !is_bs_switching) ? 1 : 0;\r
+       u32 char_template = 0;\r
+       char tmp[100];\r
+       strcpy(segment_name, "");\r
+\r
+       if (seg_rad_name && (strstr(seg_rad_name, "$RepresentationID$") || strstr(seg_rad_name, "$ID$") || strstr(seg_rad_name, "$Bandwidth$"))) \r
+               needs_init = 0;\r
+       \r
+       if (!seg_rad_name) {\r
+               char *sep;\r
+               strcpy(segment_name, output_file_name);\r
+               sep = strrchr(segment_name, '.');\r
+               if (sep) sep[0] = 0;\r
+       } else {\r
+\r
+               while (1) {\r
+                       char c = seg_rad_name[char_template];\r
+                       if (!c) break;\r
+                       \r
+                       if (!is_template && !is_init_template && !strnicmp(& seg_rad_name[char_template], "$RepresentationID$", 18)) {\r
+                               char_template+=18;\r
+                               strcat(segment_name, rep_id);\r
+                               needs_init=0;\r
+                       }\r
+                       else if (!is_template && !is_init_template && !strnicmp(& seg_rad_name[char_template], "$Bandwidth", 10)) {\r
+                               EXTRACT_FORMAT(10);\r
+\r
+                               sprintf(tmp, szFmt, bandwidth);\r
+                               strcat(segment_name, tmp);\r
+                               needs_init=0;\r
+                       }\r
+                       else if (!is_template && !strnicmp(& seg_rad_name[char_template], "$Time", 5)) {\r
+                               EXTRACT_FORMAT(5);\r
+                               if (is_init || is_init_template) continue;\r
+                               /*replace %d to LLD*/\r
+                               szFmt[strlen(szFmt)-1]=0;\r
+                               strcat(szFmt, &LLD[1]);\r
+                               sprintf(tmp, szFmt, start_time);\r
+                               strcat(segment_name, tmp);\r
+                       }\r
+                       else if (!is_template && !strnicmp(& seg_rad_name[char_template], "$Number", 7)) {\r
+                               EXTRACT_FORMAT(7);\r
+\r
+                               if (is_init || is_init_template) continue;\r
+                               sprintf(tmp, szFmt, segment_number);\r
+                               strcat(segment_name, tmp);\r
+                               has_number=1;\r
+                       }\r
+                       else if (!strnicmp(& seg_rad_name[char_template], "$Init=", 6)) {\r
+                               char *sep = strchr(seg_rad_name + char_template+6, '$');\r
+                               if (sep) sep[0] = 0;\r
+                               if (is_init || is_init_template) {\r
+                                       strcat(segment_name, seg_rad_name + char_template+6);\r
+                                       needs_init=0;\r
+                               }\r
+                               char_template += strlen(seg_rad_name + char_template)+1;\r
+                               if (sep) sep[0] = '$';\r
+                       }\r
+                       else if (!strnicmp(& seg_rad_name[char_template], "$Index=", 7)) {\r
+                               char *sep = strchr(seg_rad_name + char_template+7, '$');\r
+                               if (sep) sep[0] = 0;\r
+                               if (is_index) {\r
+                                       strcat(segment_name, seg_rad_name + char_template+6);\r
+                                       needs_init=0;\r
+                               }\r
+                               char_template += strlen(seg_rad_name + char_template)+1;\r
+                               if (sep) sep[0] = '$';\r
+                       }\r
+                       \r
+                       else {\r
+                               char_template+=1;\r
+                               sprintf(tmp, "%c", c);\r
+                               strcat(segment_name, tmp);\r
+                       }\r
+               }\r
+       }\r
+\r
+       if (is_template && !strstr(seg_rad_name, "$Number"))\r
+               strcat(segment_name, "$Number$");\r
+\r
+       if (needs_init)\r
+               strcat(segment_name, "init");\r
+\r
+       if (!is_init && !is_template && !is_init_template && !is_index && !has_number) {\r
+               sprintf(tmp, "%d", segment_number);\r
+               strcat(segment_name, tmp);\r
+       }\r
+       if (seg_ext) {\r
+               strcat(segment_name, ".");\r
+               strcat(segment_name, seg_ext);\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+GF_Err gf_dasher_store_segment_info(GF_DASHSegmenterOptions *dash_cfg, const char *SegmentName, Double segStartTime)\r
+{\r
+       char szKey[512];\r
+       if (!dash_cfg->dash_ctx) return GF_OK;\r
+\r
+       sprintf(szKey, "%g", segStartTime);\r
+       return gf_cfg_set_key(dash_cfg->dash_ctx, "SegmentsStartTimes", SegmentName, szKey);\r
+}\r
+\r
+\r
+#ifndef GPAC_DISABLE_ISOM\r
+\r
+GF_Err gf_media_get_rfc_6381_codec_name(GF_ISOFile *movie, u32 track, char *szCodec)\r
+{\r
+       GF_ESD *esd;\r
+       GF_AVCConfig *avcc;\r
+       GF_AVCConfigSlot *sps;\r
+       u32 subtype = gf_isom_is_media_encrypted(movie, track, 1);\r
+       if (!subtype) subtype = gf_isom_get_media_subtype(movie, track, 1);\r
+\r
+       switch (subtype) {\r
+       case GF_ISOM_SUBTYPE_MPEG4:\r
+               esd = gf_isom_get_esd(movie, track, 1);\r
+               switch (esd->decoderConfig->streamType) {\r
+               case GF_STREAM_AUDIO:\r
+                       if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) {\r
+                               /*5 first bits of AAC config*/\r
+                               u8 audio_object_type = (esd->decoderConfig->decoderSpecificInfo->data[0] & 0xF8) >> 3;\r
+                               sprintf(szCodec, "mp4a.%02x.%02x", esd->decoderConfig->objectTypeIndication, audio_object_type);\r
+                       } else {\r
+                               sprintf(szCodec, "mp4a.%02x", esd->decoderConfig->objectTypeIndication);\r
+                       }\r
+                       break;\r
+               case GF_STREAM_VISUAL:\r
+#ifndef GPAC_DISABLE_AV_PARSERS\r
+                       if (esd->decoderConfig->decoderSpecificInfo) {\r
+                               GF_M4VDecSpecInfo dsi;\r
+                               gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);\r
+                               sprintf(szCodec, "mp4v.%02x.%02x", esd->decoderConfig->objectTypeIndication, dsi.VideoPL);\r
+                       } else\r
+#endif\r
+                       {\r
+                               sprintf(szCodec, "mp4v.%02x", esd->decoderConfig->objectTypeIndication);\r
+                       }\r
+                       break;\r
+               default:\r
+                       sprintf(szCodec, "mp4s.%02x", esd->decoderConfig->objectTypeIndication);\r
+                       break;\r
+               }\r
+               gf_odf_desc_del((GF_Descriptor *)esd);\r
+               return GF_OK;\r
+\r
+       case GF_ISOM_SUBTYPE_AVC_H264:\r
+       case GF_ISOM_SUBTYPE_AVC2_H264:\r
+       case GF_ISOM_SUBTYPE_SVC_H264:\r
+               avcc = gf_isom_avc_config_get(movie, track, 1);\r
+               sps = gf_list_get(avcc->sequenceParameterSets, 0);\r
+               if (sps)\r
+                       sprintf(szCodec, "%s.%02x%02x%02x", gf_4cc_to_str(subtype), (u8) sps->data[1], (u8) sps->data[2], (u8) sps->data[3]);\r
+               else {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISOM Tools] AVC/SVC SPS not known - setting codecs string to default value \"%s\"\n", gf_4cc_to_str(subtype) ));\r
+                       sprintf(szCodec, "%s", gf_4cc_to_str(subtype));\r
+               }\r
+               gf_odf_avc_cfg_del(avcc);\r
+               return GF_OK;\r
+       default:\r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_AUTHOR, ("[ISOM Tools] codec parameters not known - setting codecs string to default value \"%s\"\n", gf_4cc_to_str(subtype) ));\r
+               sprintf(szCodec, "%s", gf_4cc_to_str(subtype));\r
+               return GF_OK;\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+#endif //GPAC_DISABLE_ISOM\r
+\r
+\r
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS\r
+\r
+typedef struct\r
+{\r
+       Bool is_ref_track;\r
+       Bool done;\r
+       u32 TrackID;\r
+       u32 SampleNum, SampleCount;\r
+       u32 FragmentLength;\r
+       u32 OriginalTrack;\r
+       u32 finalSampleDescriptionIndex;\r
+       u32 TimeScale, MediaType, DefaultDuration, InitialTSOffset;\r
+       u64 last_sample_cts, next_sample_dts;\r
+       Bool all_sample_raps, splitable;\r
+       u32 split_sample_dts_shift;\r
+} GF_ISOMTrackFragmenter;\r
+\r
+static u64 isom_get_next_sap_time(GF_ISOFile *input, u32 track, u32 sample_count, u32 sample_num)\r
+{\r
+       GF_ISOSample *samp;\r
+       u64 time;\r
+       Bool is_rap, has_roll;\r
+       u32 i, found_sample = 0;\r
+       for (i=sample_num; i<=sample_count; i++) {\r
+               if (gf_isom_get_sample_sync(input, track, i)) {\r
+                       found_sample = i;\r
+                       break;\r
+               }\r
+               gf_isom_get_sample_rap_roll_info(input, track, i, &is_rap, &has_roll, NULL);\r
+               if (is_rap || has_roll) {\r
+                       found_sample = i;\r
+                       break;\r
+               }\r
+       }\r
+       if (!found_sample) return 0;\r
+       samp = gf_isom_get_sample_info(input, track, found_sample, NULL, NULL);\r
+       time = samp->DTS;\r
+       gf_isom_sample_del(&samp);\r
+       return time;\r
+}\r
+\r
+static GF_Err gf_media_isom_segment_file(GF_ISOFile *input, const char *output_file, Double max_duration_sec, GF_DASHSegmenterOptions *dash_cfg, GF_DashSegInput *dash_input, Bool first_in_set)\r
+{\r
+       u8 NbBits;\r
+       u32 i, TrackNum, descIndex, j, count, nb_sync, ref_track_id, nb_tracks_done;\r
+       u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, nb_samp, nb_done;\r
+       u32 nb_video, nb_audio, nb_text, nb_scene;\r
+       u8 defaultPadding;\r
+       u16 defaultDegradationPriority;\r
+       GF_Err e;\r
+       char sOpt[100], sKey[100];\r
+       char szCodecs[200], szCodec[100];\r
+       u32 cur_seg, fragment_index, max_sap_type;\r
+       GF_ISOFile *output, *bs_switch_segment;\r
+       GF_ISOSample *sample, *next;\r
+       GF_List *fragmenters;\r
+       u32 MaxFragmentDuration, MaxSegmentDuration, SegmentDuration, maxFragDurationOverSegment;\r
+       u32 presentationTimeOffset = 0;\r
+       Double segment_start_time, file_duration, period_duration, max_segment_duration;\r
+       u32 nb_segments, width, height, sample_rate, nb_channels, sar_w, sar_h, fps_num, fps_denum, startNumber, startNumberRewind;\r
+       char langCode[5];\r
+       u32 index_start_range, index_end_range;\r
+       Bool force_switch_segment = 0;\r
+       Bool switch_segment = 0;\r
+       Bool split_seg_at_rap = dash_cfg ? dash_cfg->segments_start_with_rap : 0;\r
+       Bool split_at_rap = 0;\r
+       Bool has_rap = 0;\r
+       Bool next_sample_rap = 0;\r
+       Bool flush_all_samples = 0;\r
+       Bool simulation_pass = 0;\r
+       Bool init_segment_deleted = 0;\r
+       u64 last_ref_cts = 0;\r
+       u64 start_range, end_range, file_size, init_seg_size, ref_track_first_dts, ref_track_next_cts;\r
+       u32 tfref_timescale = 0;\r
+       u32 bandwidth = 0;\r
+       GF_ISOMTrackFragmenter *tf, *tfref;\r
+       FILE *mpd_segs = NULL;\r
+       char SegmentName[GF_MAX_PATH];\r
+       char RepSecName[200];\r
+       char RepURLsSecName[200];\r
+       const char *opt;\r
+       Double max_track_duration = 0;\r
+       Bool bs_switching_is_output = 0;\r
+       Bool store_dash_params = 0;\r
+       Bool dash_moov_setup = 0;\r
+       Bool segments_start_with_sap = 1;\r
+       Bool first_sample_in_segment = 0;\r
+       u32 *segments_info = NULL;\r
+       u32 nb_segments_info = 0;\r
+       u32 timeline_timescale=1000;\r
+       Bool audio_only = 1;\r
+       Bool is_bs_switching = 0;\r
+       Bool use_url_template = dash_cfg ? dash_cfg->use_url_template : 0;\r
+       const char *seg_rad_name = dash_cfg ? dash_cfg->seg_rad_name : NULL;\r
+       const char *seg_ext = dash_cfg ? dash_cfg->seg_ext : NULL;\r
+       const char *bs_switching_segment_name = NULL;\r
+\r
+       SegmentName[0] = 0;\r
+       SegmentDuration = 0;\r
+       nb_samp = 0;\r
+       fragmenters = NULL;\r
+       if (!seg_ext) seg_ext = "m4s";\r
+\r
+       bs_switch_segment = NULL;\r
+       if (dash_cfg && dash_cfg->bs_switch_segment_file) {\r
+               bs_switch_segment = gf_isom_open(dash_cfg->bs_switch_segment_file, GF_ISOM_OPEN_READ, NULL);\r
+               if (bs_switch_segment) {\r
+                       bs_switching_segment_name = gf_url_get_resource_name(dash_cfg->bs_switch_segment_file);\r
+                       is_bs_switching = 1;\r
+               }\r
+       }\r
+       \r
+       sprintf(RepSecName, "Representation_%s", dash_input ? dash_input->representationID : "");\r
+       sprintf(RepURLsSecName, "URLs_%s", dash_input ? dash_input->representationID : "");\r
+\r
+       bandwidth = dash_input ? dash_input->bandwidth : 0;\r
+       file_duration = 0;\r
+\r
+       startNumber = 1;\r
+       startNumberRewind = 0;\r
+\r
+       //create output file\r
+       if (dash_cfg) {\r
+\r
+               /*need to precompute bandwidth*/\r
+               if (!bandwidth && seg_rad_name && strstr(seg_rad_name, "$Bandwidth$")) {\r
+                       for (i=0; i<gf_isom_get_track_count(input); i++) {\r
+                               Double tk_dur = (Double) gf_isom_get_media_duration(input, i+1);\r
+                               tk_dur /= gf_isom_get_media_timescale(input, i+1);\r
+                               if (file_duration < tk_dur ) {\r
+                                       file_duration = tk_dur;\r
+                               }\r
+                       }\r
+                       bandwidth = (u32) (gf_isom_get_file_size(input) / file_duration * 8);\r
+               }\r
+\r
+               if (dash_cfg->dash_ctx) {\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "Setup");\r
+                       if (!opt || stricmp(opt, "yes") ) {\r
+                               store_dash_params=1;\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "ID", dash_input->representationID);\r
+                       }\r
+                       /*we are in time shift enabled mode so segments will get destroyed, set the start number to the current segment \r
+                       and restore presentationTimeOffset (cf below)*/\r
+                       if (!store_dash_params && (dash_cfg->time_shift_depth >= 0)) {\r
+                               opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "NextSegmentIndex");\r
+                               sscanf(opt, "%u", &startNumber);\r
+\r
+                               /*adjust the startNumber according to the timeShiftBuffer depth*/\r
+                               if ((dash_cfg->time_shift_depth>0) && (startNumber>(u32)dash_cfg->time_shift_depth) ) {\r
+                                       startNumberRewind = dash_cfg->time_shift_depth;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               opt = dash_cfg->dash_ctx ? gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "InitializationSegment") : NULL;\r
+               if (opt) {\r
+                       output = gf_isom_open(opt, GF_ISOM_OPEN_CAT_FRAGMENTS, NULL);\r
+                       dash_moov_setup = 1;\r
+               } else {\r
+                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_INITIALIZATION, is_bs_switching, SegmentName, output_file, dash_input->representationID, seg_rad_name, !stricmp(seg_ext, "null") ? NULL : "mp4", 0, bandwidth, 0);\r
+                       output = gf_isom_open(SegmentName, GF_ISOM_OPEN_WRITE, NULL);\r
+               }\r
+               if (!output) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISOBMF DASH] Cannot open %s for writing\n", opt ? opt : SegmentName));\r
+                       e = gf_isom_last_error(NULL);\r
+                       goto err_exit;\r
+               }\r
+\r
+               if (store_dash_params) {\r
+                       const char *name;\r
+\r
+                       if (!gf_cfg_get_key(dash_cfg->dash_ctx, "DASH", "SegmentTemplate"))\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, "DASH", "SegmentTemplate", seg_rad_name);\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "Source", gf_isom_get_filename(input) );\r
+\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "Setup", "yes");\r
+                       name = SegmentName;\r
+                       if (bs_switch_segment) name = gf_isom_get_filename(bs_switch_segment);\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "InitializationSegment", name);\r
+\r
+                       /*store BS flag per rep - it should be stored per adaptation set but we dson't have a key for adaptation sets right now*/\r
+                       if (/*first_in_set && */ is_bs_switching)\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "BitstreamSwitching", "yes");\r
+               } else if (dash_cfg->dash_ctx) {\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "BitstreamSwitching");\r
+                       if (opt && !strcmp(opt, "yes")) {\r
+                               is_bs_switching = 1;\r
+                               bs_switch_segment = output;\r
+                               bs_switching_is_output = 1;\r
+                               bs_switching_segment_name = gf_url_get_resource_name(gf_isom_get_filename(bs_switch_segment));\r
+                       }\r
+\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "Bandwidth");\r
+                       if (opt) sscanf(opt, "%u", &bandwidth);\r
+               }\r
+               mpd_segs = gf_temp_file_new();\r
+       } else {\r
+               output = gf_isom_open(output_file, GF_ISOM_OPEN_WRITE, NULL);\r
+               if (!output) return gf_isom_last_error(NULL);\r
+       }\r
+       \r
+       nb_sync = 0;\r
+       nb_samp = 0;\r
+       fragmenters = gf_list_new();\r
+\r
+       if (! dash_moov_setup) {\r
+               e = gf_isom_clone_movie(input, output, 0, 0);\r
+               if (e) goto err_exit;\r
+\r
+               /*because of movie fragments MOOF based offset, ISOM <4 is forbidden*/\r
+               gf_isom_set_brand_info(output, GF_4CC('i','s','o','5'), 1);\r
+               gf_isom_modify_alternate_brand(output, GF_4CC('i','s','o','m'), 0);\r
+               gf_isom_modify_alternate_brand(output, GF_4CC('i','s','o','1'), 0);\r
+               gf_isom_modify_alternate_brand(output, GF_4CC('i','s','o','2'), 0);\r
+               gf_isom_modify_alternate_brand(output, GF_4CC('i','s','o','3'), 0);\r
+               gf_isom_modify_alternate_brand(output, GF_ISOM_BRAND_MP41, 0);\r
+               gf_isom_modify_alternate_brand(output, GF_ISOM_BRAND_MP42, 0);\r
+       }\r
+\r
+       MaxFragmentDuration = (u32) (max_duration_sec * 1000);  \r
+       MaxSegmentDuration = (u32) (1000 * (dash_cfg ? dash_cfg->segment_duration : max_duration_sec));\r
+\r
+       if (dash_cfg) {\r
+               /*in single segment mode, only one big SIDX is written between the end of the moov and the first fragment. \r
+               To speed-up writing, we do a first fragmentation pass without writing any sample to compute the number of segments and fragments per segment\r
+               in order to allocate / write to file the sidx before the fragmentation. The sidx will then be rewritten when closing the last segment*/\r
+               if (dash_cfg->single_file_mode==1) {\r
+                       simulation_pass = 1;\r
+                       seg_rad_name = NULL;\r
+               }\r
+               /*if single file is requested, store all segments in the same file*/\r
+               else if (dash_cfg->single_file_mode==2) {\r
+                       seg_rad_name = NULL;\r
+               }\r
+       }\r
+       index_start_range = index_end_range = 0;        \r
+\r
+       tfref = NULL;\r
+       file_duration = 0;\r
+       width = height = sample_rate = nb_channels = sar_w = sar_h = fps_num = fps_denum = 0;\r
+       langCode[0]=0;\r
+       langCode[4]=0;\r
+       szCodecs[0] = 0;\r
+\r
+       nb_video = nb_audio = nb_text = nb_scene = 0;\r
+       //duplicates all tracks\r
+       for (i=0; i<gf_isom_get_track_count(input); i++) {\r
+               u32 _w, _h, _sr, _nb_ch;\r
+\r
+               u32 mtype = gf_isom_get_media_type(input, i+1);\r
+               if (mtype == GF_ISOM_MEDIA_HINT) continue;\r
+\r
+               if (! dash_moov_setup) {\r
+                       e = gf_isom_clone_track(input, i+1, output, 0, &TrackNum);\r
+                       if (e) goto err_exit;\r
+\r
+                       if (gf_isom_is_track_in_root_od(input, i+1)) gf_isom_add_track_to_root_od(output, TrackNum);\r
+\r
+                       //if only one sample, don't fragment track\r
+                       count = gf_isom_get_sample_count(input, i+1);\r
+                       if (count==1) {\r
+                               sample = gf_isom_get_sample(input, i+1, 1, &descIndex);\r
+                               e = gf_isom_add_sample(output, TrackNum, 1, sample);\r
+                               gf_isom_sample_del(&sample);\r
+                               if (e) goto err_exit;\r
+\r
+                               continue;\r
+                       }\r
+               } else {\r
+                       TrackNum = gf_isom_get_track_by_id(output, gf_isom_get_track_id(input, i+1));\r
+                       count = gf_isom_get_sample_count(input, i+1);\r
+               }\r
+\r
+               if (mtype == GF_ISOM_MEDIA_VISUAL) nb_video++;\r
+               else if (mtype == GF_ISOM_MEDIA_AUDIO) nb_audio++;\r
+               else if (mtype == GF_ISOM_MEDIA_TEXT) nb_text++;\r
+               else if (mtype == GF_ISOM_MEDIA_SCENE) nb_scene++;\r
+               else if (mtype == GF_ISOM_MEDIA_DIMS) nb_scene++;\r
+\r
+               if (mtype != GF_ISOM_MEDIA_AUDIO) audio_only = 0;\r
+\r
+               //setup fragmenters\r
+               if (! dash_moov_setup) {\r
+                       gf_isom_get_fragment_defaults(input, i+1,\r
+                                                                        &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority);\r
+\r
+                       //new initialization segment, setup fragmentation\r
+                       e = gf_isom_setup_track_fragment(output, gf_isom_get_track_id(output, TrackNum),\r
+                                               defaultDescriptionIndex, defaultDuration,\r
+                                               defaultSize, (u8) defaultRandomAccess,\r
+                                               defaultPadding, defaultDegradationPriority);\r
+                       if (e) goto err_exit;\r
+               } else {\r
+                       gf_isom_get_fragment_defaults(output, TrackNum,\r
+                                                                        &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority);\r
+               }\r
+\r
+               gf_media_get_rfc_6381_codec_name(output, TrackNum, szCodec);\r
+               if (strlen(szCodecs)) strcat(szCodecs, ",");\r
+               strcat(szCodecs, szCodec);\r
+\r
+               GF_SAFEALLOC(tf, GF_ISOMTrackFragmenter);\r
+               tf->TrackID = gf_isom_get_track_id(output, TrackNum);\r
+               tf->SampleCount = gf_isom_get_sample_count(input, i+1);\r
+               tf->OriginalTrack = i+1;\r
+               tf->TimeScale = gf_isom_get_media_timescale(input, i+1);\r
+               tf->MediaType = gf_isom_get_media_type(input, i+1);\r
+               tf->DefaultDuration = defaultDuration;\r
+\r
+               if (max_track_duration < gf_isom_get_track_duration(input, i+1)) {\r
+                       max_track_duration = (Double) gf_isom_get_track_duration(input, i+1);\r
+               }\r
+\r
+               if (gf_isom_get_sync_point_count(input, i+1)>nb_sync) { \r
+                       tfref = tf;\r
+                       nb_sync = gf_isom_get_sync_point_count(input, i+1);\r
+               } else if (!gf_isom_has_sync_points(input, i+1)) {\r
+                       tf->all_sample_raps = 1;\r
+               }\r
+\r
+               tf->finalSampleDescriptionIndex = 1;\r
+\r
+               /*figure out if we have an initial TS*/\r
+               if (!dash_moov_setup) {\r
+                       if (gf_isom_get_edit_segment_count(input, i+1)) {\r
+                               u64 EditTime, SegDuration, MediaTime;\r
+                               u8 EditMode;\r
+                               gf_isom_get_edit_segment(input, i+1, 1, &EditTime, &SegDuration, &MediaTime, &EditMode);\r
+                               if (EditMode==GF_ISOM_EDIT_EMPTY) {\r
+                                       tf->InitialTSOffset = (u32) (SegDuration * tf->TimeScale / gf_isom_get_timescale(input));\r
+                               }\r
+                               /*and remove edit segments*/\r
+                               gf_isom_remove_edit_segments(output, TrackNum);\r
+                       }\r
+\r
+                       gf_isom_set_brand_info(output, GF_4CC('i','s','o','5'), 1);\r
+                       gf_isom_modify_alternate_brand(output, GF_4CC('d','a','s','h'), 1);\r
+\r
+                       /*locate sample description in list if given*/\r
+                       if (bs_switch_segment) {\r
+                               u32 s_count;\r
+                               u32 sample_descs_track = gf_isom_get_track_by_id(bs_switch_segment, tf->TrackID);\r
+                               if (!sample_descs_track) {\r
+                                       e = GF_BAD_PARAM;\r
+                                       goto err_exit;\r
+\r
+                               }\r
+\r
+                               //the initialization segment is not yet setup for fragmentation\r
+                               if (! gf_isom_is_track_fragmented(bs_switch_segment, tf->TrackID)) {\r
+                                       e = GF_BAD_PARAM;\r
+                                       if (e) goto err_exit;\r
+                               }\r
+                               /*otherwise override the fragment defauls so that we are consistent with the shared init segment*/\r
+                               else {\r
+                                       e = gf_isom_get_fragment_defaults(bs_switch_segment, sample_descs_track,\r
+                                                                                        &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority);\r
+                                       if (e) goto err_exit;\r
+\r
+                                       e = gf_isom_change_track_fragment_defaults(output, tf->TrackID,\r
+                                                                                        defaultDescriptionIndex, defaultDuration, defaultSize, defaultRandomAccess, defaultPadding, defaultDegradationPriority);\r
+                                       if (e) goto err_exit;\r
+                               }\r
+\r
+                               /*and search in new ones the new index*/\r
+                               s_count = gf_isom_get_sample_description_count(bs_switch_segment, sample_descs_track); \r
+\r
+                               /*more than one sampleDesc, we will need to indicate all the sample descs in the file in case we produce a single file, \r
+                               otherwise the file would not be compliant*/\r
+                               if (s_count > 1) {\r
+                                       gf_isom_clone_sample_descriptions(output, TrackNum, bs_switch_segment, sample_descs_track, 1);\r
+                               }\r
+\r
+                               /*and search in new ones the new index*/\r
+                               s_count = gf_isom_get_sample_description_count(bs_switch_segment, sample_descs_track); \r
+                               if (s_count>1) {\r
+                                       u32 k;\r
+                                       /*remove all sample descs*/\r
+                                       for (k=0; k<s_count; k++) {\r
+                                               /*search in original file if we have the sample desc*/\r
+                                               if (gf_isom_is_same_sample_description(input, TrackNum, 1, bs_switch_segment, sample_descs_track, k+1)) {\r
+                                                       tf->finalSampleDescriptionIndex = k+1;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               /*restore track decode times*/\r
+               else {\r
+                       char *opt, sKey[100];\r
+                       sprintf(sKey, "TKID_%d_NextDecodingTime", tf->TrackID);\r
+                       opt = (char *)gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, sKey);\r
+                       if (opt) tf->InitialTSOffset = atoi(opt);\r
+\r
+                       /*in time shift enabled, restore presentationTimeOffset */\r
+                       if (dash_cfg->time_shift_depth>=0)\r
+                               presentationTimeOffset = tf->InitialTSOffset;\r
+               }\r
+\r
+               /*get language, width/height/layout info, audio info*/\r
+               switch (mtype) {\r
+               case GF_ISOM_MEDIA_TEXT:\r
+                       tf->splitable = 1;\r
+                       gf_isom_get_media_language(input, i+1, langCode);\r
+               case GF_ISOM_MEDIA_VISUAL:\r
+               case GF_ISOM_MEDIA_SCENE:\r
+               case GF_ISOM_MEDIA_DIMS:\r
+                       gf_isom_get_track_layout_info(input, i+1, &_w, &_h, NULL, NULL, NULL);\r
+                       if (_w>width) width = _w;\r
+                       if (_h>height) height = _h;\r
+                       break;\r
+               case GF_ISOM_MEDIA_AUDIO:\r
+                       gf_isom_get_audio_info(input, i+1, 1, &_sr, &_nb_ch, NULL);\r
+                       if (_sr>sample_rate) sample_rate=_sr;\r
+                       if (_nb_ch>nb_channels) nb_channels = _nb_ch;\r
+                       gf_isom_get_media_language(input, i+1, langCode);\r
+                       break;\r
+               }\r
+\r
+               if (mtype==GF_ISOM_MEDIA_VISUAL) {\r
+                       /*get duration of 2nd sample*/\r
+                       u32 sample_dur = gf_isom_get_sample_duration(input, i+1, 2);\r
+                       gf_isom_get_pixel_aspect_ratio(input, i+1, 1, &sar_w, &sar_h);\r
+                       if (! fps_num || ! fps_denum) {\r
+                               fps_num = tf->TimeScale;\r
+                               fps_denum = sample_dur;\r
+                       }\r
+                       else if (fps_num *sample_dur < tf->TimeScale * fps_denum) {\r
+                               fps_num = tf->TimeScale;\r
+                               fps_denum = sample_dur;\r
+                       }\r
+               }\r
+\r
+\r
+               if (file_duration < ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale ) {\r
+                       file_duration = ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale;\r
+               }\r
+               gf_list_add(fragmenters, tf);\r
+\r
+               nb_samp += count;\r
+       }\r
+\r
+\r
+       if (!tfref) tfref = gf_list_get(fragmenters, 0);\r
+       tfref->is_ref_track = 1;\r
+       tfref_timescale = tfref->TimeScale;\r
+       ref_track_id = tfref->TrackID;\r
+       if (tfref->all_sample_raps) split_seg_at_rap = 1;\r
+\r
+\r
+       if (!dash_moov_setup) {\r
+               max_track_duration /= gf_isom_get_timescale(input);\r
+               max_track_duration *= gf_isom_get_timescale(output);\r
+               gf_isom_set_movie_duration(output, (u64) max_track_duration);\r
+       }\r
+\r
+       //if single segment, add msix brand if we use indexes\r
+       gf_isom_modify_alternate_brand(output, GF_4CC('m','s','i','x'), (dash_cfg && (dash_cfg->single_file_mode==1) && (dash_cfg->subsegs_per_sidx>=0)) ? 1 : 0);\r
+\r
+       //flush movie\r
+       e = gf_isom_finalize_for_fragment(output, dash_cfg ? 1 : 0);\r
+       if (e) goto err_exit;\r
+\r
+       start_range = 0;\r
+       file_size = gf_isom_get_file_size(bs_switch_segment ? bs_switch_segment : output);\r
+       end_range = file_size - 1;\r
+       init_seg_size = file_size;\r
+\r
+       if (dash_cfg->dash_ctx) {\r
+               if (store_dash_params) {\r
+                       char szVal[1024];\r
+                       sprintf(szVal, LLU, init_seg_size);\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "InitializationSegmentSize", szVal);\r
+               } else {\r
+                       const char *opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "InitializationSegmentSize");\r
+                       if (opt) init_seg_size = atoi(opt);\r
+               }\r
+       }\r
+\r
+restart_fragmentation_pass:\r
+\r
+       for (i=0; i<gf_list_count(fragmenters); i++) {\r
+               tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, i);\r
+               tf->split_sample_dts_shift = 0;\r
+       }\r
+       segment_start_time = 0;\r
+       nb_segments = 0;\r
+\r
+       nb_tracks_done = 0;\r
+       ref_track_first_dts = (u64) -1;\r
+       nb_done = 0;\r
+\r
+       maxFragDurationOverSegment=0;\r
+       if (dash_cfg) switch_segment=1;\r
+\r
+       if (!seg_rad_name) use_url_template = 0;\r
+\r
+       cur_seg=1;\r
+       fragment_index=1;\r
+       period_duration = 0;\r
+       split_at_rap = 0;\r
+       has_rap = 0;\r
+       next_sample_rap = 0;\r
+       flush_all_samples = 0;\r
+       force_switch_segment = 0;\r
+       max_sap_type = 0;\r
+       ref_track_next_cts = 0;\r
+\r
+       /*setup previous URL list*/\r
+       if (dash_cfg->dash_ctx) {\r
+               const char *opt;\r
+               char sKey[100];\r
+               count = gf_cfg_get_key_count(dash_cfg->dash_ctx, RepURLsSecName);\r
+               for (i=0; i<count; i++) {\r
+                       const char *key_name = gf_cfg_get_key_name(dash_cfg->dash_ctx, RepURLsSecName, i);\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepURLsSecName, key_name);\r
+                       fprintf(mpd_segs, "     %s\n", opt);    \r
+               }\r
+\r
+               opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "NextSegmentIndex");\r
+               if (opt) cur_seg = atoi(opt);\r
+               opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "NextFragmentIndex");\r
+               if (opt) fragment_index = atoi(opt);\r
+               opt = gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, "CumulatedDuration");\r
+               if (opt) period_duration = atof(opt);\r
+\r
+               sprintf(sKey, "TKID_%d_NextSampleNum", tf->TrackID);\r
+               opt = (char *)gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, sKey);\r
+               if (opt) tf->SampleNum = atoi(opt);\r
+\r
+               sprintf(sKey, "TKID_%d_LastSampleCTS", tf->TrackID);\r
+               opt = (char *)gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, sKey);\r
+               if (opt) sscanf(opt, LLU, &tf->last_sample_cts);\r
+\r
+               sprintf(sKey, "TKID_%d_NextSampleDTS", tf->TrackID);\r
+               opt = (char *)gf_cfg_get_key(dash_cfg->dash_ctx, RepSecName, sKey);\r
+               if (opt) {\r
+                       sscanf(opt, LLU, &tf->next_sample_dts);\r
+               }\r
+       }\r
+       gf_isom_set_next_moof_number(output, fragment_index);\r
+\r
+\r
+       max_segment_duration = 0;\r
+\r
+       while ( (count = gf_list_count(fragmenters)) ) {\r
+\r
+               if (switch_segment) {\r
+                       SegmentDuration = 0;\r
+                       switch_segment = 0;\r
+                       first_sample_in_segment = 1;\r
+\r
+                       if (dash_cfg && dash_cfg->subduration && (segment_start_time>=1000*dash_cfg->subduration)) {\r
+                               /*done with file (exceeded the requested duration) : store all fragmenters state and abord*/\r
+                               break;\r
+                       }\r
+\r
+                       if (simulation_pass) {\r
+                               segments_info = gf_realloc(segments_info, sizeof(u32) * (nb_segments_info+1) );\r
+                               segments_info[nb_segments_info] = 0;\r
+                               nb_segments_info++;\r
+                               e = GF_OK;\r
+                       } else {\r
+                               start_range = gf_isom_get_file_size(output);\r
+                               if (seg_rad_name) {\r
+                                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_SEGMENT, is_bs_switching, SegmentName, output_file, dash_input->representationID, seg_rad_name, !stricmp(seg_ext, "null") ? NULL : seg_ext, (u64) ( period_duration * timeline_timescale + segment_start_time), bandwidth, cur_seg);\r
+                                       e = gf_isom_start_segment(output, SegmentName);\r
+\r
+                                       gf_dasher_store_segment_info(dash_cfg, SegmentName, period_duration + segment_start_time / 1000.0);\r
+\r
+                                       /*we are in bitstream switching mode, delete init segment*/\r
+                                       if (is_bs_switching && !init_segment_deleted) {\r
+                                               init_segment_deleted = 1;\r
+                                               gf_delete_file(gf_isom_get_filename(output));\r
+                                       }\r
+\r
+                                       if (!use_url_template) {\r
+                                               const char *name = gf_url_get_resource_name(SegmentName);\r
+                                               fprintf(mpd_segs, "     <SegmentURL media=\"%s\"/>\n", name );  \r
+                                               if (dash_cfg->dash_ctx) {\r
+                                                       char szKey[100], szVal[4046];\r
+                                                       sprintf(szKey, "UrlInfo%d", cur_seg );\r
+                                                       sprintf(szVal, "<SegmentURL media=\"%s\"/>", name);\r
+                                                       gf_cfg_set_key(dash_cfg->dash_ctx, RepURLsSecName, szKey, szVal);\r
+                                               }\r
+                                       }\r
+                               } else {\r
+                                       e = gf_isom_start_segment(output, NULL);\r
+                               }\r
+                       }\r
+\r
+                       cur_seg++;\r
+                       if (e) goto err_exit;\r
+               } \r
+\r
+               maxFragDurationOverSegment=0;\r
+\r
+               sample = NULL;\r
+\r
+               if (simulation_pass) {\r
+                       segments_info[nb_segments_info-1] ++;\r
+                       e = GF_OK;\r
+               } else {\r
+                       e = gf_isom_start_fragment(output, 1);\r
+                       if (e) goto err_exit;\r
+       \r
+\r
+                       for (i=0; i<count; i++) {\r
+                               tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, i);\r
+                               if (tf->done) continue;\r
+                               /*FIXME - we need a way in the spec to specify "past" DTS for splitted sample*/\r
+                               gf_isom_set_traf_base_media_decode_time(output, tf->TrackID, tf->InitialTSOffset + tf->next_sample_dts);\r
+                       }\r
+               \r
+               }\r
+\r
+               //process track by track\r
+               for (i=0; i<count; i++) {\r
+                       Bool has_roll, is_rap;\r
+                       s32 roll_distance;\r
+                       u32 SAP_type = 0;\r
+                       /*start with ref*/\r
+                       if (tfref && split_seg_at_rap ) {\r
+                               if (i==0) {\r
+                                       tf = tfref;\r
+                                       has_rap=0;\r
+                               } else {\r
+                                       tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, i-1);\r
+                                       if (tf == tfref) {\r
+                                               tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, i);\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, i);\r
+                               if (tf == tfref) \r
+                                       has_rap=0;\r
+                       } \r
+                       if (tf->done) continue;\r
+\r
+                       //ok write samples\r
+                       while (1) {\r
+                               Bool stop_frag = 0;\r
+                               Bool is_redundant_sample = 0;\r
+                               u32 split_sample_duration = 0;\r
+\r
+                               /*first sample*/\r
+                               if (!sample) {\r
+                                       sample = gf_isom_get_sample(input, tf->OriginalTrack, tf->SampleNum + 1, &descIndex);\r
+                                       if (!sample) {\r
+                                               e = gf_isom_last_error(input);\r
+                                               goto err_exit;\r
+                                       }\r
+                                       if (tf->split_sample_dts_shift) {\r
+                                               sample->DTS += tf->split_sample_dts_shift;\r
+                                               is_redundant_sample = 1;\r
+                                       }\r
+\r
+                                       /*also get SAP type - this is not needed if sample is not NULL as SAP tye was computed for "next sample" in previous loop*/\r
+                                       if (sample->IsRAP) {\r
+                                               SAP_type = 1;\r
+                                       } else {\r
+                                               SAP_type = 0;\r
+                                               e = gf_isom_get_sample_rap_roll_info(input, tf->OriginalTrack, tf->SampleNum + 1, &is_rap, &has_roll, &roll_distance);\r
+                                               if (e==GF_OK) {\r
+                                                       if (is_rap) SAP_type = 3;\r
+                                                       else if (has_roll && (roll_distance>=0) ) SAP_type = 4;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               gf_isom_get_sample_padding_bits(input, tf->OriginalTrack, tf->SampleNum+1, &NbBits);\r
+\r
+                               next = gf_isom_get_sample(input, tf->OriginalTrack, tf->SampleNum + 2, &j);\r
+                               if (next) {\r
+                                       defaultDuration = (u32) (next->DTS - sample->DTS);\r
+                               } else {\r
+                                       defaultDuration = tf->DefaultDuration;\r
+                               }\r
+\r
+                               if (tf->splitable) {\r
+                                       if (tfref==tf) {\r
+                                               u32 frag_dur = (tf->FragmentLength + defaultDuration) * 1000 / tf->TimeScale;\r
+                                               /*if media segment about to be produced is longer than max segment length, force segment split*/\r
+                                               if (SegmentDuration + frag_dur > MaxSegmentDuration) {\r
+                                                       split_sample_duration = defaultDuration;\r
+                                                       defaultDuration = tf->TimeScale * (MaxSegmentDuration - SegmentDuration) / 1000 - tf->FragmentLength;\r
+                                                       split_sample_duration -= defaultDuration;\r
+                                               }\r
+                                       } else if ((tf->last_sample_cts + defaultDuration) * tfref_timescale > tfref->next_sample_dts * tf->TimeScale) {\r
+                                               split_sample_duration = defaultDuration;\r
+                                               defaultDuration = (u32) ( (last_ref_cts * tf->TimeScale)/tfref_timescale - tf->last_sample_cts );\r
+                                               split_sample_duration -= defaultDuration;\r
+                                       }\r
+                               }\r
+\r
+                               if (tf==tfref) {\r
+                                       if (segments_start_with_sap && first_sample_in_segment ) {\r
+                                               first_sample_in_segment = 0;\r
+                                               if (! SAP_type) segments_start_with_sap = 0;\r
+                                       }\r
+                                       if (ref_track_first_dts > sample->DTS) \r
+                                               ref_track_first_dts = sample->DTS;\r
+\r
+                                       if (next) {\r
+                                               u64 next_cts = next->DTS + next->CTS_Offset;\r
+                                               if (split_sample_duration) \r
+                                                       next_cts -= split_sample_duration;\r
+\r
+                                               if (ref_track_next_cts<next_cts) {\r
+                                                       ref_track_next_cts = next_cts;\r
+                                               }\r
+                                       } else {\r
+                                               u64 cts = gf_isom_get_media_duration(input, tf->OriginalTrack);\r
+                                               if (cts>ref_track_next_cts) ref_track_next_cts = cts;\r
+                                               else ref_track_next_cts += defaultDuration;\r
+                                       }\r
+                               }\r
+\r
+                               if (SAP_type > max_sap_type) max_sap_type = SAP_type;\r
+\r
+                               if (simulation_pass) {\r
+                                       e = GF_OK;\r
+                               } else {\r
+                                       /*override descIndex with final index used in file*/\r
+                                       descIndex = tf->finalSampleDescriptionIndex;\r
+                                       e = gf_isom_fragment_add_sample(output, tf->TrackID, sample, descIndex,\r
+                                                                        defaultDuration, NbBits, 0, is_redundant_sample);\r
+                                       if (e) \r
+                                               goto err_exit;\r
+\r
+                                       /*copy subsample information*/\r
+                                       e = gf_isom_fragment_copy_subsample(output, tf->TrackID, input, tf->OriginalTrack, tf->SampleNum + 1);\r
+                                       if (e) \r
+                                               goto err_exit;\r
+\r
+                                       gf_set_progress("ISO File Fragmenting", nb_done, nb_samp);\r
+                                       nb_done++;\r
+                               }\r
+\r
+                               tf->last_sample_cts = sample->DTS + sample->CTS_Offset;\r
+                               tf->next_sample_dts = sample->DTS + defaultDuration;\r
+\r
+                               if (split_sample_duration) {\r
+                                       gf_isom_sample_del(&next);\r
+                                       sample->DTS += defaultDuration;\r
+                               } else {\r
+                                       gf_isom_sample_del(&sample);\r
+                                       sample = next;\r
+                                       tf->SampleNum += 1;\r
+                                       tf->split_sample_dts_shift = 0;\r
+                               }\r
+                               tf->FragmentLength += defaultDuration;\r
+\r
+                               /*compute SAP type*/\r
+                               if (sample) {\r
+                                       if (sample->IsRAP) {\r
+                                               SAP_type = 1;\r
+                                       } else {\r
+                                               SAP_type = 0;\r
+                                               e = gf_isom_get_sample_rap_roll_info(input, tf->OriginalTrack, tf->SampleNum + 1, &is_rap, &has_roll, NULL);\r
+                                               if (e==GF_OK) {\r
+                                                       if (is_rap)\r
+                                                               SAP_type = 3;\r
+                                                       else if (has_roll && (roll_distance>=0) )\r
+                                                               SAP_type = 4;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               if (next && SAP_type) {\r
+                                       if (tf==tfref) {\r
+                                               if (split_sample_duration) {\r
+                                                       stop_frag = 1;\r
+                                               }\r
+                                               else if (split_seg_at_rap) {\r
+                                                       u64 next_sap_time;\r
+                                                       u32 frag_dur, next_dur;\r
+                                                       next_dur = gf_isom_get_sample_duration(input, tf->OriginalTrack, tf->SampleNum + 1);\r
+                                                       if (!next_dur) next_dur = defaultDuration;\r
+                                                       /*duration of fragment if we add this rap*/\r
+                                                       frag_dur = (tf->FragmentLength+next_dur)*1000/tf->TimeScale;\r
+                                                       next_sample_rap = 1;\r
+                                                       next_sap_time = isom_get_next_sap_time(input, tf->OriginalTrack, tf->SampleCount, tf->SampleNum + 2);\r
+                                                       /*if no more SAP after this one, do not switch segment*/\r
+                                                       if (next_sap_time) {\r
+                                                               u32 scaler;\r
+                                                               /*this is the fragment duration from last sample added to next SAP*/\r
+                                                               frag_dur += (u32) (next_sap_time - tf->next_sample_dts - next_dur)*1000/tf->TimeScale;\r
+                                                               /*if media segment about to be produced is longer than max segment length, force segment split*/\r
+                                                               if (SegmentDuration + frag_dur > MaxSegmentDuration) {\r
+                                                                       split_at_rap = 1;\r
+                                                                       /*force new segment*/\r
+                                                                       force_switch_segment = 1;\r
+                                                               }\r
+\r
+                                                               if (tf->all_sample_raps) {\r
+                                                                       /*if adding this SAP will result in stoping the fragment "soon" after it, stop now and start with SAP\r
+                                                                       if all samples are RAPs, just stop fragment if we exceed the requested duration by adding the next sample\r
+                                                                       otherwise, take 3 samples (should be refined of course)*/\r
+                                                                       scaler = 3;\r
+                                                                       if ( (tf->FragmentLength + scaler * next_dur)*1000 >= MaxFragmentDuration * tf->TimeScale)\r
+                                                                               stop_frag = 1;\r
+                                                               }\r
+                                                       }\r
+                                               } else if (!has_rap) {\r
+                                                       if (tf->FragmentLength == defaultDuration) has_rap = 2;\r
+                                                       else has_rap = 1;\r
+                                               }\r
+                                       } \r
+                               } else {\r
+                                       next_sample_rap = 0;\r
+                               }\r
+\r
+                               if (tf->SampleNum==tf->SampleCount) {\r
+                                       stop_frag = 1;\r
+                               } else if (tf==tfref) {\r
+                                       /*fragmenting on "clock" track: no drift control*/\r
+                                       if (!(dash_cfg ? dash_cfg->fragments_start_with_rap : 0) || ( (next && next->IsRAP) || split_at_rap) ) {\r
+                                               if (tf->FragmentLength*1000 >= MaxFragmentDuration*tf->TimeScale) {\r
+                                                       stop_frag = 1;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               /*do not abort fragment if ref track is done, put everything in the last fragment*/\r
+                               else if (!flush_all_samples) {\r
+                                       /*fragmenting on "non-clock" track: drift control*/\r
+                                       if (tf->last_sample_cts * tfref_timescale >= last_ref_cts * tf->TimeScale)\r
+                                               stop_frag = 1;\r
+                               }\r
+\r
+                               if (stop_frag) {\r
+                                       gf_isom_sample_del(&sample);\r
+                                       sample = next = NULL;\r
+                                       if (maxFragDurationOverSegment<=tf->FragmentLength*1000/tf->TimeScale) {\r
+                                               maxFragDurationOverSegment = tf->FragmentLength*1000/tf->TimeScale;\r
+                                       }\r
+                                       tf->FragmentLength = 0;\r
+                                       if (split_sample_duration)\r
+                                               tf->split_sample_dts_shift += defaultDuration;\r
+\r
+                                       if (tf==tfref) last_ref_cts = tf->last_sample_cts;\r
+\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       if (tf->SampleNum==tf->SampleCount) {\r
+                               tf->done = 1;\r
+                               nb_tracks_done++;\r
+                               if (tf == tfref) {\r
+                                       tfref = NULL;\r
+                                       flush_all_samples = 1;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if (dash_cfg) {\r
+\r
+                       SegmentDuration += maxFragDurationOverSegment;\r
+                       maxFragDurationOverSegment=0;\r
+\r
+                       /*next fragment will exceed segment length, abort fragment now (all samples RAPs)*/\r
+                       if (tfref && tfref->all_sample_raps && (SegmentDuration + MaxFragmentDuration >= MaxSegmentDuration)) {\r
+                               force_switch_segment = 1;\r
+                       }\r
+\r
+                       if (force_switch_segment || ((SegmentDuration >= MaxSegmentDuration) && (!split_seg_at_rap || next_sample_rap))) {\r
+                               segment_start_time += SegmentDuration;\r
+                               nb_segments++;\r
+                               if (max_segment_duration * 1000 <= SegmentDuration) {\r
+                                       max_segment_duration = SegmentDuration;\r
+                                       max_segment_duration /= 1000;\r
+                               }\r
+                               force_switch_segment=0;\r
+                               switch_segment=1;\r
+                               SegmentDuration=0;\r
+                               split_at_rap = 0;\r
+                               has_rap = 0;\r
+                               /*restore fragment duration*/\r
+                               MaxFragmentDuration = (u32) (max_duration_sec * 1000);\r
+\r
+                               if (!simulation_pass) {\r
+                                       u64 idx_start_range, idx_end_range;\r
+                                       \r
+                                       gf_isom_close_segment(output, dash_cfg->subsegs_per_sidx, ref_track_id, ref_track_first_dts, ref_track_next_cts, dash_cfg->daisy_chain_sidx, flush_all_samples ? 1 : 0, &idx_start_range, &idx_end_range);\r
+                                       ref_track_first_dts = (u64) -1;\r
+\r
+                                       if (!seg_rad_name) {\r
+                                               file_size = gf_isom_get_file_size(output);\r
+                                               end_range = file_size - 1;\r
+                                               if (dash_cfg->single_file_mode!=1) {\r
+                                                       fprintf(mpd_segs, "      <SegmentURL mediaRange=\""LLD"-"LLD"\"", start_range, end_range);      \r
+                                                       if (idx_start_range || idx_end_range) {\r
+                                                               fprintf(mpd_segs, " indexRange=\""LLD"-"LLD"\"", idx_start_range, idx_end_range);       \r
+                                                       }\r
+                                                       fprintf(mpd_segs, "/>\n");      \r
+                                                       if (dash_cfg->dash_ctx) {\r
+                                                               char szKey[100], szVal[4046];\r
+                                                               sprintf(szKey, "UrlInfo%d", cur_seg );\r
+                                                               sprintf(szVal, "<SegmentURL mediaRange=\""LLD"-"LLD"\" indexRange=\""LLD"-"LLD"\"/>", start_range, end_range, idx_start_range, idx_end_range);\r
+                                                               gf_cfg_set_key(dash_cfg->dash_ctx, RepURLsSecName, szKey, szVal);\r
+                                                       }\r
+                                               }\r
+                                       } else {\r
+                                               file_size += gf_isom_get_file_size(output);\r
+                                       }\r
+                               }\r
+                       } \r
+                       /*next fragment will exceed segment length, abort fragment at next rap (possibly after MaxSegmentDuration)*/\r
+                       if (split_seg_at_rap && SegmentDuration && (SegmentDuration + MaxFragmentDuration >= MaxSegmentDuration)) {\r
+                               if (!split_at_rap) {\r
+                                       split_at_rap = 1;\r
+                                       MaxFragmentDuration = MaxSegmentDuration - SegmentDuration;\r
+                               }\r
+                       }\r
+               }\r
+               if (nb_tracks_done==count) break;\r
+       }\r
+\r
+       if (simulation_pass) {\r
+               /*OK, we have all segments and frags per segments*/\r
+               gf_isom_allocate_sidx(output, dash_cfg->subsegs_per_sidx, dash_cfg->daisy_chain_sidx, nb_segments_info, segments_info, &index_start_range, &index_end_range );\r
+               gf_free(segments_info);\r
+               segments_info = NULL;\r
+               simulation_pass = 0;\r
+               /*reset fragmenters*/\r
+               for (i=0; i<gf_list_count(fragmenters); i++) {\r
+                       tf = gf_list_get(fragmenters, i);\r
+                       tf->done = 0;\r
+                       tf->last_sample_cts = 0;\r
+                       tf->next_sample_dts = 0;\r
+                       tf->FragmentLength = 0;\r
+                       tf->SampleNum = 0;\r
+                       if (tf->is_ref_track) tfref = tf;\r
+               }\r
+               goto restart_fragmentation_pass;\r
+       }\r
+\r
+       if (dash_cfg) {\r
+               char buffer[1000];\r
+\r
+               /*flush last segment*/\r
+               if (!switch_segment) {\r
+                       u64 idx_start_range, idx_end_range;\r
+\r
+                       if (max_segment_duration * 1000 <= SegmentDuration) {\r
+                               max_segment_duration = SegmentDuration;\r
+                               max_segment_duration /= 1000;\r
+                       }\r
+\r
+                       segment_start_time += SegmentDuration;\r
+\r
+                       gf_isom_close_segment(output, dash_cfg->subsegs_per_sidx, ref_track_id, ref_track_first_dts, ref_track_next_cts, dash_cfg->daisy_chain_sidx, 1, &idx_start_range, &idx_end_range);\r
+                       nb_segments++;\r
+\r
+                       if (!seg_rad_name) {\r
+                               file_size = gf_isom_get_file_size(output);\r
+                               end_range = file_size - 1;\r
+                               if (dash_cfg->single_file_mode!=1) {\r
+                                       fprintf(mpd_segs, "     <SegmentURL mediaRange=\""LLD"-"LLD"\"", start_range, end_range);\r
+                                       if (idx_start_range || idx_end_range) {\r
+                                               fprintf(mpd_segs, " indexRange=\""LLD"-"LLD"\"", idx_start_range, idx_end_range);\r
+                                       }\r
+                                       fprintf(mpd_segs, "/>\n");\r
+\r
+                                       if (dash_cfg->dash_ctx) {\r
+                                               char szKey[100], szVal[4046];\r
+                                               sprintf(szKey, "UrlInfo%d", cur_seg );\r
+                                               sprintf(szVal, "<SegmentURL mediaRange=\""LLD"-"LLD"\" indexRange=\""LLD"-"LLD"\"/>", start_range, end_range, idx_start_range, idx_end_range);\r
+                                               gf_cfg_set_key(dash_cfg->dash_ctx, RepURLsSecName, szKey, szVal);\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               file_size += gf_isom_get_file_size(output);\r
+                       }\r
+               }\r
+\r
+               if (!bandwidth)\r
+                       bandwidth = (u32) (file_size * 8 / file_duration);\r
+\r
+               if (use_url_template) {\r
+                       /*segment template does not depend on file name, write the template at the adaptationSet level*/\r
+                       if (!dash_cfg->variable_seg_rad_name && first_in_set) {\r
+                               const char *rad_name = gf_url_get_resource_name(seg_rad_name);\r
+                               gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_TEMPLATE, is_bs_switching, SegmentName, output_file, dash_input->representationID, rad_name, !stricmp(seg_ext, "null") ? NULL : seg_ext, 0, 0, 0);\r
+                               fprintf(dash_cfg->mpd, "   <SegmentTemplate timescale=\"1000\" duration=\"%d\" media=\"%s\" startNumber=\"%d\"", (u32) (max_segment_duration*1000), SegmentName, startNumber - startNumberRewind);      \r
+                               /*in BS switching we share the same IS for all reps*/\r
+                               if (is_bs_switching) {\r
+                                       strcpy(SegmentName, bs_switching_segment_name);\r
+                               } else {\r
+                                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_INITIALIZATION_TEMPLATE, is_bs_switching, SegmentName, output_file, dash_input->representationID, rad_name, !stricmp(seg_ext, "null") ? NULL : "mp4", 0, 0, 0);\r
+                               }\r
+                               fprintf(dash_cfg->mpd, " initialization=\"%s\"", SegmentName);\r
+                               if (presentationTimeOffset) \r
+                                       fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", presentationTimeOffset);\r
+                               fprintf(dash_cfg->mpd, "/>\n");\r
+                       }\r
+                       /*in BS switching we share the same IS for all reps, write the SegmentTemplate for the init segment*/\r
+                       else if (is_bs_switching && first_in_set) {\r
+                               fprintf(dash_cfg->mpd, "   <SegmentTemplate initialization=\"%s\"", bs_switching_segment_name);\r
+                               if (presentationTimeOffset) \r
+                                       fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", presentationTimeOffset);\r
+                               fprintf(dash_cfg->mpd, "/>\n");\r
+                       }\r
+               }\r
+\r
+\r
+               fprintf(dash_cfg->mpd, "   <Representation ");\r
+               if (dash_input->representationID) fprintf(dash_cfg->mpd, "id=\"%s\"", dash_input->representationID);\r
+               else fprintf(dash_cfg->mpd, "id=\"%p\"", output);\r
+               \r
+               fprintf(dash_cfg->mpd, " mimeType=\"%s/mp4\" codecs=\"%s\"", audio_only ? "audio" : "video", szCodecs);\r
+               if (width && height) {\r
+                       fprintf(dash_cfg->mpd, " width=\"%d\" height=\"%d\"", width, height);\r
+                       gf_media_get_reduced_frame_rate(&fps_num, &fps_denum);\r
+                       if (fps_denum>1)\r
+                               fprintf(dash_cfg->mpd, " frameRate=\"%d/%d\"", fps_num, fps_denum);\r
+                       else\r
+                               fprintf(dash_cfg->mpd, " frameRate=\"%d\"", fps_num);\r
+\r
+                       if (!sar_w) sar_w = 1;\r
+                       if (!sar_h) sar_h = 1;\r
+                       fprintf(dash_cfg->mpd, " sar=\"%d:%d\"", sar_w, sar_h);\r
+\r
+               }\r
+               if (sample_rate) fprintf(dash_cfg->mpd, " audioSamplingRate=\"%d\"", sample_rate);\r
+               if (segments_start_with_sap || split_seg_at_rap) {\r
+                       fprintf(dash_cfg->mpd, " startWithSAP=\"%d\"", max_sap_type);\r
+               } else {\r
+                       fprintf(dash_cfg->mpd, " startWithSAP=\"0\"");\r
+               }\r
+               //only appears at AdaptationSet level - need to rewrite the DASH segementer to allow writing this at the proper place\r
+//             if ((single_file_mode==1) && segments_start_with_sap) fprintf(dash_cfg->mpd, " subsegmentStartsWithSAP=\"%d\"", max_sap_type);\r
+               \r
+               fprintf(dash_cfg->mpd, " bandwidth=\"%d\"", bandwidth);         \r
+               fprintf(dash_cfg->mpd, ">\n");\r
+\r
+               if (nb_channels && !is_bs_switching) \r
+                       fprintf(dash_cfg->mpd, "    <AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\"/>\n", nb_channels);\r
+\r
+               if (dash_cfg->dash_ctx) {\r
+                       Double seg_dur;\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, "DASH", "MaxSegmentDuration");\r
+                       if (opt) {\r
+                               seg_dur = atof(opt);\r
+                               if (seg_dur < max_segment_duration) {\r
+                                       sprintf(sOpt, "%f", max_segment_duration);\r
+                                       gf_cfg_set_key(dash_cfg->dash_ctx, "DASH", "MaxSegmentDuration", sOpt);\r
+                                       seg_dur = max_segment_duration;\r
+                               } else {\r
+                                       max_segment_duration = seg_dur;\r
+                               }\r
+                       } else {\r
+                               sprintf(sOpt, "%f", max_segment_duration);\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, "DASH", "MaxSegmentDuration", sOpt);\r
+                       }\r
+               }\r
+\r
+               if (use_url_template) {\r
+                       /*segment template depends on file name, but the template at the representation level*/\r
+                       if (dash_cfg->variable_seg_rad_name) {\r
+                               const char *rad_name = gf_url_get_resource_name(seg_rad_name);\r
+                               gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_TEMPLATE, is_bs_switching, SegmentName, output_file, dash_input->representationID, rad_name, !stricmp(seg_ext, "null") ? NULL : seg_ext, 0, bandwidth, 0);\r
+                               fprintf(dash_cfg->mpd, "    <SegmentTemplate timescale=\"1000\" duration=\"%d\" media=\"%s\" startNumber=\"%d\"", (u32) (max_segment_duration*1000), SegmentName, startNumber - startNumberRewind);     \r
+                               if (!is_bs_switching) {\r
+                                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_INITIALIZATION_TEMPLATE, is_bs_switching, SegmentName, output_file, dash_input->representationID, rad_name, !stricmp(seg_ext, "null") ? NULL : "mp4", 0, 0, 0);\r
+                                       fprintf(dash_cfg->mpd, " initialization=\"%s\"", SegmentName);\r
+                               }\r
+                               if (presentationTimeOffset) \r
+                                       fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", presentationTimeOffset);\r
+                               fprintf(dash_cfg->mpd, "/>\n");\r
+                       }\r
+               } else if (dash_cfg->single_file_mode==1) {\r
+                       fprintf(dash_cfg->mpd, "    <BaseURL>%s</BaseURL>\n", gf_url_get_resource_name( gf_isom_get_filename(output) ) );       \r
+                       fprintf(dash_cfg->mpd, "    <SegmentBase indexRangeExact=\"true\" indexRange=\"%d-%d\"", index_start_range, index_end_range);   \r
+                       if (presentationTimeOffset) \r
+                               fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", presentationTimeOffset);\r
+                       fprintf(dash_cfg->mpd, "/>\n"); \r
+               } else {\r
+                       if (!seg_rad_name) {\r
+                               fprintf(dash_cfg->mpd, "    <BaseURL>%s</BaseURL>\n", gf_url_get_resource_name( gf_isom_get_filename(output) ) );       \r
+                       }\r
+                       fprintf(dash_cfg->mpd, "    <SegmentList timescale=\"1000\" duration=\"%d\"", (u32) (max_segment_duration*1000));       \r
+                       if (presentationTimeOffset) \r
+                               fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", presentationTimeOffset);\r
+                       fprintf(dash_cfg->mpd, ">\n");  \r
+                       /*we are not in bitstreamSwitching mode*/\r
+                       if (!is_bs_switching) {\r
+                               fprintf(dash_cfg->mpd, "     <Initialization"); \r
+                               if (!seg_rad_name) {\r
+                                       fprintf(dash_cfg->mpd, " range=\"0-"LLD"\"", init_seg_size-1);\r
+                               } else {\r
+                                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_INITIALIZATION, is_bs_switching, SegmentName, output_file, dash_input->representationID, gf_url_get_resource_name( seg_rad_name) , !stricmp(seg_ext, "null") ? NULL : "mp4", 0, bandwidth, 0);\r
+                                       fprintf(dash_cfg->mpd, " sourceURL=\"%s\"", SegmentName);\r
+                               }\r
+                               fprintf(dash_cfg->mpd, "/>\n");\r
+                       }\r
+               }\r
+\r
+               gf_f64_seek(mpd_segs, 0, SEEK_SET);\r
+               while (!feof(mpd_segs)) {\r
+                       u32 r = fread(buffer, 1, 100, mpd_segs);\r
+                       gf_fwrite(buffer, 1, r, dash_cfg->mpd);\r
+               }\r
+\r
+               if (!use_url_template && (dash_cfg->single_file_mode!=1)) {\r
+                       fprintf(dash_cfg->mpd, "    </SegmentList>\n");\r
+               }\r
+\r
+               fprintf(dash_cfg->mpd, "   </Representation>\n");\r
+       }\r
+\r
+       /*store context*/\r
+       if (dash_cfg && dash_cfg->dash_ctx) {\r
+               period_duration += (Double)segment_start_time / 1000;\r
+\r
+               for (i=0; i<gf_list_count(fragmenters); i++) {\r
+                       tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, i);\r
+\r
+                       /*InitialTSOffset is used when joining different files - if we are still in the same file , do not update it*/\r
+                       if (tf->done) {\r
+                               sprintf(sKey, "TKID_%d_NextDecodingTime", tf->TrackID);\r
+                               sprintf(sOpt, LLU, tf->InitialTSOffset + tf->next_sample_dts);\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, sKey, sOpt);\r
+                       }\r
+\r
+                       if (dash_cfg->subduration) {\r
+                               sprintf(sKey, "TKID_%d_NextSampleNum", tf->TrackID);\r
+                               sprintf(sOpt, "%d", tf->SampleNum);\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, sKey, tf->done ? NULL : sOpt);\r
+\r
+                               sprintf(sKey, "TKID_%d_LastSampleCTS", tf->TrackID);\r
+                               sprintf(sOpt, LLU, tf->last_sample_cts);\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, sKey, tf->done ? NULL : sOpt);\r
+\r
+                               sprintf(sKey, "TKID_%d_NextSampleDTS", tf->TrackID);\r
+                               sprintf(sOpt, LLU, tf->next_sample_dts);\r
+                               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, sKey, tf->done ? NULL : sOpt);\r
+                       }\r
+               }\r
+               sprintf(sOpt, "%d", cur_seg);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "NextSegmentIndex", sOpt);\r
+\r
+               fragment_index = gf_isom_get_next_moof_number(output);\r
+               sprintf(sOpt, "%d", fragment_index);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "NextFragmentIndex", sOpt);\r
+\r
+\r
+               sprintf(sOpt, "%f", period_duration);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "CumulatedDuration", sOpt);\r
+\r
+               if (store_dash_params) {\r
+                       sprintf(sOpt, "%u", bandwidth);\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, RepSecName, "Bandwidth", sOpt);\r
+               }\r
+       }\r
+\r
+err_exit:\r
+       if (fragmenters){\r
+               while (gf_list_count(fragmenters)) {\r
+                       tf = (GF_ISOMTrackFragmenter *)gf_list_get(fragmenters, 0);\r
+                       gf_free(tf);\r
+                       gf_list_rem(fragmenters, 0);\r
+               }\r
+               gf_list_del(fragmenters);\r
+       }\r
+       if (output) {\r
+               if (e) gf_isom_delete(output);\r
+               else gf_isom_close(output);\r
+       }\r
+       if (!bs_switching_is_output && bs_switch_segment) \r
+               gf_isom_delete(bs_switch_segment);\r
+       gf_set_progress("ISO File Fragmenting", nb_samp, nb_samp);\r
+       if (mpd_segs) fclose(mpd_segs);\r
+       return e;\r
+}\r
+\r
+\r
+static GF_Err dasher_isom_get_input_components_info(GF_DashSegInput *input, GF_DASHSegmenterOptions *opts)\r
+{\r
+       u32 i;\r
+       GF_ISOFile *in;\r
+       Double dur;\r
+\r
+       in = gf_isom_open(input->file_name, GF_ISOM_OPEN_READ, NULL);\r
+       input->duration = 0;\r
+       for (i=0; i<gf_isom_get_track_count(in); i++) {\r
+               u32 mtype = gf_isom_get_media_type(in, i+1);\r
+\r
+               if (mtype == GF_ISOM_MEDIA_HINT) \r
+                       continue;\r
+               \r
+               if (gf_isom_get_sample_count(in, i+1)<2)\r
+                       continue;\r
+       \r
+               dur = (Double) gf_isom_get_track_duration(in, i+1);\r
+               dur /= gf_isom_get_timescale(in);\r
+               if (dur > input->duration) input->duration = dur;\r
+\r
+               input->components[input->nb_components].ID = gf_isom_get_track_id(in, i+1);\r
+               input->components[input->nb_components].media_type = mtype;\r
+               if (mtype == GF_ISOM_MEDIA_VISUAL) {\r
+                       gf_isom_get_visual_info(in, i+1, 1, &input->components[input->nb_components].width, &input->components[input->nb_components].height);\r
+\r
+                       input->components[input->nb_components].fps_num = gf_isom_get_media_timescale(in, i+1);\r
+                       /*get duration of 2nd sample*/\r
+                       input->components[input->nb_components].fps_denum = gf_isom_get_sample_duration(in, i+1, 2);\r
+\r
+               }\r
+               /*non-video tracks, get lang*/\r
+               else if (mtype == GF_ISOM_MEDIA_AUDIO) {\r
+                       u8 bps;\r
+                       gf_isom_get_audio_info(in, i+1, 1, &input->components[input->nb_components].sample_rate, &input->components[input->nb_components].channels, &bps);\r
+               }\r
+               gf_isom_get_media_language(in, i+1, input->components[input->nb_components].szLang);\r
+\r
+               input->nb_components++;\r
+       }\r
+       return gf_isom_close(in);\r
+}\r
+\r
+static GF_Err dasher_isom_classify_input(GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 input_idx, u32 *current_group_id, u32 *max_sap_type)\r
+{\r
+       u32 i, j;\r
+       GF_ISOFile *set_file = gf_isom_open(dash_inputs[input_idx].file_name, GF_ISOM_OPEN_READ, NULL);\r
+\r
+       for (i=input_idx+1; i<nb_dash_inputs; i++) {\r
+               Bool valid_in_adaptation_set = 1;\r
+               Bool assign_to_group = 1;\r
+               GF_ISOFile *in;\r
+\r
+               if (dash_inputs[input_idx].period != dash_inputs[i].period) \r
+                       continue;\r
+               \r
+               if (strcmp(dash_inputs[input_idx].szMime, dash_inputs[i].szMime))\r
+                       continue;\r
+\r
+               in = gf_isom_open(dash_inputs[i].file_name, GF_ISOM_OPEN_READ, NULL);\r
+\r
+               for (j=0; j<gf_isom_get_track_count(set_file); j++) {\r
+                       u32 mtype, msub_type;\r
+                       Bool same_codec = 1;\r
+                       u32 track = gf_isom_get_track_by_id(in, gf_isom_get_track_id(set_file, j+1));\r
+\r
+                       if (!track) {\r
+                               valid_in_adaptation_set = 0;\r
+                               assign_to_group = 0;\r
+                               break;\r
+                       }\r
+                       mtype = gf_isom_get_media_type(set_file, j+1);\r
+                       if (mtype != gf_isom_get_media_type(in, j+1)) {\r
+                               valid_in_adaptation_set = 0;\r
+                               assign_to_group = 0;\r
+                               break;\r
+                       }\r
+                       msub_type = gf_isom_get_media_subtype(set_file, j+1, 1);\r
+                       if (msub_type != gf_isom_get_media_subtype(in, j+1, 1)) same_codec = 0;\r
+                       if ((msub_type==GF_ISOM_SUBTYPE_MPEG4) \r
+                               || (msub_type==GF_ISOM_SUBTYPE_MPEG4_CRYP) \r
+                               || (msub_type==GF_ISOM_SUBTYPE_AVC_H264)\r
+                               || (msub_type==GF_ISOM_SUBTYPE_AVC2_H264)\r
+                               || (msub_type==GF_ISOM_SUBTYPE_SVC_H264)\r
+                               || (msub_type==GF_ISOM_SUBTYPE_LSR1)\r
+                               ) {\r
+                                       GF_DecoderConfig *dcd1 = gf_isom_get_decoder_config(set_file, j+1, 1);\r
+                                       GF_DecoderConfig *dcd2 = gf_isom_get_decoder_config(in, j+1, 1);\r
+                                       if (dcd1 && dcd2 && (dcd1->streamType==dcd2->streamType) && (dcd1->objectTypeIndication==dcd2->objectTypeIndication)) {\r
+                                               same_codec = 1;\r
+                                       } else {\r
+                                               same_codec = 0;\r
+                                       }\r
+                                       if (dcd1) gf_odf_desc_del((GF_Descriptor *)dcd1);\r
+                                       if (dcd2) gf_odf_desc_del((GF_Descriptor *)dcd2);\r
+                       }\r
+\r
+                       if (!same_codec) {\r
+                               valid_in_adaptation_set = 0;\r
+                               break;\r
+                       }\r
+\r
+                       if ((mtype!=GF_ISOM_MEDIA_VISUAL) && (mtype!=GF_ISOM_MEDIA_HINT)) {\r
+                               char szLang1[4], szLang2[4];\r
+                               szLang1[3] = szLang2[3] = 0;\r
+                               gf_isom_get_media_language(set_file, j+1, szLang1);\r
+                               gf_isom_get_media_language(in, j+1, szLang2);\r
+                               if (stricmp(szLang1, szLang2)) {\r
+                                       valid_in_adaptation_set = 0;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (mtype==GF_ISOM_MEDIA_VISUAL) {\r
+                               u32 w1, h1, w2, h2;\r
+                               Bool rap, roll;\r
+                               u32 roll_dist, sap_type;\r
+\r
+                               gf_isom_get_track_layout_info(set_file, j+1, &w1, &h1, NULL, NULL, NULL);\r
+                               gf_isom_get_track_layout_info(in, j+1, &w2, &h2, NULL, NULL, NULL);\r
+\r
+                               if (h1*w2 != h2*w1) {\r
+                                       valid_in_adaptation_set = 0;\r
+                                       break;\r
+                               }\r
+\r
+                               gf_isom_get_sample_rap_roll_info(in, j+1, 0, &rap, &roll, &roll_dist);\r
+                               if (roll_dist>0) sap_type = 4;\r
+                               else if (roll) sap_type = 3;\r
+                               else if (rap) sap_type = 1;\r
+                               else sap_type = 1;\r
+                               if (*max_sap_type < sap_type) *max_sap_type = sap_type;\r
+                       }\r
+               }\r
+               gf_isom_close(in);\r
+               if (valid_in_adaptation_set) {\r
+                       dash_inputs[i].adaptation_set = dash_inputs[input_idx].adaptation_set;\r
+                       dash_inputs[input_idx].nb_rep_in_adaptation_set ++;\r
+               } else if (assign_to_group) {\r
+                       if (!dash_inputs[input_idx].group_id) {\r
+                               (*current_group_id) ++;\r
+                               dash_inputs[input_idx].group_id = (*current_group_id);\r
+                       }\r
+                       dash_inputs[i].group_id = (*current_group_id);\r
+               }\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err dasher_isom_create_init_segment(GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 adaptation_set, char *szInitName, const char *tmpdir, Bool *disable_bs_switching)\r
+{\r
+       GF_Err e = GF_OK;\r
+       u32 i;\r
+       Bool sps_merge_failed = 0;\r
+       GF_ISOFile *init_seg = gf_isom_open(szInitName, GF_ISOM_OPEN_WRITE, tmpdir);\r
+\r
+       for (i=0; i<nb_dash_inputs; i++) {\r
+               u32 j;\r
+               GF_ISOFile *in;\r
+\r
+               if (dash_inputs[i].adaptation_set != adaptation_set)\r
+                       continue;\r
+\r
+               in = gf_isom_open(dash_inputs[i].file_name, GF_ISOM_OPEN_READ, NULL);\r
+               if (!in) {\r
+                       e = gf_isom_last_error(NULL);\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH]: Error while opening %s: %s\n", dash_inputs[i].file_name, gf_error_to_string( e ) ));\r
+                       return e;\r
+               }\r
+\r
+               for (j=0; j<gf_isom_get_track_count(in); j++) {\r
+                       u32 track = gf_isom_get_track_by_id(init_seg, gf_isom_get_track_id(in, j+1));\r
+                       if (track) {\r
+                               u32 outDescIndex;\r
+                               if ( gf_isom_get_sample_description_count(in, j+1) != 1) {\r
+                                       e = GF_NOT_SUPPORTED;\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH]: Cannot merge track with multiple sample descriptions (file %s) - try disabling bitstream switching\n", dash_inputs[i].file_name ));\r
+                                       gf_isom_delete(init_seg);\r
+                                       gf_isom_delete(in);\r
+                                       return e;\r
+                               }\r
+\r
+                               /*if not the same sample desc we might need to clone it*/\r
+                               if (! gf_isom_is_same_sample_description(in, j+1, 1, init_seg, track, 1)) {\r
+                                       Bool do_merge = 1;\r
+                                       u32 stype1, stype2;\r
+                                       stype1 = gf_isom_get_media_subtype(in, j+1, 1);\r
+                                       stype2 = gf_isom_get_media_subtype(init_seg, track, 1);\r
+                                       if (stype1 != stype2) do_merge = 0;\r
+                                       switch (stype1) {\r
+                                               case GF_4CC( 'a', 'v', 'c', '1'):\r
+                                               case GF_4CC( 'a', 'v', 'c', '2'):\r
+                                               case GF_4CC( 's', 'v', 'c', '1'):\r
+                                                       break;\r
+                                               default:\r
+                                                       do_merge = 0;\r
+                                                       break;\r
+                                       }\r
+                                       if (do_merge) {\r
+                                               u32 k, l, sps_id1, sps_id2;\r
+                                               GF_AVCConfig *avccfg1 = gf_isom_avc_config_get(in, j+1, 1);\r
+                                               GF_AVCConfig *avccfg2 = gf_isom_avc_config_get(init_seg, track, 1);\r
+#ifndef GPAC_DISABLE_AV_PARSERS\r
+                                               for (k=0; k<gf_list_count(avccfg2->sequenceParameterSets); k++) {\r
+                                                       GF_AVCConfigSlot *slc = gf_list_get(avccfg2->sequenceParameterSets, k);\r
+                                                       gf_avc_get_sps_info(slc->data, slc->size, &sps_id1, NULL, NULL, NULL, NULL);\r
+                                                       for (l=0; l<gf_list_count(avccfg1->sequenceParameterSets); l++) {\r
+                                                               GF_AVCConfigSlot *slc_orig = gf_list_get(avccfg1->sequenceParameterSets, l);\r
+                                                               gf_avc_get_sps_info(slc_orig->data, slc_orig->size, &sps_id2, NULL, NULL, NULL, NULL);\r
+                                                               if (sps_id2==sps_id1) {\r
+                                                                       do_merge = 0;\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+#endif\r
+                                               /*no conflicts in SPS ids, merge all SPS in a single sample desc*/\r
+                                               if (do_merge) {\r
+                                                       while (gf_list_count(avccfg1->sequenceParameterSets)) {\r
+                                                               GF_AVCConfigSlot *slc = gf_list_get(avccfg1->sequenceParameterSets, 0);\r
+                                                               gf_list_rem(avccfg1->sequenceParameterSets, 0);\r
+                                                               gf_list_add(avccfg2->sequenceParameterSets, slc);\r
+                                                       }\r
+                                                       while (gf_list_count(avccfg1->pictureParameterSets)) {\r
+                                                               GF_AVCConfigSlot *slc = gf_list_get(avccfg1->pictureParameterSets, 0);\r
+                                                               gf_list_rem(avccfg1->pictureParameterSets, 0);\r
+                                                               gf_list_add(avccfg2->pictureParameterSets, slc);\r
+                                                       }\r
+                                                       gf_isom_avc_config_update(init_seg, track, 1, avccfg2);\r
+                                               } else {\r
+                                                       sps_merge_failed = 1;\r
+                                               }\r
+                                               gf_odf_avc_cfg_del(avccfg1);\r
+                                               gf_odf_avc_cfg_del(avccfg2);\r
+                                       }\r
+\r
+                                       /*cannot merge, clone*/\r
+                                       if (!do_merge)\r
+                                               gf_isom_clone_sample_description(init_seg, track, in, j+1, 1, NULL, NULL, &outDescIndex);\r
+                               }\r
+                       } else {\r
+                               u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess;\r
+                               u8 defaultPadding;\r
+                               u16 defaultDegradationPriority;\r
+\r
+                               gf_isom_clone_track(in, j+1, init_seg, 0, &track);\r
+\r
+                               gf_isom_get_fragment_defaults(in, j+1, &defaultDuration, &defaultSize, \r
+                                                                               &defaultDescriptionIndex, &defaultRandomAccess, \r
+                                                                               &defaultPadding, &defaultDegradationPriority);\r
+                               //setup for fragmentation\r
+                               e = gf_isom_setup_track_fragment(init_seg, gf_isom_get_track_id(init_seg, track),\r
+                                                       defaultDescriptionIndex, defaultDuration,\r
+                                                       defaultSize, (u8) defaultRandomAccess,\r
+                                                       defaultPadding, defaultDegradationPriority);\r
+                               if (e) break;\r
+                       }\r
+               }\r
+               gf_isom_set_brand_info(init_seg, GF_4CC('i','s','o','5'), 1);\r
+               gf_isom_modify_alternate_brand(init_seg, GF_4CC('d','a','s','h'), 1);\r
+               if (i) gf_isom_close(in);\r
+       }\r
+       if (e) {\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH]: Couldn't create initialization segment: error %s\n", gf_error_to_string(e) ));\r
+               *disable_bs_switching = 1;\r
+               gf_isom_delete(init_seg);\r
+               gf_delete_file(szInitName);\r
+               return GF_OK;\r
+       } else if (sps_merge_failed) {\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH]: Couldnt merge AVC|H264 SPS from different files (same SPS ID used) - different sample descriptions will be used\n"));\r
+               *disable_bs_switching = 1;\r
+               gf_isom_delete(init_seg);\r
+               gf_delete_file(szInitName);\r
+       } else {\r
+               gf_isom_close(init_seg);\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err dasher_isom_segment_file(GF_DashSegInput *dash_input, const char *szOutName, GF_DASHSegmenterOptions *dash_cfg, Bool first_in_set)\r
+{\r
+       GF_ISOFile *in = gf_isom_open(dash_input->file_name, GF_ISOM_OPEN_READ, dash_cfg->tmpdir);\r
+       GF_Err e = gf_media_isom_segment_file(in, szOutName, dash_cfg->fragment_duration, dash_cfg, dash_input, first_in_set);\r
+       gf_isom_close(in);\r
+       return e;\r
+}\r
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/\r
+\r
+static GF_Err dasher_generic_classify_input(GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 input_idx, u32 *current_group_id, u32 *max_sap_type)\r
+{\r
+#ifdef GPAC_DISABLE_MEDIA_IMPORT\r
+       return GF_NOT_SUPPORTED;\r
+#else\r
+       GF_Err e;\r
+       u32 i, j, k;\r
+       GF_MediaImporter in, probe;\r
+\r
+       memset(&in, 0, sizeof(GF_MediaImporter));\r
+       in.flags = GF_IMPORT_PROBE_ONLY;\r
+       in.in_name = (char *)dash_inputs[input_idx].file_name;\r
+       e = gf_media_import(&in);\r
+       if (e) return e;\r
+\r
+       for (i=input_idx+1; i<nb_dash_inputs; i++) {\r
+               Bool valid_in_adaptation_set = 1;\r
+               Bool assign_to_group = 1;\r
+\r
+               if (dash_inputs[input_idx].period != dash_inputs[i].period) \r
+                       continue;\r
+\r
+               if (strcmp(dash_inputs[input_idx].szMime, dash_inputs[i].szMime))\r
+                       continue;\r
+\r
+               memset(&probe, 0, sizeof(GF_MediaImporter));\r
+               probe.flags = GF_IMPORT_PROBE_ONLY;\r
+               probe.in_name = (char *)dash_inputs[i].file_name;\r
+               e = gf_media_import(&probe);\r
+               if (e) return e;\r
+\r
+               if (in.nb_progs != probe.nb_progs) valid_in_adaptation_set = 0;\r
+               if (in.nb_tracks != probe.nb_tracks) valid_in_adaptation_set = 0;\r
+\r
+               for (j=0; j<in.nb_tracks; j++) {\r
+                       struct __track_import_info *src_tk, *probe_tk;\r
+                       Bool found = 0;\r
+                       /*make sure we have the same track*/\r
+                       for (k=0; k<probe.nb_tracks;k++) {\r
+                               if (in.tk_info[j].track_num==probe.tk_info[k].track_num) {\r
+                                       found = 1;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (!found) {\r
+                               valid_in_adaptation_set = 0;\r
+                               assign_to_group = 0;\r
+                               break;\r
+                       }\r
+                       src_tk = &in.tk_info[j];\r
+                       probe_tk = &probe.tk_info[k];\r
+\r
+                       /*make sure we use the same media type*/\r
+                       if (src_tk->type != probe_tk->type) {\r
+                               valid_in_adaptation_set = 0;\r
+                               assign_to_group = 0;\r
+                               break;\r
+                       }\r
+                       /*make sure we use the same codec type*/\r
+                       if (src_tk->media_type != probe_tk->media_type) {\r
+                               valid_in_adaptation_set = 0;\r
+                               break;\r
+                       }\r
+                       /*make sure we use the same aspect ratio*/\r
+                       if (src_tk->type==GF_ISOM_MEDIA_VISUAL) {\r
+                               if (src_tk->video_info.width * probe_tk->video_info.height != src_tk->video_info.height * probe_tk->video_info.width) {\r
+                                       valid_in_adaptation_set = 0;\r
+                                       break;\r
+                               }\r
+                       } else if (src_tk->lang != probe_tk->lang) {\r
+                               valid_in_adaptation_set = 0;\r
+                               break;\r
+                       }\r
+\r
+                       if (!valid_in_adaptation_set) break;\r
+               }\r
+               if (valid_in_adaptation_set) {\r
+                       dash_inputs[i].adaptation_set = dash_inputs[input_idx].adaptation_set;\r
+                       dash_inputs[input_idx].nb_rep_in_adaptation_set ++;\r
+               } else if (assign_to_group) {\r
+                       if (!dash_inputs[input_idx].group_id) {\r
+                               (*current_group_id) ++;\r
+                               dash_inputs[input_idx].group_id = (*current_group_id);\r
+                       }\r
+                       dash_inputs[i].group_id = (*current_group_id);\r
+               }\r
+       }\r
+#endif\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err dasher_generic_get_components_info(GF_DashSegInput *input, GF_DASHSegmenterOptions *opts)\r
+{\r
+#ifdef GPAC_DISABLE_MEDIA_IMPORT\r
+       return GF_NOT_SUPPORTED;\r
+#else\r
+       u32 i;\r
+       GF_Err e;\r
+       GF_MediaImporter in;\r
+       memset(&in, 0, sizeof(GF_MediaImporter));\r
+       in.flags = GF_IMPORT_PROBE_ONLY;\r
+       in.in_name = (char *)input->file_name;\r
+       e = gf_media_import(&in);\r
+       if (e) return e;\r
+\r
+       input->nb_components = in.nb_tracks;\r
+       for (i=0; i<in.nb_tracks; i++) {\r
+               input->components[i].width = in.tk_info[i].video_info.width;\r
+               input->components[i].height = in.tk_info[i].video_info.height;\r
+               input->components[i].media_type = in.tk_info[i].type;\r
+               input->components[i].channels = in.tk_info[i].audio_info.nb_channels;\r
+               input->components[i].sample_rate = in.tk_info[i].audio_info.sample_rate;\r
+               input->components[i].ID = in.tk_info[i].track_num;\r
+               if (in.tk_info[i].lang)\r
+                       strcpy(input->components[i].szLang, gf_4cc_to_str(in.tk_info[i].lang) );\r
+               strcpy(input->components[i].szCodec, in.tk_info[i].szCodecProfile);\r
+               input->components[i].fps_denum = 1000;\r
+               input->components[i].fps_num = (u32) (in.tk_info[i].video_info.FPS*1000);\r
+       }\r
+#endif\r
+       return GF_OK;\r
+}\r
+\r
+#ifndef GPAC_DISABLE_MPEG2TS\r
+\r
+typedef struct\r
+{\r
+       FILE *src;\r
+       GF_M2TS_Demuxer *ts;\r
+       u64 file_size;\r
+       u32 bandwidth;\r
+       Bool has_seen_pat;\r
+       \r
+       u64 suspend_indexing;\r
+\r
+       /* For indexing the TS*/\r
+       Double segment_duration;\r
+       Bool segment_at_rap;\r
+\r
+       FILE *index_file;\r
+       GF_BitStream *index_bs;\r
+\r
+       u32 subduration;\r
+       u32 skip_nb_segments;\r
+       u32 cumulated_duration;\r
+\r
+       GF_SegmentIndexBox *sidx;\r
+       GF_PcrInfoBox *pcrb;\r
+\r
+       u32 reference_pid;\r
+       GF_M2TS_PES *reference_stream;\r
+       \r
+       u32 nb_pes_in_segment;\r
+       /* earliest presentation time for the whole segment */\r
+       u64 first_PTS;\r
+       /* DTS-PCR diff for the first PES packet */\r
+       u64 PCR_DTS_initial_diff;\r
+\r
+       /* earliest presentation time for the subsegment being processed */\r
+       u64 base_PTS;\r
+       /* byte offset for the start of subsegment being processed */\r
+       u64 base_offset;\r
+       /* last presentation time for the subsegment being processed (before the next subsegment is started) */\r
+       u64 last_PTS;\r
+       /* last decoding time for the subsegment being processed */\r
+       u64 last_DTS;\r
+       /* byte offset for the last PES packet for the subsegment being processed */\r
+       u32 last_offset;\r
+       u32 last_frame_duration;\r
+\r
+       /* earliest presentation time for the previous subsegment */\r
+       u64 prev_base_PTS;\r
+       /* byte offset for the start of the previous subsegment */\r
+       u64 prev_base_offset;\r
+       /* last presentation time for the previous subsegment */\r
+       u64 prev_last_PTS;\r
+       /* byte offset for the last PES packet for the previous subsegment */\r
+       u32 prev_last_offset;\r
+\r
+       /* indicates if the current subsegment contains a SAP and its SAP type*/\r
+       u32 SAP_type;\r
+       /* indicates if the first PES in the current subsegment is a SAP*/\r
+       Bool first_pes_sap;\r
+       /* Presentation time for the first RAP encountered in the subsegment */\r
+       u64 first_SAP_PTS;\r
+       /* byte offset for the first RAP encountered in the subsegment */\r
+       u32 first_SAP_offset;\r
+       u64 prev_last_SAP_PTS;\r
+       u32 prev_last_SAP_offset;\r
+       u64 last_SAP_PTS;\r
+       u32 last_SAP_offset;\r
+\r
+       /*Interpolated PCR value for the pcrb*/\r
+       u64 interpolated_pcr_value;\r
+       u64 last_pcr_value;\r
+\r
+       /* information about the first PAT found in the subsegment */\r
+       u32 last_pat_position;\r
+       u32 first_pat_position;\r
+       u32 prev_last_pat_position;\r
+       Bool first_pat_position_valid;\r
+       u32 pat_version;\r
+\r
+       /* information about the first CAT found in the subsegment */\r
+       u32 last_cat_position;\r
+       u32 first_cat_position;\r
+       u32 prev_last_cat_position;\r
+       Bool first_cat_position_valid;\r
+       u32 cat_version;\r
+\r
+       /* information about the first PMT found in the subsegment */\r
+       u32 last_pmt_position;\r
+       u32 first_pmt_position;\r
+       u32 prev_last_pmt_position;\r
+       Bool first_pmt_position_valid;\r
+       u32 pmt_version;\r
+\r
+       /* information about the first PCR found in the subsegment */\r
+       u32 last_pcr_position;\r
+       u32 first_pcr_position;\r
+       Bool first_pcr_position_valid;\r
+       u32 prev_last_pcr_position;\r
+\r
+} GF_TSSegmenter;\r
+\r
+static void m2ts_sidx_add_entry(GF_SegmentIndexBox *sidx, Bool ref_type, \r
+                                                               u32 size, u32 duration, Bool first_is_SAP, u32 sap_type, u32 RAP_delta_time)\r
+{\r
+       GF_SIDXReference *ref;\r
+       sidx->nb_refs++;\r
+       sidx->refs = gf_realloc(sidx->refs, sidx->nb_refs*sizeof(GF_SIDXReference));\r
+       ref = &(sidx->refs[sidx->nb_refs-1]);\r
+       ref->reference_type = ref_type;\r
+       ref->reference_size = size;\r
+       ref->subsegment_duration = duration;\r
+       ref->starts_with_SAP = first_is_SAP;\r
+       ref->SAP_type = sap_type;\r
+       ref->SAP_delta_time = (sap_type ? RAP_delta_time: 0);\r
+}\r
+\r
+static void m2ts_sidx_finalize_size(GF_TSSegmenter *index_info, u64 file_size)\r
+{\r
+       GF_SIDXReference *ref;\r
+       if (index_info->suspend_indexing) return;\r
+       if (index_info->sidx->nb_refs == 0) return;\r
+       ref = &(index_info->sidx->refs[index_info->sidx->nb_refs-1]);\r
+       ref->reference_size = (u32)(file_size - index_info->prev_base_offset);\r
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Subsegment: position-range ajdustment:%d-%d (%d bytes)\n", index_info->prev_base_offset, (u32)file_size, ref->reference_size));\r
+}\r
+\r
+static void m2ts_sidx_flush_entry(GF_TSSegmenter *index_info) \r
+{\r
+       u32 end_offset, size, duration; \r
+       Bool store_segment = 1;\r
+\r
+       if (index_info->suspend_indexing) \r
+               return;\r
+\r
+       if (index_info->skip_nb_segments) {\r
+               index_info->skip_nb_segments --;\r
+               store_segment = 0;\r
+       }\r
+\r
+       /* determine the end of the current index */\r
+       if (index_info->segment_at_rap) {\r
+               /*split at PAT*/\r
+               end_offset = index_info->last_pat_position;\r
+       } else {\r
+               /* split at PES header */\r
+               end_offset = index_info->last_offset; \r
+       }\r
+       size = (u32)(end_offset - index_info->base_offset);\r
+       duration = (u32)(index_info->last_PTS - index_info->base_PTS);\r
+\r
+       if (store_segment) {\r
+               u32 prev_duration, SAP_delta_time, SAP_offset;\r
+               if (!index_info->sidx) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Segment: Reference PID: %d, EPTime: "LLU", Start Offset: %d bytes\n", index_info->reference_pid, index_info->base_PTS, index_info->base_offset));\r
+                       index_info->sidx = (GF_SegmentIndexBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_SIDX);\r
+                       index_info->sidx->reference_ID = index_info->reference_pid;\r
+                       /* timestamps in MPEG-2 are expressed in 90 kHz timescale */\r
+                       index_info->sidx->timescale = 90000;\r
+                       /* first encountered PTS on the PID for this subsegment */\r
+                       index_info->sidx->earliest_presentation_time = index_info->base_PTS;\r
+                       index_info->sidx->first_offset = index_info->base_offset;\r
+                                       \r
+               }\r
+               \r
+               if (!index_info->pcrb) {\r
+                       index_info->pcrb = (GF_PcrInfoBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_PCRB);\r
+               }\r
+\r
+               /* close the current index */ \r
+               SAP_delta_time = (u32)(index_info->first_SAP_PTS - index_info->base_PTS);\r
+               SAP_offset = (u32)(index_info->first_SAP_offset - index_info->base_offset);\r
+               m2ts_sidx_add_entry(index_info->sidx, 0, size, duration, index_info->first_pes_sap, index_info->SAP_type, SAP_delta_time);\r
+\r
+               /*add pcrb entry*/\r
+               index_info->pcrb->subsegment_count++;\r
+               index_info->pcrb->pcr_values = gf_realloc(index_info->pcrb->pcr_values, index_info->pcrb->subsegment_count*sizeof(u64));\r
+               index_info->pcrb->pcr_values[index_info->pcrb->subsegment_count-1] = index_info->interpolated_pcr_value;\r
+\r
+               /* adjust the previous index duration */\r
+               if (index_info->sidx->nb_refs > 0 && (index_info->base_PTS < index_info->prev_last_PTS) ) {\r
+                       prev_duration = (u32)(index_info->base_PTS-index_info->prev_base_PTS);\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("           time-range adj.: %.03f-%.03f / %.03f sec.\n",               \r
+                               (index_info->prev_base_PTS - index_info->first_PTS)/90000.0, \r
+                               (index_info->base_PTS - index_info->first_PTS)/90000.0, prev_duration/90000.0));\r
+                       \r
+                       /*update previous duration*/\r
+                       if (index_info->sidx->nb_refs) {\r
+                               index_info->sidx->refs[index_info->sidx->nb_refs-1].subsegment_duration = prev_duration;\r
+                       }\r
+\r
+               }\r
+\r
+               /* Printing result */\r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Subsegment:"));\r
+               //time-range:position-range: \r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (" %.03f-%0.3f / %.03f sec., %d-%d / %d bytes, ",\r
+                       (index_info->base_PTS - index_info->first_PTS)/90000.0, \r
+                       (index_info->last_PTS - index_info->first_PTS)/90000.0, duration/90000.0,\r
+                       index_info->base_offset, end_offset, size));\r
+               if (index_info->SAP_type) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("RAP @ %.03f sec. / %d bytes", (index_info->first_SAP_PTS - index_info->first_PTS)/90000.0, \r
+                               SAP_offset));\r
+               }\r
+               if (index_info->first_pat_position_valid) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", PAT @ %d bytes", (u32)(index_info->first_pat_position - index_info->base_offset)));\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No PAT"));\r
+               }\r
+               if (index_info->first_cat_position_valid) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", CAT @ %d bytes", (u32)(index_info->first_cat_position - index_info->base_offset)));\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No CAT"));\r
+               }\r
+               if (index_info->first_pmt_position_valid) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", PMT @ %d bytes", (u32)(index_info->first_pmt_position - index_info->base_offset)));\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No PMT"));\r
+               }\r
+               if (index_info->first_pcr_position_valid) {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", PCR @ %d bytes", (u32)(index_info->first_pcr_position - index_info->base_offset)));\r
+               } else {\r
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, (", No PCR"));\r
+               }\r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\n"));\r
+\r
+       }\r
+\r
+       /* save the current values for later adjustments */\r
+       index_info->prev_last_SAP_PTS = index_info->last_SAP_PTS;\r
+       index_info->prev_last_SAP_offset = index_info->last_SAP_offset;\r
+       index_info->prev_last_PTS = index_info->last_PTS;\r
+       index_info->prev_last_offset = index_info->last_offset;\r
+       index_info->prev_base_PTS = index_info->base_PTS;\r
+       index_info->base_PTS = index_info->last_PTS;\r
+       index_info->prev_base_offset = index_info->base_offset;\r
+       index_info->prev_last_pat_position = index_info->last_pat_position;\r
+       index_info->prev_last_cat_position = index_info->last_cat_position;\r
+       index_info->prev_last_pmt_position = index_info->last_pmt_position;\r
+       index_info->prev_last_pcr_position = index_info->last_pcr_position;\r
+       \r
+       /* update the values for the new index*/\r
+       index_info->base_offset = end_offset;\r
+       index_info->SAP_type = 0;\r
+       index_info->first_SAP_PTS = 0;\r
+       index_info->first_SAP_offset = 0;\r
+       index_info->first_pes_sap = 0;\r
+       index_info->nb_pes_in_segment = 0;\r
+       index_info->last_DTS = 0;\r
+\r
+       if (index_info->last_pat_position >= index_info->base_offset) {\r
+               index_info->first_pat_position_valid = 1;\r
+               index_info->first_pat_position = index_info->last_pat_position;\r
+       } else {\r
+               index_info->first_pat_position_valid = 0;\r
+               index_info->first_pat_position = 0;\r
+       }\r
+       if (index_info->last_cat_position >= index_info->base_offset) {\r
+               index_info->first_cat_position_valid = 1;\r
+               index_info->first_cat_position = index_info->last_cat_position;\r
+       } else {\r
+               index_info->first_cat_position_valid = 0;\r
+               index_info->first_cat_position = 0;\r
+       }\r
+       if (index_info->last_pmt_position >= index_info->base_offset) {\r
+               index_info->first_pmt_position_valid = 1;\r
+               index_info->first_pmt_position = index_info->last_pmt_position;\r
+       } else {\r
+               index_info->first_pmt_position_valid = 0;\r
+               index_info->first_pmt_position = 0;\r
+       }\r
+       if (index_info->last_pcr_position >= index_info->base_offset) {\r
+               index_info->first_pcr_position_valid = 1;\r
+               index_info->first_pcr_position = index_info->last_pcr_position;\r
+       } else {\r
+               index_info->first_pcr_position_valid = 0;\r
+               index_info->first_pcr_position = 0;\r
+       }\r
+\r
+       index_info->cumulated_duration += duration;\r
+       if (index_info->subduration && (index_info->cumulated_duration >= index_info->subduration))\r
+               index_info->suspend_indexing = end_offset;\r
+}\r
+\r
+static void m2ts_check_indexing(GF_TSSegmenter *index_info)\r
+{\r
+       u32 delta_time = (u32)(index_info->last_PTS - index_info->base_PTS);\r
+       u32 segment_duration = (u32)(index_info->segment_duration*90000);\r
+       /* we exceed the segment duration flush sidx entry*/\r
+       if (delta_time >= segment_duration) {\r
+               m2ts_sidx_flush_entry(index_info);\r
+       } \r
+}\r
+static void dash_m2ts_event_check_pat(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) \r
+{\r
+       GF_TSSegmenter *ts_seg = (GF_TSSegmenter*)ts->user;\r
+       GF_M2TS_PES_PCK *pck;\r
+       switch (evt_type) {\r
+       case GF_M2TS_EVT_PAT_REPEAT:\r
+               ts_seg->has_seen_pat = 1;\r
+               break;\r
+       case GF_M2TS_EVT_PMT_FOUND:\r
+       {\r
+               u32 i, count;\r
+               GF_M2TS_Program *prog = (GF_M2TS_Program*)par;\r
+               count = gf_list_count(prog->streams);\r
+               for (i=0; i<count; i++) {\r
+                       GF_M2TS_ES *es = gf_list_get(prog->streams, i);\r
+                       gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_DEFAULT);\r
+               }\r
+       }\r
+               break;\r
+       case GF_M2TS_EVT_PES_PCK:\r
+               pck = par;\r
+               /* we process packets only for the given PID */\r
+               if (pck->stream->pid == pck->stream->program->pcr_pid) {\r
+                       if (!ts_seg->nb_pes_in_segment || (ts_seg->first_PTS > pck->PTS)) {\r
+                               ts_seg->first_PTS = pck->PTS;\r
+                               ts_seg->nb_pes_in_segment++;\r
+                       }\r
+                       if (pck->PTS > ts_seg->last_PTS) {\r
+                               ts_seg->last_PTS = pck->PTS;\r
+                       }\r
+                       if (ts_seg->last_DTS != pck->DTS) {\r
+                               ts_seg->last_frame_duration = (u32) (pck->DTS - ts_seg->last_DTS);\r
+                               ts_seg->last_DTS = pck->DTS;\r
+                       }\r
+               }\r
+               break;\r
+       }\r
+}\r
+\r
+static void dash_m2ts_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) \r
+{\r
+       GF_M2TS_Program *prog;\r
+       GF_M2TS_PES_PCK *pck;\r
+       GF_M2TS_PES *pes;\r
+       u64 interpolated_pcr_value;\r
+       u32 count, i;\r
+       GF_TSSegmenter *ts_seg = (GF_TSSegmenter*)ts->user;\r
+\r
+       switch (evt_type) {\r
+       case GF_M2TS_EVT_PAT_FOUND:\r
+               if (!ts_seg->first_pat_position_valid) {\r
+                       ts_seg->first_pat_position_valid = 1;\r
+                       ts_seg->first_pat_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pat_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_PAT_UPDATE:\r
+               if (!ts_seg->first_pat_position_valid) {\r
+                       ts_seg->first_pat_position_valid = 1;\r
+                       ts_seg->first_pat_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pat_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_PAT_REPEAT:\r
+               if (!ts_seg->first_pat_position_valid) {\r
+                       ts_seg->first_pat_position_valid = 1;\r
+                       ts_seg->first_pat_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pat_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_CAT_FOUND:\r
+               if (!ts_seg->first_cat_position_valid) {\r
+                       ts_seg->first_cat_position_valid = 1;\r
+                       ts_seg->first_cat_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_cat_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_CAT_UPDATE:\r
+               if (!ts_seg->first_cat_position_valid) {\r
+                       ts_seg->first_cat_position_valid = 1;\r
+                       ts_seg->first_cat_position = (ts->pck_number-1)*188;\r
+               }\r
+               break;\r
+       case GF_M2TS_EVT_CAT_REPEAT:\r
+               if (!ts_seg->first_cat_position_valid) {\r
+                       ts_seg->first_cat_position_valid = 1;\r
+                       ts_seg->first_cat_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_cat_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_PMT_FOUND:\r
+               ts_seg->has_seen_pat = 1;\r
+               prog = (GF_M2TS_Program*)par;\r
+               if (!ts_seg->first_pmt_position_valid) {\r
+                       ts_seg->first_pmt_position_valid = 1;\r
+                       ts_seg->first_pmt_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pmt_position = (ts->pck_number-1)*188;\r
+               /* we create indexing information on the stream used for carrying the PCR */\r
+               ts_seg->reference_pid = prog->pcr_pid;\r
+               ts_seg->reference_stream = (GF_M2TS_PES *) ts_seg->ts->ess[prog->pcr_pid];\r
+               count = gf_list_count(prog->streams);\r
+\r
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Program number %d found - %d streams:\n", prog->number, count));\r
+               for (i=0; i<count; i++) {\r
+                       GF_M2TS_ES *es = gf_list_get(prog->streams, i);\r
+                       gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_DEFAULT);\r
+               }\r
+               break;\r
+       case GF_M2TS_EVT_PMT_UPDATE:\r
+               if (!ts_seg->first_pmt_position_valid) {\r
+                       ts_seg->first_pmt_position_valid = 1;\r
+                       ts_seg->first_pmt_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pmt_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_PMT_REPEAT:\r
+               if (!ts_seg->first_pmt_position_valid) {\r
+                       ts_seg->first_pmt_position_valid = 1;\r
+                       ts_seg->first_pmt_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pmt_position = (ts->pck_number-1)*188;\r
+               break;\r
+       case GF_M2TS_EVT_PES_PCK:\r
+               pck = par;\r
+               /*We need the interpolated PCR for the pcrb, hence moved this calculus out, and saving the calculated value in ts_seg to put it in the pcrb*/\r
+               pes = pck->stream;\r
+               /* Interpolated PCR value for the TS packet containing the PES header start */\r
+               interpolated_pcr_value = 0;\r
+               if (pes->last_pcr_value && pes->before_last_pcr_value_pck_number && pes->last_pcr_value > pes->before_last_pcr_value) {\r
+                       u32 delta_pcr_pck_num = pes->last_pcr_value_pck_number - pes->before_last_pcr_value_pck_number;\r
+                       u32 delta_pts_pcr_pck_num = pes->pes_start_packet_number - pes->last_pcr_value_pck_number;\r
+                       u64 delta_pcr_value = pes->last_pcr_value - pes->before_last_pcr_value; \r
+                       if ((pes->pes_start_packet_number > pes->last_pcr_value_pck_number)\r
+                               && (pes->last_pcr_value > pes->before_last_pcr_value)) {\r
+                               \r
+                                       pes->last_pcr_value = pes->before_last_pcr_value;\r
+                       }\r
+                       /* we can compute the interpolated pcr value for the packet containing the PES header */\r
+                       interpolated_pcr_value = pes->last_pcr_value + (u64)((delta_pcr_value*delta_pts_pcr_pck_num*1.0)/delta_pcr_pck_num);\r
+                       ts_seg->interpolated_pcr_value = interpolated_pcr_value;\r
+                       ts_seg->last_pcr_value = pes->last_pcr_value;\r
+               }\r
+               /* we process packets only for the given PID */\r
+               if (pck->stream->pid != ts_seg->reference_pid) {\r
+                       break;\r
+               } else {\r
+                       if (ts_seg->last_DTS != pck->DTS) {\r
+                               if (ts_seg->last_DTS)\r
+                                       ts_seg->last_frame_duration = (u32) (pck->DTS - ts_seg->last_DTS);\r
+                               ts_seg->last_DTS = pck->DTS;\r
+                               ts_seg->nb_pes_in_segment++;\r
+                       }\r
+\r
+                       /* we store the fact that there is at least a RAP for the index\r
+                       and we store the PTS of the first encountered RAP in the index*/\r
+                       if (pck->flags & GF_M2TS_PES_PCK_RAP) {\r
+                               ts_seg->SAP_type = 1;\r
+                               if (!ts_seg->first_SAP_PTS || (ts_seg->first_SAP_PTS > pck->PTS)) {\r
+                                       ts_seg->first_SAP_PTS = pck->PTS;\r
+                                       ts_seg->first_SAP_offset = (pck->stream->pes_start_packet_number-1)*188;\r
+                               }\r
+                               ts_seg->last_SAP_PTS = pck->PTS;\r
+                               ts_seg->last_SAP_offset = (pck->stream->pes_start_packet_number-1)*188;\r
+\r
+                               if (ts_seg->nb_pes_in_segment==1) {\r
+                                       ts_seg->first_pes_sap = 1;\r
+                               }\r
+                       }\r
+                       /* we need to know the earliest PTS value (RAP or not) in the index*/\r
+                       if (!ts_seg->base_PTS || (ts_seg->base_PTS > pck->PTS)) {\r
+                               ts_seg->base_PTS = pck->PTS;\r
+                       }\r
+                       /* we need to know the earliest PTS value for the whole file (segment) */\r
+                       if (!ts_seg->first_PTS || (ts_seg->first_PTS > pck->PTS)) {\r
+                               ts_seg->first_PTS = pck->PTS;\r
+                       }\r
+                       if (pck->PTS > ts_seg->last_PTS) {\r
+                               /* we use the last PTS for first approximation of the duration */\r
+                               ts_seg->last_PTS = pck->PTS;\r
+                               ts_seg->last_offset = (ts_seg->reference_stream->pes_start_packet_number-1)*188;\r
+                       }\r
+\r
+                       if (ts_seg->PCR_DTS_initial_diff == (u64) -1) {\r
+                               ts_seg->PCR_DTS_initial_diff = ts_seg->last_DTS - pes->last_pcr_value / 300;\r
+                       }\r
+\r
+                       m2ts_check_indexing(ts_seg);\r
+               }\r
+               break;\r
+       case GF_M2TS_EVT_PES_PCR:\r
+               pck = par;\r
+               if (!ts_seg->first_pcr_position_valid) {\r
+                       ts_seg->first_pcr_position_valid = 1;\r
+                       ts_seg->first_pcr_position = (ts->pck_number-1)*188;\r
+               }\r
+               ts_seg->last_pcr_position = (ts->pck_number-1)*188;\r
+               break;\r
+       }\r
+}\r
+\r
+static GF_Err dasher_get_ts_demux(GF_TSSegmenter *ts_seg, const char *file, u32 probe_mode)\r
+{\r
+       memset(ts_seg, 0, sizeof(GF_TSSegmenter));\r
+       ts_seg->src = gf_f64_open(file, "rb");\r
+       if (!ts_seg->src) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH]: Cannot open input %s: no such file\n", file));\r
+               return GF_URL_ERROR;\r
+       }\r
+       ts_seg->ts = gf_m2ts_demux_new();\r
+       ts_seg->ts->on_event = dash_m2ts_event_check_pat;\r
+       ts_seg->ts->notify_pes_timing = 1;\r
+       ts_seg->ts->user = ts_seg;\r
+\r
+       gf_f64_seek(ts_seg->src, 0, SEEK_END);\r
+       ts_seg->file_size = gf_f64_tell(ts_seg->src);\r
+       gf_f64_seek(ts_seg->src, 0, SEEK_SET);\r
+\r
+       if (probe_mode) {\r
+               /* first loop to process all packets between two PAT, and assume all signaling was found between these 2 PATs */\r
+               while (!feof(ts_seg->src)) {\r
+                       char data[188];\r
+                       u32 size = fread(data, 1, 188, ts_seg->src);\r
+                       if (size<188) break;\r
+\r
+                       gf_m2ts_process_data(ts_seg->ts, data, size);\r
+                       if ((probe_mode ==1) && ts_seg->has_seen_pat) break;\r
+               }\r
+               gf_m2ts_reset_parsers(ts_seg->ts);\r
+               gf_f64_seek(ts_seg->src, 0, SEEK_SET);\r
+       }\r
+       ts_seg->ts->on_event = dash_m2ts_event;\r
+       return GF_OK;\r
+}\r
+\r
+static void dasher_del_ts_demux(GF_TSSegmenter *ts_seg)\r
+{\r
+       if (ts_seg->ts) gf_m2ts_demux_del(ts_seg->ts);\r
+       if (ts_seg->src) fclose(ts_seg->src);\r
+       memset(ts_seg, 0, sizeof(GF_TSSegmenter));\r
+}\r
+\r
+static GF_Err dasher_mp2t_get_components_info(GF_DashSegInput *dash_input, GF_DASHSegmenterOptions *opts)\r
+{\r
+       GF_TSSegmenter ts_seg;\r
+       GF_Err e = dasher_generic_get_components_info(dash_input, opts);\r
+       if (e) return e;\r
+\r
+       e = dasher_get_ts_demux(&ts_seg, dash_input->file_name, 2);\r
+       if (e) return e;\r
+\r
+       dash_input->duration = (ts_seg.last_PTS + ts_seg.last_frame_duration - ts_seg.first_PTS)/90000.0;\r
+       dasher_del_ts_demux(&ts_seg);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err dasher_mp2t_segment_file(GF_DashSegInput *dash_input, const char *szOutName, GF_DASHSegmenterOptions *dash_cfg, Bool first_in_set)\r
+{      \r
+       GF_TSSegmenter ts_seg;\r
+       Bool rewrite_input = 0;\r
+       u8 is_pes[GF_M2TS_MAX_STREAMS];\r
+       char szOpt[100];\r
+       char SegName[GF_MAX_PATH], IdxName[GF_MAX_PATH];\r
+       char szSectionName[100], szRepURLsSecName[100];\r
+       char szCodecs[100];\r
+       const char *opt;\r
+       u32 i, startNumberRewind;\r
+       GF_Err e;\r
+       u64 start, pcr_shift, next_pcr_shift, next_dts;\r
+       Bool store_params=0;\r
+       Double cumulated_duration = 0;\r
+       u32 bandwidth = 0;\r
+       u32 segment_index;\r
+       /*compute name for indexed segments*/\r
+       const char *basename = gf_url_get_resource_name(szOutName);\r
+\r
+       /*perform indexation of the file, this info will be destroyed at the end of the segment file routine*/\r
+       e = dasher_get_ts_demux(&ts_seg, dash_input->file_name, 0);\r
+       if (e) return e;\r
+       \r
+       ts_seg.segment_duration = dash_cfg->segment_duration;\r
+       ts_seg.segment_at_rap = dash_cfg->segments_start_with_rap;\r
+\r
+       ts_seg.bandwidth = (u32) (ts_seg.file_size * 8 / dash_input->duration); \r
+\r
+       /*create bitstreams*/\r
+       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_REPINDEX, 1, IdxName, basename, dash_input->representationID, dash_cfg->seg_rad_name, "six", 0, 0, 0);        \r
+\r
+       segment_index = 1;\r
+       startNumberRewind = 0;\r
+\r
+       ts_seg.index_file = NULL;\r
+       ts_seg.index_bs = NULL;\r
+       if (!dash_cfg->dash_ctx && (dash_cfg->use_url_template != 2)) {\r
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS\r
+               GF_SegmentTypeBox *styp;\r
+               ts_seg.index_file = gf_f64_open(IdxName, "wb");\r
+               ts_seg.index_bs = gf_bs_from_file(ts_seg.index_file, GF_BITSTREAM_WRITE);\r
+\r
+               styp = (GF_SegmentTypeBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_STYP);\r
+               styp->majorBrand = GF_4CC('r','i','s','x');\r
+               styp->minorVersion = 0;\r
+               styp->altBrand = (u32*)gf_malloc(sizeof(u32));\r
+               styp->altBrand[0] = styp->majorBrand;\r
+               styp->altCount = 1;\r
+               gf_isom_box_size((GF_Box *)styp);\r
+               gf_isom_box_write((GF_Box *)styp, ts_seg.index_bs);\r
+               gf_isom_box_del((GF_Box *)styp);\r
+#endif\r
+       }\r
+\r
+       ts_seg.PCR_DTS_initial_diff = (u64) -1;\r
+       ts_seg.subduration = (u32) (dash_cfg->subduration * 90000);\r
+\r
+       szSectionName[0] = 0;\r
+       if (dash_cfg->dash_ctx) {\r
+               sprintf(szSectionName, "Representation_%s", dash_input->representationID);\r
+               sprintf(szRepURLsSecName, "URLs_%s", dash_input->representationID);\r
+\r
+               /*restart where we left last time*/\r
+               opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "ByteOffset");\r
+               if (opt) {\r
+                       u64 offset;\r
+                       sscanf(opt, LLU, &offset);\r
+\r
+                       while (!feof(ts_seg.src) && !ts_seg.has_seen_pat) {\r
+                               char data[188];\r
+                               u32 size = fread(data, 1, 188, ts_seg.src);\r
+                               if (size<188) break;\r
+                               gf_m2ts_process_data(ts_seg.ts, data, size);\r
+                       }\r
+                       gf_m2ts_reset_parsers(ts_seg.ts);\r
+\r
+                       gf_f64_seek(ts_seg.src, offset, SEEK_SET);\r
+                       ts_seg.base_offset = offset;\r
+                       ts_seg.ts->pck_number = (u32) (offset/188);\r
+               }\r
+\r
+               opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "InitialDTSOffset");\r
+               if (opt) sscanf(opt, LLU, &ts_seg.PCR_DTS_initial_diff);\r
+       }\r
+\r
+       /*index the file*/\r
+       while (!feof(ts_seg.src) && !ts_seg.suspend_indexing) {\r
+               char data[188];\r
+               u32 size = fread(data, 1, 188, ts_seg.src);\r
+               if (size<188) break;\r
+               gf_m2ts_process_data(ts_seg.ts, data, size);\r
+       }\r
+       if (feof(ts_seg.src)) ts_seg.suspend_indexing = 0;\r
+\r
+       next_pcr_shift = 0;\r
+       if (!ts_seg.suspend_indexing) {\r
+               next_pcr_shift = ts_seg.last_DTS + ts_seg.last_frame_duration - ts_seg.PCR_DTS_initial_diff;\r
+       }\r
+       next_dts = ts_seg.last_DTS + ts_seg.last_frame_duration;\r
+\r
+       /* flush SIDX entry for the last packets */\r
+       m2ts_sidx_flush_entry(&ts_seg);\r
+       m2ts_sidx_finalize_size(&ts_seg, ts_seg.file_size);\r
+       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH]: Indexing done (1 sidx, %d entries).\n", ts_seg.sidx->nb_refs));\r
+\r
+       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_REPINDEX, 1, IdxName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "six", 0, 0, 0);      \r
+\r
+\r
+       memset(is_pes, 0, sizeof(u8)*GF_M2TS_MAX_STREAMS);\r
+       for (i=0; i<dash_input->nb_components; i++) {\r
+               is_pes[ dash_input->components[i].ID ] = 1;\r
+       }\r
+       pcr_shift = 0;\r
+\r
+       bandwidth = dash_input->bandwidth;\r
+       if (!bandwidth) bandwidth = ts_seg.bandwidth;\r
+\r
+       if (dash_cfg->dash_ctx) {\r
+\r
+               opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "Setup");\r
+               if (!opt || strcmp(opt, "yes")) {\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "Setup", "yes");\r
+                       gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "ID", dash_input->representationID);\r
+                       store_params = 1;\r
+               } else {\r
+                       if (!bandwidth) {\r
+                               opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "Bandwidth");\r
+                               if (opt) sscanf(opt, "%u", &bandwidth);\r
+                       }\r
+\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "StartIndex");\r
+                       if (opt) sscanf(opt, "%u", &segment_index);\r
+\r
+                       /*adjust the startNumber according to the timeShiftBuffer depth*/\r
+                       if ((dash_cfg->time_shift_depth>0) && (segment_index > (u32)dash_cfg->time_shift_depth) ) {\r
+                               startNumberRewind = dash_cfg->time_shift_depth;\r
+                       }\r
+\r
+\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "PCR90kOffset");\r
+                       if (opt) sscanf(opt, LLU, &pcr_shift);\r
+\r
+                       opt = gf_cfg_get_key(dash_cfg->dash_ctx, szSectionName, "CumulatedDuration");\r
+                       if (opt) cumulated_duration = atof(opt);\r
+               }\r
+       }\r
+\r
+       /*write segment template for all representations*/\r
+       if (first_in_set && dash_cfg->seg_rad_name && dash_cfg->use_url_template && !dash_cfg->variable_seg_rad_name) {\r
+               gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_TEMPLATE, 1, SegName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "ts", 0, bandwidth, segment_index);\r
+               fprintf(dash_cfg->mpd, "   <SegmentTemplate timescale=\"90000\" duration=\"%d\" startNumber=\"%d\" media=\"%s\"", (u32) (90000*dash_cfg->segment_duration), segment_index - startNumberRewind, SegName); \r
+               if (!dash_cfg->dash_ctx) {\r
+                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_INITIALIZATION_TEMPLATE, 1, IdxName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "six", 0, bandwidth, segment_index);\r
+                       fprintf(dash_cfg->mpd, " index=\"%s\"", IdxName); \r
+               } \r
+               fprintf(dash_cfg->mpd, "/>\n", (u32) (90000*dash_cfg->segment_duration), segment_index, SegName); \r
+       }\r
+\r
+\r
+       fprintf(dash_cfg->mpd, "   <Representation id=\"%s\" mimeType=\"video/mp2t\"", dash_input->representationID);\r
+       szCodecs[0] = 0;\r
+       for (i=0; i<dash_input->nb_components; i++) {\r
+               if (strlen(dash_input->components[i].szCodec)) \r
+                       if (strlen(szCodecs))\r
+                               strcat(szCodecs, ",");\r
+               strcat(szCodecs, dash_input->components[i].szCodec);\r
+\r
+               if (dash_input->components[i].width && dash_input->components[i].height) \r
+                       fprintf(dash_cfg->mpd, " width=\"%d\" height=\"%d\"", dash_input->components[i].width, dash_input->components[i].height);\r
+\r
+               if (dash_input->components[i].sample_rate) \r
+                       fprintf(dash_cfg->mpd, " audioSamplingRate=\"%d\"", dash_input->components[i].sample_rate);\r
+\r
+               if (dash_input->components[i].szLang[0]) \r
+                       fprintf(dash_cfg->mpd, " lang=\"%s\"", dash_input->components[i].szLang);\r
+       }\r
+       if (strlen(szCodecs))\r
+               fprintf(dash_cfg->mpd, " codecs=\"%s\"", szCodecs);\r
+\r
+       fprintf(dash_cfg->mpd, " startWithSAP=\"%d\"", dash_cfg->segments_start_with_rap ? 1 : 0);\r
+       fprintf(dash_cfg->mpd, " bandwidth=\"%d\"", bandwidth);\r
+       fprintf(dash_cfg->mpd, ">\n");\r
+\r
+       if (dash_cfg->single_file_mode==1) {\r
+               gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_SEGMENT, 1, SegName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "ts", 0, bandwidth, segment_index);\r
+               fprintf(dash_cfg->mpd, "    <BaseURL>%s</BaseURL>\n", dash_cfg->seg_rad_name ? SegName : dash_input->file_name);\r
+\r
+               fprintf(dash_cfg->mpd, "    <SegmentBase>\n");\r
+               fprintf(dash_cfg->mpd, "     <RepresentationIndex sourceURL=\"%s\"/>\n", IdxName);\r
+               fprintf(dash_cfg->mpd, "    </SegmentBase>\n");\r
+\r
+               /*we rewrite the file*/\r
+               if (dash_cfg->seg_rad_name) rewrite_input = 1;\r
+       } else {\r
+               if (dash_cfg->seg_rad_name && dash_cfg->use_url_template) {\r
+                       if (dash_cfg->variable_seg_rad_name) {\r
+                               gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_TEMPLATE, 1, SegName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "ts", 0, bandwidth, segment_index);\r
+                               fprintf(dash_cfg->mpd, "    <SegmentTemplate timescale=\"90000\" duration=\"%d\" startNumber=\"%d\" media=\"%s\"", (u32) (9000*dash_cfg->segment_duration), segment_index, SegName); \r
+                               if (!dash_cfg->dash_ctx) {\r
+                                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_INITIALIZATION_TEMPLATE, 1, IdxName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "six", 0, bandwidth, segment_index);\r
+                                       fprintf(dash_cfg->mpd, " index=\"%s\"", IdxName); \r
+                               }\r
+\r
+                               if (dash_cfg->time_shift_depth>=0) \r
+                                       fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", ts_seg.sidx->earliest_presentation_time + pcr_shift); \r
+                               fprintf(dash_cfg->mpd, "/>\n"); \r
+                       } else if (dash_cfg->time_shift_depth>=0) {\r
+                               fprintf(dash_cfg->mpd, "    <SegmentTemplate presentationTimeOffset=\"%d\"/>\n", ts_seg.sidx->earliest_presentation_time + pcr_shift); \r
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DASH]: PTSOffset "LLD" - startNumber %d - time %g\n", ts_seg.sidx->earliest_presentation_time + pcr_shift, segment_index, (Double) (s64) (ts_seg.sidx->earliest_presentation_time + pcr_shift) / 90000.0));\r
+                       }\r
+               } else {\r
+                       gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_SEGMENT, 1, SegName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "ts", 0, bandwidth, segment_index);\r
+                       fprintf(dash_cfg->mpd, "    <BaseURL>%s</BaseURL>\n", dash_cfg->seg_rad_name ? SegName : dash_input->file_name);\r
+                       fprintf(dash_cfg->mpd, "    <SegmentList timescale=\"90000\" duration=\"%d\"", (u32) (90000*dash_cfg->segment_duration)); \r
+                       if (dash_cfg->time_shift_depth>=0) \r
+                               fprintf(dash_cfg->mpd, " presentationTimeOffset=\"%d\"", ts_seg.sidx->earliest_presentation_time + pcr_shift); \r
+                       fprintf(dash_cfg->mpd, ">\n"); \r
+\r
+                       if (!dash_cfg->dash_ctx) {\r
+                               fprintf(dash_cfg->mpd, "     <RepresentationIndex sourceURL=\"%s\"/>\n", IdxName); \r
+                       }\r
+               }\r
+\r
+               /*rewrite previous SegmentList entries*/\r
+               if ((dash_cfg->single_file_mode==2) || (!dash_cfg->single_file_mode && !dash_cfg->use_url_template)) {\r
+                       /*rewrite previous URLs*/\r
+                       const char *opt;\r
+                       u32 count, i;\r
+                       count = gf_cfg_get_key_count(dash_cfg->dash_ctx, szRepURLsSecName);\r
+                       for (i=0; i<count; i++) {\r
+                               const char *key_name = gf_cfg_get_key_name(dash_cfg->dash_ctx, szRepURLsSecName, i);\r
+                               opt = gf_cfg_get_key(dash_cfg->dash_ctx, szRepURLsSecName, key_name);\r
+                               fprintf(dash_cfg->mpd, "     %s\n", opt);       \r
+                       }\r
+               }\r
+\r
+               if (dash_cfg->single_file_mode==2) {\r
+\r
+                       start = ts_seg.sidx->first_offset;\r
+                       for (i=0; i<ts_seg.sidx->nb_refs; i++) {\r
+                               GF_SIDXReference *ref = &ts_seg.sidx->refs[i];\r
+                               fprintf(dash_cfg->mpd, "     <SegmentURL mediaRange=\""LLD"-"LLD"\"/>\n", start, start+ref->reference_size-1);\r
+                               start += ref->reference_size;\r
+                       }\r
+                       if (dash_cfg->seg_rad_name) rewrite_input = 1;\r
+\r
+               } else {\r
+                       FILE *src, *dst;\r
+                       u64 pos, end;\r
+                       Double current_time = cumulated_duration, dur;\r
+                       src = gf_f64_open(dash_input->file_name, "rb");\r
+                       start = ts_seg.sidx->first_offset;\r
+                       for (i=0; i<ts_seg.sidx->nb_refs; i++) {\r
+                               char buf[4096];\r
+                               GF_SIDXReference *ref = &ts_seg.sidx->refs[i];\r
+\r
+                               gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_SEGMENT, 1, SegName, basename, dash_input->representationID, dash_cfg->seg_rad_name, "ts", 0, bandwidth, segment_index);\r
+\r
+                               /*warning - we may introduce repeated sequence number when concatenating files. We should use switching \r
+                               segments to force reset of the continuity counter for all our pids - we don't because most players don't car ...*/\r
+                               if (dash_cfg->use_url_template != 2) {\r
+                                       dst = gf_f64_open(SegName, "wb");\r
+\r
+                                       gf_dasher_store_segment_info(dash_cfg, SegName, current_time);\r
+                                       dur = ref->subsegment_duration;\r
+                                       dur /= 90000;\r
+                                       current_time += dur;\r
+\r
+                                       gf_f64_seek(src, start, SEEK_SET);\r
+                                       pos = start;\r
+                                       end = start+ref->reference_size;\r
+                                       while (pos<end) {\r
+                                               u32 res;\r
+                                               u32 to_read = 3760;\r
+                                               if (pos+3760 >= end) {\r
+                                                       to_read = (u32) (end-pos);\r
+                                               }\r
+                                               res = fread(buf, 1, to_read, src);\r
+                                               if (res==to_read) {\r
+                                                       gf_m2ts_restamp(buf, res, pcr_shift, is_pes);\r
+                                                       res = fwrite(buf, 1, to_read, dst);\r
+                                               }\r
+                                               if (res!=to_read) {\r
+                                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH]: IO error while Extracting segment %03d / %03d\r", i+1, ts_seg.sidx->nb_refs));\r
+                                                       break;\r
+                                               }\r
+                                               pos += res;\r
+                                       }\r
+                                       fclose(dst);\r
+                               }\r
+                               start += ref->reference_size;\r
+                               segment_index++;\r
+\r
+                               if (!dash_cfg->use_url_template) {\r
+                                       fprintf(dash_cfg->mpd, "     <SegmentURL media=\"%s\"/>\n", SegName);\r
+\r
+                                       if (dash_cfg->dash_ctx) {\r
+                                               char szKey[100], szVal[4046];\r
+                                               sprintf(szKey, "UrlInfo%d", segment_index);\r
+                                               sprintf(szVal, "<SegmentURL media=\"%s\"/>", SegName);\r
+                                               gf_cfg_set_key(dash_cfg->dash_ctx, szRepURLsSecName, szKey, szVal);\r
+                                       }\r
+                               }\r
+\r
+                               gf_set_progress("Extracting segment ", i+1, ts_seg.sidx->nb_refs);\r
+                       }\r
+                       fclose(src);\r
+                       cumulated_duration = current_time;\r
+               }       \r
+               if (!dash_cfg->seg_rad_name || !dash_cfg->use_url_template) {\r
+                       fprintf(dash_cfg->mpd, "    </SegmentList>\n");\r
+               }\r
+       }\r
+\r
+       if (rewrite_input) {\r
+               FILE *in, *out;\r
+               char buf[3760];\r
+\r
+               in = gf_f64_open(dash_input->file_name, "rb");\r
+               out = gf_f64_open(SegName, "wb");\r
+               while (1) {\r
+                       u32 read = fread(buf, 1, 3760, in);\r
+                       if (!read) break;\r
+                       gf_m2ts_restamp(buf, read, pcr_shift, is_pes);\r
+                       fwrite(buf, 1, read, out);\r
+               }\r
+               fclose(in);\r
+               fclose(out);\r
+       }\r
+\r
+       fprintf(dash_cfg->mpd, "   </Representation>\n");\r
+\r
+       if (dash_cfg->dash_ctx) {\r
+               sprintf(szOpt, "%u", bandwidth);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "Bandwidth", szOpt);\r
+\r
+               sprintf(szOpt, "%u", segment_index);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "StartIndex", szOpt);\r
+\r
+               sprintf(szOpt, "%g", ts_seg.segment_duration);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "CumulatedDuration", szOpt);\r
+\r
+               sprintf(szOpt, LLU, next_pcr_shift + pcr_shift);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "PCR90kOffset", szOpt);\r
+\r
+               sprintf(szOpt, LLU, ts_seg.suspend_indexing);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "ByteOffset", ts_seg.suspend_indexing ? szOpt : NULL);\r
+\r
+               sprintf(szOpt, LLU, ts_seg.PCR_DTS_initial_diff);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "InitialDTSOffset", ts_seg.suspend_indexing ? szOpt : NULL);\r
+\r
+               sprintf(szOpt, "%g", cumulated_duration);\r
+               gf_cfg_set_key(dash_cfg->dash_ctx, szSectionName, "CumulatedDuration", szOpt);\r
+       }\r
+\r
+       if (ts_seg.sidx && ts_seg.index_bs) {\r
+               gf_isom_box_size((GF_Box *)ts_seg.sidx);\r
+               gf_isom_box_write((GF_Box *)ts_seg.sidx, ts_seg.index_bs);\r
+       }\r
+       if (ts_seg.pcrb && ts_seg.index_bs) {\r
+               gf_isom_box_size((GF_Box *)ts_seg.pcrb);\r
+               gf_isom_box_write((GF_Box *)ts_seg.pcrb, ts_seg.index_bs);\r
+       }\r
+\r
+       if (ts_seg.sidx) gf_isom_box_del((GF_Box *)ts_seg.sidx);\r
+       if (ts_seg.pcrb) gf_isom_box_del((GF_Box *)ts_seg.pcrb);\r
+       if (ts_seg.index_file) fclose(ts_seg.index_file);\r
+       if (ts_seg.index_bs) gf_bs_del(ts_seg.index_bs);\r
+       dasher_del_ts_demux(&ts_seg);\r
+\r
+       return GF_OK;\r
+}\r
+\r
+#endif //GPAC_DISABLE_MPEG2TS\r
+\r
+GF_Err gf_dash_segmenter_probe_input(GF_DashSegInput *dash_input)\r
+{\r
+       FILE *t = gf_f64_open(dash_input->file_name, "rb");\r
+       if (!t) return GF_URL_ERROR;\r
+       fclose(t);\r
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS\r
+       if (gf_isom_probe_file(dash_input->file_name)) {\r
+               strcpy(dash_input->szMime, "video/mp4");\r
+               dash_input->dasher_create_init_segment = dasher_isom_create_init_segment;\r
+               dash_input->dasher_input_classify = dasher_isom_classify_input;\r
+               dash_input->dasher_get_components_info = dasher_isom_get_input_components_info;\r
+               dash_input->dasher_segment_file = dasher_isom_segment_file;\r
+               return GF_OK;\r
+       }\r
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/\r
+\r
+#ifndef GPAC_DISABLE_MPEG2TS\r
+       if (gf_m2ts_probe_file(dash_input->file_name)) {\r
+               GF_TSSegmenter ts_seg;\r
+               u32 count = 0;\r
+               GF_Err e = dasher_get_ts_demux(&ts_seg, dash_input->file_name, 1);\r
+               if (e) return e;\r
+               count = gf_list_count(ts_seg.ts->programs);\r
+               dasher_del_ts_demux(&ts_seg);\r
+               if (count>1) {\r
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH]: MPEG-2 TS file %s has several programs - this is not supported in MPEG-DASH - skipping\n", dash_input->file_name));\r
+                       return GF_NOT_SUPPORTED;\r
+               }\r
+\r
+               strcpy(dash_input->szMime, "video/mp2t");\r
+               /*we don't use init segments with MPEG-2 TS*/\r
+               dash_input->dasher_create_init_segment = NULL;\r
+               dash_input->dasher_input_classify = dasher_generic_classify_input;\r
+               dash_input->dasher_get_components_info = dasher_mp2t_get_components_info;\r
+               dash_input->dasher_segment_file = dasher_mp2t_segment_file;\r
+               return GF_OK;\r
+       }\r
+#endif\r
+\r
+       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH]: File %s not supported for dashing - skipping\n", dash_input->file_name));\r
+       return GF_NOT_SUPPORTED;\r
+}\r
+\r
+static GF_Err write_mpd_header(FILE *mpd, const char *mpd_name, GF_Config *dash_ctx, GF_DashProfile profile, Bool is_mpeg2, const char *title, const char *source, const char *copyright, const char *moreInfoURL, const char **mpd_base_urls, u32 nb_mpd_base_urls, Bool dash_dynamic, u32 time_shift_depth, Double mpd_duration, Double mpd_update_period)\r
+{\r
+       u32 h, m, i;\r
+       Double s;\r
+\r
+       fprintf(mpd, "<?xml version=\"1.0\"?>\n");\r
+       fprintf(mpd, "<!-- MPD file Generated with GPAC version "GPAC_FULL_VERSION" -->\n");\r
+\r
+       /*TODO what should we put for minBufferTime */\r
+       fprintf(mpd, "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\" minBufferTime=\"PT1.5S\" type=\"%s\"", dash_dynamic ? "dynamic" : "static"); \r
+       if (dash_dynamic) {\r
+#ifndef _WIN32_WCE\r
+               u32 sec, frac;\r
+               time_t gtime;\r
+               struct tm *t;\r
+               gf_net_get_ntp(&sec, &frac);\r
+\r
+               /*if time shift buffer depth is set, set availability start time to now minus timeshift buffer depth*/\r
+               if ((s32)time_shift_depth>=0) {\r
+                       sec -= time_shift_depth;\r
+               } \r
+               /*otherwise timeshift is infinite, use original availability start time*/\r
+               else if (dash_ctx) {\r
+                       const char *opt = gf_cfg_get_key(dash_ctx, "DASH", "GenerationNTP");\r
+                       sscanf(opt, "%u", &sec);\r
+               }\r
+               gtime = sec - GF_NTP_SEC_1900_TO_1970;\r
+               t = gmtime(&gtime);\r
+               fprintf(mpd, " availabilityStartTime=\"%d-%02d-%02dT%02d:%02d:%02dZ\"", 1900+t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);\r
+#endif\r
+\r
+               if ((s32)time_shift_depth>=0) {\r
+                       h = (u32) (time_shift_depth/3600);\r
+                       m = (u32) (time_shift_depth-h*60)/60;\r
+                       s = time_shift_depth - h*3600 - m*60;\r
+                       fprintf(mpd, " timeShiftBufferDepth=\"PT%dH%dM%.2fS\"", h, m, s);\r
+               }\r
+               if (mpd_update_period) {\r
+                       h = (u32) (mpd_update_period/3600);\r
+                       m = (u32) (mpd_update_period-h*60)/60;\r
+                       s = mpd_update_period - h*3600 - m*60;\r
+                       fprintf(mpd, " minimumUpdatePeriod=\"PT%dH%dM%.2fS\"", h, m, s);\r
+               }\r
+               \r
+       } else {\r
+               h = (u32) (mpd_duration/3600);\r
+               m = (u32) (mpd_duration-h*60)/60;\r
+               s = mpd_duration - h*3600 - m*60;\r
+               fprintf(mpd, " mediaPresentationDuration=\"PT%dH%dM%.2fS\"", h, m, s);\r
+       }\r
+\r
+       if (profile==GF_DASH_PROFILE_LIVE) {\r
+               fprintf(mpd, " profiles=\"urn:mpeg:dash:profile:%s:2011\"", is_mpeg2 ? "mp2t-simple" : "isoff-live");\r
+       } else if (profile==GF_DASH_PROFILE_ONDEMAND) \r
+               fprintf(mpd, " profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"");\r
+       else if (profile==GF_DASH_PROFILE_MAIN) \r
+               fprintf(mpd, " profiles=\"urn:mpeg:dash:profile:%s:2011\"", is_mpeg2 ? "mp2t-main" : "isoff-main");\r
+       else \r
+               fprintf(mpd, " profiles=\"urn:mpeg:dash:profile:full:2011\"");  \r
+\r
+       fprintf(mpd, ">\n");\r
+\r
+       fprintf(mpd, " <ProgramInformation moreInformationURL=\"%s\">\n", moreInfoURL ? moreInfoURL : "http://gpac.sourceforge.net");   \r
+       if (title) \r
+               fprintf(mpd, "  <Title>%s</Title>\n", title);\r
+       else \r
+               fprintf(mpd, "  <Title>%s generated by GPAC</Title>\n", mpd_name);\r
+\r
+       if (source) \r
+               fprintf(mpd, "  <Source>%s</Source>\n", source);\r
+       if (copyright)\r
+               fprintf(mpd, "  <Copyright>%s</Copyright>\n", copyright);\r
+       fprintf(mpd, " </ProgramInformation>\n");\r
+\r
+       for (i=0; i<nb_mpd_base_urls; i++) {\r
+               fprintf(mpd, " <BaseURL>%s</BaseURL>\n", mpd_base_urls[i]);\r
+       }\r
+       fprintf(mpd, "\n");\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err write_period_header(FILE *mpd, const char *szID, Double period_start, Double period_duration, Bool dash_dynamic)\r
+{\r
+       u32 h, m;\r
+       Double s;\r
+\r
+       fprintf(mpd, " <Period");\r
+       if (szID) \r
+               fprintf(mpd, " id=\"%s\"", szID);\r
+       \r
+       if (period_start || dash_dynamic) {\r
+               h = (u32) (period_start/3600);\r
+               m = (u32) (period_start-h*60)/60;\r
+               s = period_start - h*3600 - m*60;\r
+               fprintf(mpd, " start=\"PT%dH%dM%.2fS\"", h, m, s);      \r
+       }\r
+       if (!dash_dynamic && period_duration) {\r
+               h = (u32) (period_duration/3600);\r
+               m = (u32) (period_duration-h*60)/60;\r
+               s = period_duration - h*3600 - m*60;\r
+               fprintf(mpd, " duration=\"PT%dH%dM%.2fS\"", h, m, s);   \r
+       }\r
+       fprintf(mpd, ">\n");    \r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool use_url_template, u32 single_file_mode, GF_DashSegInput *first_rep, Bool bitstream_switching_mode, u32 max_width, u32 max_height, char *szMaxFPS, char *szLang, const char *szInitSegment)\r
+{\r
+       fprintf(mpd, "  <AdaptationSet segmentAlignment=\"true\"");\r
+       if (bitstream_switching_mode) {\r
+               fprintf(mpd, " bitstreamSwitching=\"true\"");\r
+       }\r
+       if (first_rep->group_id) {\r
+               fprintf(mpd, " group=\"%d\"", first_rep->group_id);\r
+       }\r
+       if (max_width && max_height) {\r
+               fprintf(mpd, " maxWidth=\"%d\" maxHeight=\"%d\"", max_width, max_height);\r
+               if (strlen(szMaxFPS))\r
+                       fprintf(mpd, " maxFrameRate=\"%s\"", szMaxFPS);\r
+               gf_media_reduce_aspect_ratio(&max_width, &max_height);\r
+               fprintf(mpd, " par=\"%d:%d\"", max_width, max_height);\r
+       }\r
+       if (szLang && szLang[0]) {\r
+               fprintf(mpd, " lang=\"%s\"", szLang);\r
+       }\r
+       /*this should be fixed to use info collected during segmentation process*/\r
+       if (profile==GF_DASH_PROFILE_ONDEMAND) \r
+               fprintf(mpd, " subsegmentStartsWithSAP=\"1\"");\r
+\r
+       if (!strcmp(first_rep->szMime, "video/mp2t"))\r
+               fprintf(mpd, " subsegmentAlignment=\"true\"");\r
+\r
+       fprintf(mpd, ">\n");\r
+       \r
+       if (first_rep) {\r
+               u32 i;\r
+               char langCode[4];\r
+               langCode[3] = 0;\r
+\r
+               if (bitstream_switching_mode) {\r
+                       for (i=0; i<first_rep->nb_components; i++) {\r
+                               struct _dash_component *comp = &first_rep->components[i];\r
+                               if (comp->media_type == GF_ISOM_MEDIA_AUDIO) {\r
+                                       fprintf(mpd, "   <AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\"/>\n", comp->channels);\r
+                               }\r
+                       }\r
+               }\r
+               if (first_rep->nb_components>1) {\r
+                       for (i=0; i<first_rep->nb_components; i++) {\r
+                               struct _dash_component *comp = &first_rep->components[i];\r
+\r
+                               fprintf(mpd, "   <ContentComponent id=\"%d\" ", comp->ID);\r
+                               switch (comp->media_type ) {\r
+                               case GF_ISOM_MEDIA_TEXT:\r
+                                       fprintf(mpd, "contentType=\"text\" ");\r
+                                       break;\r
+                               case GF_ISOM_MEDIA_VISUAL:\r
+                                       fprintf(mpd, "contentType=\"video\" ");\r
+                                       break;\r
+                               case GF_ISOM_MEDIA_AUDIO:\r
+                                       fprintf(mpd, "contentType=\"audio\" ");\r
+                                       break;\r
+                               case GF_ISOM_MEDIA_SCENE:\r
+                               case GF_ISOM_MEDIA_DIMS:\r
+                               default:\r
+                                       fprintf(mpd, "contentType=\"application\" ");\r
+                                       break;\r
+                               }\r
+                               /*if lang not specified at adaptationSet level, put it here*/\r
+                               if ((!szLang || !szLang[0]) && comp->szLang[0]) {\r
+                                       fprintf(mpd, " lang=\"%s\"", langCode);\r
+                               }\r
+                               fprintf(mpd, "/>\n");\r
+                       }\r
+               }\r
+\r
+               if (bitstream_switching_mode && !use_url_template && (single_file_mode!=1) && strlen(szInitSegment) ) {\r
+                       fprintf(mpd, "   <SegmentList>\n");     \r
+                       fprintf(mpd, "    <Initialization sourceURL=\"%s\"/>\n", gf_url_get_resource_name( szInitSegment ));    \r
+                       fprintf(mpd, "   </SegmentList>\n");    \r
+               }\r
+       }\r
+       return GF_OK;\r
+}\r
+\r
+static GF_Err gf_dasher_init_context(GF_Config *dash_ctx, Bool *dynamic, u32 *timeShiftBufferDepth, const char *periodID)\r
+{\r
+       const char *opt;\r
+       char szVal[100];\r
+       Bool first_run = 0;\r
+       u32 sec, frac;\r
+#ifndef _WIN32_WCE\r
+               time_t gtime;\r
+#endif\r
+\r
+       if (!dash_ctx) return GF_BAD_PARAM;\r
+       \r
+       opt = gf_cfg_get_key(dash_ctx, "DASH", "SessionType");\r
+       /*first run, init all options*/\r
+       if (!opt) {\r
+               first_run = 1;\r
+               sprintf(szVal, "%d", *timeShiftBufferDepth);\r
+               gf_cfg_set_key(dash_ctx, "DASH", "SessionType", *dynamic ? "dynamic" : "static");\r
+               gf_cfg_set_key(dash_ctx, "DASH", "TimeShiftBufferDepth", szVal);\r
+               gf_cfg_set_key(dash_ctx, "DASH", "StoreParams", "yes");\r
+       } else {\r
+               *dynamic = !strcmp(opt, "dynamic") ? 1 : 0;\r
+               opt = gf_cfg_get_key(dash_ctx, "DASH", "TimeShiftBufferDepth");\r
+               *timeShiftBufferDepth = atoi(opt);\r
+               gf_cfg_set_key(dash_ctx, "DASH", "StoreParams", "no");\r
+       }\r
+\r
+       gf_cfg_set_key(dash_ctx, "DASH", "PeriodSwitch", "no");\r
+       \r
+       gf_net_get_ntp(&sec, &frac);\r
+       if (first_run) {\r
+#ifndef _WIN32_WCE\r
+               gtime = sec - GF_NTP_SEC_1900_TO_1970;\r
+               gf_cfg_set_key(dash_ctx, "DASH", "GenerationTime", asctime(gmtime(&gtime)));\r
+#endif\r
+               sprintf(szVal, "%u", sec);\r
+               gf_cfg_set_key(dash_ctx, "DASH", "GenerationNTP", szVal);\r
+               sprintf(szVal, "%u", frac);\r
+               gf_cfg_set_key(dash_ctx, "DASH", "GenerationNTPFraction", szVal);\r
+       \r
+               if (periodID)\r
+                       gf_cfg_set_key(dash_ctx, "DASH", "PeriodID", periodID);\r
+       } else {\r
+\r
+               /*check if we change period*/\r
+               if (periodID) {\r
+                       opt = gf_cfg_get_key(dash_ctx, "DASH", "PeriodID");\r
+                       if (!opt || strcmp(opt, periodID)) {\r
+                               gf_cfg_set_key(dash_ctx, "DASH", "PeriodID", periodID);\r
+                               gf_cfg_set_key(dash_ctx, "DASH", "PeriodSwitch", "yes");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /*perform cleanup of previous representations*/\r
+\r
+       return GF_OK;\r
+}\r
+\r
+GF_EXPORT\r
+u32 gf_dasher_next_update_time(GF_Config *dash_ctx, u32 mpd_update_time)\r
+{\r
+       Double max_dur = 0;\r
+       Double safety_dur;\r
+       Double ms_ellapsed;\r
+       u32 i, ntp_sec, frac, prev_sec, prev_frac;\r
+       const char *opt, *section;\r
+\r
+       opt = gf_cfg_get_key(dash_ctx, "DASH", "MaxSegmentDuration");\r
+       if (!opt) return 0;\r
+\r
+       safety_dur = atof(opt);\r
+       if (safety_dur > (Double) mpd_update_time)\r
+               safety_dur = (Double) mpd_update_time;\r
+\r
+\r
+       opt = gf_cfg_get_key(dash_ctx, "DASH", "GenerationNTP");\r
+       sscanf(opt, "%u", &prev_sec);\r
+       opt = gf_cfg_get_key(dash_ctx, "DASH", "GenerationNTPFraction");\r
+       sscanf(opt, "%u", &prev_frac);\r
+\r
+       /*compute cumulated duration*/\r
+       for (i=0; i<gf_cfg_get_section_count(dash_ctx); i++) {\r
+               Double dur = 0;\r
+               section = gf_cfg_get_section_name(dash_ctx, i);\r
+               if (section && !strncmp(section, "Representation_", 15)) {\r
+                       opt = gf_cfg_get_key(dash_ctx, section, "CumulatedDuration");\r
+                       if (opt) dur = atof(opt);\r
+                       if (dur>max_dur) max_dur = dur;\r
+               }\r
+       }\r
+\r
+       if (!max_dur) return 0;\r
+       gf_net_get_ntp(&ntp_sec, &frac);\r
+\r
+       ms_ellapsed = frac;\r
+       ms_ellapsed -= prev_frac;\r
+       ms_ellapsed /= 0xFFFFFFFF;\r
+       ms_ellapsed *= 1000;\r
+       ms_ellapsed += (ntp_sec - prev_sec)*1000;\r
+\r
+       /*check if we need to generate */\r
+       if (ms_ellapsed < (max_dur - safety_dur)*1000 ) {\r
+               return (u32) (1000*max_dur - ms_ellapsed);\r
+       }\r
+       return 0;\r
+}\r
+\r
+/*peform all file cleanup*/\r
+static Bool gf_dasher_cleanup(GF_Config *dash_ctx, Bool dash_dynamic, u32 mpd_update_time, u32 time_shift_depth, Double dash_duration)\r
+{\r
+       Double max_dur = 0;\r
+       Double ellapsed = 0;\r
+       Double safety_dur = MAX(mpd_update_time, (u32) dash_duration);\r
+       u32 i, ntp_sec, frac, prev_sec;\r
+       const char *opt, *section;\r
+       GF_Err e;\r
+\r
+       opt = gf_cfg_get_key(dash_ctx, "DASH", "StoreParams");\r
+       if (opt && !strcmp(opt, "yes")) return 1;\r
+\r
+       opt = gf_cfg_get_key(dash_ctx, "DASH", "GenerationNTP");\r
+       if (!opt) return 1;\r
+       sscanf(opt, "%u", &prev_sec);\r
+\r
+       /*compute cumulated duration*/\r
+       for (i=0; i<gf_cfg_get_section_count(dash_ctx); i++) {\r
+               Double dur = 0;\r
+               section = gf_cfg_get_section_name(dash_ctx, i);\r
+               if (section && !strncmp(section, "Representation_", 15)) {\r
+                       opt = gf_cfg_get_key(dash_ctx, section, "CumulatedDuration");\r
+                       if (opt) dur = atof(opt);\r
+                       if (dur>max_dur) max_dur = dur;\r
+               }\r
+       }\r
+       if (!max_dur) return 1;\r
+       gf_net_get_ntp(&ntp_sec, &frac);\r
+\r
+       ellapsed = ntp_sec;\r
+       ellapsed -= prev_sec;\r
+       /*check if we need to generate */\r
+       if (ellapsed < max_dur - safety_dur ) {\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DASH] Asked to regenerate segments before expiration of the current segment list, please wait %g seconds - ignoring\n", max_dur + prev_sec - ntp_sec ));\r
+               return 0;\r
+       }\r
+       if (ellapsed > max_dur) {\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Generating segments and MPD %g seconds too late\n", ellapsed - (u32) max_dur));\r
+       } else {\r
+               /*generate as if max_dur has been reached*/\r
+               ellapsed = max_dur;\r
+       }\r
+\r
+       /*cleanup old segments*/\r
+       if ((s32) time_shift_depth >= 0) {\r
+               for (i=0; i<gf_cfg_get_key_count(dash_ctx, "SegmentsStartTimes"); i++) {\r
+                       Double seg_time;\r
+                       Bool found=0;\r
+                       u32 j;\r
+                       const char *fileName = gf_cfg_get_key_name(dash_ctx, "SegmentsStartTimes", i);\r
+                       const char *MPDTime = gf_cfg_get_key(dash_ctx, "SegmentsStartTimes", fileName);\r
+                       if (!fileName) \r
+                               break;\r
+\r
+                       seg_time = atof(MPDTime);\r
+                       if (seg_time + dash_duration + time_shift_depth >= ellapsed )\r
+                               break;\r
+\r
+                       e = gf_delete_file(fileName);\r
+                       if (e) {\r
+                               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Could not remove file %s: %s\n", fileName, gf_error_to_string(e) ));\r
+                               break;\r
+                       }\r
+\r
+                       /*check all reps*/\r
+                       for (j=0; j<gf_cfg_get_section_count(dash_ctx); j++) {\r
+                               u32 k;\r
+                               const char *secName = gf_cfg_get_section_name(dash_ctx, j);\r
+                               if (!strstr(secName, "URLs_")) continue;\r
+                               for (k=0; k<gf_cfg_get_key_count(dash_ctx, secName); k++) {\r
+                                       const char *entry = gf_cfg_get_key_name(dash_ctx, secName, k);\r
+                                       const char *name = gf_cfg_get_key(dash_ctx, secName, entry);\r
+                                       if (strstr(name, fileName)) {\r
+                                               gf_cfg_set_key(dash_ctx, secName, entry, NULL);\r
+                                               found=1;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if (found) break;\r
+                       }\r
+\r
+                       gf_cfg_set_key(dash_ctx, "SegmentsStartTimes", fileName, NULL);\r
+                       i--;\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
+\r
+/*dash segmenter*/\r
+GF_EXPORT\r
+GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *inputs, u32 nb_dash_inputs, GF_DashProfile dash_profile, \r
+                                                          const char *mpd_title, const char *mpd_source, const char *mpd_copyright,\r
+                                                          const char *mpd_moreInfoURL, const char **mpd_base_urls, u32 nb_mpd_base_urls, \r
+                                                          Bool use_url_template, Bool single_segment, Bool single_file, Bool bitstream_switching_mode, \r
+                                                          Bool seg_at_rap, Double dash_duration, char *seg_name, char *seg_ext,\r
+                                                          Double frag_duration, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool frag_at_rap, const char *tmpdir,\r
+                                                          GF_Config *dash_ctx, Bool dash_dynamic, u32 mpd_update_time, u32 time_shift_depth, Double subduration)\r
+{\r
+       u32 i, j, segment_mode;\r
+       char *sep, szSegName[GF_MAX_PATH], szSolvedSegName[GF_MAX_PATH], szTempMPD[GF_MAX_PATH];\r
+       u32 cur_adaptation_set;\r
+       u32 max_adaptation_set = 0;\r
+       u32 cur_period;\r
+       u32 max_period = 0;\r
+       u32 cur_group_id = 0;\r
+       u32 max_sap_type = 0;\r
+       Bool none_supported = 1;\r
+       Bool has_mpeg2 = 0;\r
+       Double presentation_duration = 0;\r
+       GF_Err e = GF_OK;\r
+       FILE *mpd = NULL;\r
+       GF_DashSegInput *dash_inputs;\r
+       GF_DASHSegmenterOptions dash_opts;\r
+\r
+       /*init dash context if needed*/\r
+       if (dash_ctx) {\r
+\r
+               e = gf_dasher_init_context(dash_ctx, &dash_dynamic, &time_shift_depth, NULL);\r
+               if (e) return e;\r
+               if (dash_ctx) {\r
+                       Bool regenerate;\r
+                       const char *opt = gf_cfg_get_key(dash_ctx, "DASH", "MaxSegmentDuration");\r
+                       if (opt) {\r
+                               Double seg_dur = atof(opt);\r
+                               if (seg_dur != dash_duration) {\r
+                                       gf_cfg_del(dash_ctx);\r
+                                       return GF_NOT_SUPPORTED;\r
+                               }\r
+                       } else {\r
+                               char sOpt[100];\r
+                               sprintf(sOpt, "%f", dash_duration);\r
+                               gf_cfg_set_key(dash_ctx, "DASH", "MaxSegmentDuration", sOpt);\r
+                       }\r
+\r
+                       /*peform all file cleanup*/\r
+                       regenerate = gf_dasher_cleanup(dash_ctx, dash_dynamic, mpd_update_time, time_shift_depth, dash_duration);\r
+                       if (!regenerate) return GF_OK;\r
+               }\r
+       }\r
+\r
+       /*copy over input files to our internal structure*/\r
+       max_period = 0;\r
+       dash_inputs = gf_malloc(sizeof(GF_DashSegInput)*nb_dash_inputs);\r
+       memset(dash_inputs, 0, sizeof(GF_DashSegInput)*nb_dash_inputs);\r
+       for (i=0; i<nb_dash_inputs; i++) {\r
+               dash_inputs[i].file_name = inputs[i].file_name;\r
+               strcpy(dash_inputs[i].representationID, inputs[i].representationID);\r
+               strcpy(dash_inputs[i].periodID, inputs[i].periodID);\r
+               dash_inputs[i].bandwidth = inputs[i].bandwidth;\r
+\r
+               if (!strlen(dash_inputs[i].periodID)) {\r
+                       max_period = 1;\r
+                       dash_inputs[i].period = 1;\r
+                       if (dash_dynamic) {\r
+                               strcpy(dash_inputs[i].periodID, "GENID_DEF");\r
+                       }\r
+               }\r
+               gf_dash_segmenter_probe_input(&dash_inputs[i]);\r
+\r
+               if (!strcmp(dash_inputs[i].szMime, "video/mp2t")) has_mpeg2 = 1;\r
+       }\r
+       memset(&dash_opts, 0, sizeof(GF_DASHSegmenterOptions));\r
+\r
+       for (i=0; i<nb_dash_inputs; i++) {\r
+               if (dash_inputs[i].period) \r
+                       continue;\r
+               if (strlen(dash_inputs[i].periodID)) {\r
+                       max_period++;\r
+                       dash_inputs[i].period = max_period;\r
+\r
+                       for (j=i+1; j<nb_dash_inputs; j++) {\r
+                               if (!strcmp(dash_inputs[j].periodID, dash_inputs[i].periodID))\r
+                                       dash_inputs[j].period = dash_inputs[i].period;\r
+                       }\r
+               }\r
+       }\r
+       if (dash_dynamic && max_period>1) {\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Multiple periods in live mode not supported\n"));\r
+               return GF_NOT_SUPPORTED;\r
+       }\r
+\r
+       for (cur_period=0; cur_period<max_period; cur_period++) {\r
+               /*classify all input in possible adaptation sets*/\r
+               for (i=0; i<nb_dash_inputs; i++) {\r
+                       /*this file does not belong to our current period*/\r
+                       if (dash_inputs[i].period != cur_period+1) continue;\r
+                       \r
+                       /*this file already belongs to an adaptation set*/\r
+                       if (dash_inputs[i].adaptation_set) continue;\r
+\r
+                       /*we cannot fragment the input file*/\r
+                       if (!dash_inputs[i].dasher_input_classify || !dash_inputs[i].dasher_segment_file) {\r
+                               continue;\r
+                       }\r
+\r
+                       max_adaptation_set ++;\r
+                       dash_inputs[i].adaptation_set = max_adaptation_set;\r
+                       dash_inputs[i].nb_rep_in_adaptation_set = 1;\r
+\r
+                       e = dash_inputs[i].dasher_input_classify(dash_inputs, nb_dash_inputs, i, &cur_group_id, &max_sap_type);\r
+                       if (e) goto exit;\r
+                       none_supported = 0;\r
+               }\r
+               if (none_supported) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH]: None of the input types are supported for DASHing - nothing to do ...\n"));\r
+                       return GF_OK;\r
+               }\r
+       }\r
+\r
+\r
+       /*check requested profiles can be generated, or adjust them*/\r
+       if (max_sap_type>=3) {\r
+               if (dash_profile) {\r
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH]: WARNING! Max SAP type %d detected\n\tswitching to FULL profile\n", max_sap_type));\r
+               }\r
+               dash_profile = 0;\r
+       }\r
+       if ((dash_profile==GF_DASH_PROFILE_LIVE) && !seg_name) {\r
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH]: WARNING! DASH Live profile requested but no -segment-name\n\tusing \"%%s_dash\" by default\n\n"));\r
+               seg_name = "%s_dash";\r
+       }\r
+\r
+       /*if output id not in the current working dir, concatenate output path to segment name*/\r
+       szSegName[0] = 0;\r
+       if (seg_name) {\r
+               if (gf_url_get_resource_path(mpdfile, szSegName)) {\r
+                       strcat(szSegName, seg_name);\r
+                       seg_name = szSegName;\r
+               }\r
+       }\r
+\r
+\r
+       /*adjust params based on profiles*/\r
+       switch (dash_profile) {\r
+       case GF_DASH_PROFILE_LIVE:\r
+               seg_at_rap = 1;\r
+               use_url_template = 1;\r
+               single_segment = single_file = 0;\r
+               break;\r
+       case GF_DASH_PROFILE_ONDEMAND:\r
+               seg_at_rap = 1;\r
+               single_segment = 1;\r
+               /*BS switching is meaningless in onDemand profile*/\r
+               bitstream_switching_mode = 0;\r
+               use_url_template = single_file = 0;\r
+               break;\r
+       case GF_DASH_PROFILE_MAIN:\r
+               seg_at_rap = 1;\r
+               single_segment = 0;\r
+               break;\r
+       default:\r
+               break;\r
+       }\r
+\r
+       segment_mode = single_segment ? 1 : (single_file ? 2 : 0);\r
+\r
+       if (single_segment) {\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("DASH-ing file%s - single segment\nSubsegment duration %.3f - Fragment duration: %.3f secs\n", (nb_dash_inputs>1) ? "s" : "", dash_duration, frag_duration));\r
+               subsegs_per_sidx = 0;\r
+       } else {\r
+               if (!seg_ext) seg_ext = "m4s";\r
+\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("DASH-ing file%s: %.2fs segments %.2fs fragments ", (nb_dash_inputs>1) ? "s" : "", dash_duration, frag_duration));\r
+               if (subsegs_per_sidx<0) {\r
+                       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("no sidx used"));\r
+               } else if (subsegs_per_sidx) {\r
+                       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("%d subsegments per sidx", subsegs_per_sidx));\r
+               } else {\r
+                       GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("single sidx per segment"));\r
+               }\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("\n"));\r
+       }\r
+       if (frag_at_rap) seg_at_rap = 1;\r
+\r
+       if (seg_at_rap) {\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Spliting segments %sat GOP boundaries\n", frag_at_rap ? "and fragments " : ""));\r
+       }\r
+\r
+\r
+       dash_opts.mpd_name = mpdfile;\r
+       dash_opts.segments_start_with_rap = seg_at_rap;\r
+       dash_opts.segment_duration = dash_duration;\r
+       dash_opts.seg_ext = seg_ext;\r
+       dash_opts.daisy_chain_sidx = daisy_chain_sidx;\r
+       dash_opts.subsegs_per_sidx = subsegs_per_sidx;\r
+       dash_opts.use_url_template = use_url_template;\r
+       dash_opts.single_file_mode = segment_mode;\r
+       dash_opts.fragments_start_with_rap = frag_at_rap;\r
+       dash_opts.fragment_duration = frag_duration;\r
+       dash_opts.tmpdir = tmpdir;\r
+       dash_opts.dash_ctx = dash_ctx;\r
+       dash_opts.time_shift_depth = (s32) time_shift_depth;\r
+       dash_opts.subduration = subduration;\r
+\r
+       for (cur_period=0; cur_period<max_period; cur_period++) {\r
+               u32 first_in_period = 0;\r
+               Double period_duration=0;\r
+               for (i=0; i<nb_dash_inputs; i++) {\r
+                       /*this file does not belongs to any adaptation set*/\r
+                       if (dash_inputs[i].period != cur_period+1) continue;\r
+\r
+                       /*this file does not belongs to any adaptation set*/\r
+                       if (!dash_inputs[i].adaptation_set) continue;\r
+\r
+                       if (!first_in_period) {\r
+                               first_in_period = i+1;\r
+                       }\r
+\r
+                       if (dash_inputs[i].dasher_get_components_info) {\r
+                               e = dash_inputs[i].dasher_get_components_info(&dash_inputs[i], &dash_opts);\r
+                               if (e) goto exit;\r
+                       }\r
+                       if (dash_inputs[i].duration > period_duration)\r
+                               period_duration = dash_inputs[i].duration;\r
+               }\r
+               if (first_in_period)\r
+                       dash_inputs[first_in_period-1].period_duration = period_duration;\r
+\r
+               presentation_duration += period_duration;\r
+       }\r
+\r
+       strcpy(szTempMPD, mpdfile);\r
+       if (dash_dynamic) strcat(szTempMPD, ".tmp");\r
+       \r
+       mpd = gf_f64_open(mpdfile, "wt");\r
+       if (!mpd) {\r
+               GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[MPD] Cannot open MPD file %s for writing\n", szTempMPD));\r
+               return GF_IO_ERR;\r
+       }\r
+\r
+       dash_opts.mpd = mpd;\r
+\r
+       e = write_mpd_header(mpd, mpdfile, dash_ctx, dash_profile, has_mpeg2, mpd_title, mpd_source, mpd_copyright, mpd_moreInfoURL, (const char **) mpd_base_urls, nb_mpd_base_urls, dash_dynamic, time_shift_depth, presentation_duration, mpd_update_time);\r
+       if (e) goto exit;\r
+\r
+       for (cur_period=0; cur_period<max_period; cur_period++) {\r
+               Double period_duration = 0;\r
+               const char *id=NULL;\r
+               /*for each identified adaptationSets, write MPD and perform segmentation of input files*/\r
+               for (i=0; i< nb_dash_inputs; i++) {\r
+                       if (dash_inputs[i].adaptation_set && (dash_inputs[i].period==cur_period+1)) {\r
+                               period_duration = dash_inputs[i].period_duration;\r
+                               id = dash_inputs[i].periodID;\r
+                               break;\r
+                       }\r
+               }\r
+               e = write_period_header(mpd, id, 0.0, period_duration, dash_dynamic);\r
+               if (e) goto exit;\r
+\r
+               /*for each identified adaptationSets, write MPD and perform segmentation of input files*/\r
+               for (cur_adaptation_set=0; cur_adaptation_set < max_adaptation_set; cur_adaptation_set++) {\r
+                       char szInit[GF_MAX_PATH], tmp[GF_MAX_PATH];\r
+                       u32 first_rep_in_set=0;\r
+                       u32 max_width = 0;\r
+                       u32 max_height = 0;\r
+                       u32 fps_num = 0;\r
+                       u32 fps_denum = 0;\r
+                       Bool use_bs_switching = bitstream_switching_mode ? 1 : 0;\r
+                       char szLang[4];\r
+                       char szFPS[100];\r
+                       Bool is_first_rep=0;\r
+                       Bool skip_init_segment_creation = 0;\r
+\r
+                       while (dash_inputs[first_rep_in_set].adaptation_set!=cur_adaptation_set+1)\r
+                               first_rep_in_set++;\r
+\r
+                       /*not in our period*/\r
+                       if (dash_inputs[first_rep_in_set].period != cur_period+1)\r
+                               continue;\r
+\r
+                       strcpy(tmp, mpdfile);\r
+                       sep = strrchr(tmp, '.');\r
+                       if (sep) sep[0] = 0;\r
+\r
+                       if (max_adaptation_set==1) {\r
+                               strcpy(szInit, tmp);\r
+                               strcat(szInit, "_init.mp4");\r
+                       } else {\r
+                               sprintf(szInit, "%s_set%d_init.mp4", tmp, cur_adaptation_set+1);\r
+                       }\r
+                       if ((bitstream_switching_mode==1) && dash_inputs[first_rep_in_set].nb_rep_in_adaptation_set==1)\r
+                               use_bs_switching = 0;\r
+\r
+                       if (! use_bs_switching) {\r
+                               skip_init_segment_creation = 1;\r
+                       }\r
+                       else if (! dash_inputs[first_rep_in_set].dasher_create_init_segment) {\r
+                               skip_init_segment_creation = 1;\r
+                               strcpy(szInit, "");\r
+                       }\r
+                       /*if we already wrote the InitializationSegment, get rid of it (no overwrite) and let the dashing routine open it*/\r
+                       else if (dash_ctx) {\r
+                               char RepSecName[GF_MAX_PATH];\r
+                               const char *init_seg_name;\r
+                               sprintf(RepSecName, "Representation_%s", dash_inputs[first_rep_in_set].representationID);\r
+                               if ((init_seg_name = gf_cfg_get_key(dash_ctx, RepSecName, "InitializationSegment")) != NULL) {\r
+                                       skip_init_segment_creation = 1;\r
+                               }\r
+                       }\r
+\r
+                       if (!skip_init_segment_creation) {\r
+                               Bool disable_bs_switching = 0;\r
+                               e = dash_inputs[first_rep_in_set].dasher_create_init_segment(dash_inputs, nb_dash_inputs, cur_adaptation_set+1, szInit, tmpdir, &disable_bs_switching);\r
+                               if (e) goto exit;\r
+                               if (disable_bs_switching)\r
+                                       use_bs_switching = 0;\r
+                       }\r
+\r
+                       dash_opts.bs_switch_segment_file = use_bs_switching ? szInit : NULL;\r
+                       dash_opts.use_url_template = seg_name ? use_url_template : 0;\r
+\r
+                       szFPS[0] = 0;\r
+                       szLang[0] = 0;\r
+                       /*compute some max defaults*/\r
+                       for (i=0; i<nb_dash_inputs && !e; i++) {\r
+\r
+                               if (dash_inputs[i].adaptation_set!=cur_adaptation_set+1)\r
+                                       continue;\r
+\r
+                               for (j=0; j<dash_inputs[i].nb_components; j++) {\r
+                                       if (dash_inputs[i].components[j].width > max_width) \r
+                                               max_width = dash_inputs[i].components[j].width;\r
+                                       if (dash_inputs[i].components[j].height > max_height) \r
+                                               max_height = dash_inputs[i].components[j].height;\r
+\r
+                                       if (! fps_num || !fps_denum) {\r
+                                               fps_num = dash_inputs[i].components[j].fps_num;\r
+                                               fps_denum = dash_inputs[i].components[j].fps_denum;\r
+                                       }\r
+                                       else if (fps_num * dash_inputs[i].components[j].fps_denum < dash_inputs[i].components[j].fps_num * fps_denum) {\r
+                                               fps_num = dash_inputs[i].components[j].fps_num;\r
+                                               fps_denum = dash_inputs[i].components[j].fps_denum;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       if (max_width && max_height) {\r
+                               gf_media_get_reduced_frame_rate(&fps_num, &fps_denum);\r
+                               if (fps_denum>1) \r
+                                       sprintf(szFPS, "%d/%d", fps_num, fps_denum);\r
+                               else if (fps_num)\r
+                                       sprintf(szFPS, "%d", fps_num);\r
+                       }\r
+\r
+                       e = write_adaptation_header(mpd, dash_profile, use_url_template, segment_mode, &dash_inputs[first_rep_in_set], use_bs_switching, max_width, max_height, szFPS, szLang, szInit);\r
+                       if (e) goto exit;\r
+\r
+                       is_first_rep = 1;\r
+                       for (i=0; i<nb_dash_inputs && !e; i++) {\r
+                               char szOutName[GF_MAX_PATH], *segment_name;\r
+\r
+                               if (dash_inputs[i].adaptation_set!=cur_adaptation_set+1)\r
+                                       continue;\r
+\r
+                               segment_name = seg_name;\r
+\r
+                               strcpy(szOutName, gf_url_get_resource_name(dash_inputs[i].file_name));\r
+                               sep = strrchr(szOutName, '.');\r
+                               if (sep) sep[0] = 0;\r
+\r
+                               dash_opts.variable_seg_rad_name = 0;\r
+                               if (seg_name) {\r
+                                       if (strstr(seg_name, "%s")) {\r
+                                               sprintf(szSolvedSegName, seg_name, szOutName);\r
+                                               dash_opts.variable_seg_rad_name = 1;\r
+                                       } else {\r
+                                               strcpy(szSolvedSegName, seg_name);\r
+                                       }\r
+                                       segment_name = szSolvedSegName;\r
+                               }\r
+                               strcat(szOutName, "_dash");\r
+\r
+                               if (gf_url_get_resource_path(mpdfile, tmp)) {\r
+                                       strcat(tmp, szOutName);\r
+                                       strcpy(szOutName, tmp);\r
+                               }\r
+                               dash_opts.seg_rad_name = segment_name;\r
+\r
+                               GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("DASHing file %s\n", dash_inputs[i].file_name));\r
+                               e = dash_inputs[i].dasher_segment_file(&dash_inputs[i], szOutName, &dash_opts, is_first_rep);\r
+\r
+                               if (e) {\r
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while DASH-ing file: %s\n", gf_error_to_string(e)));\r
+                                       goto exit;\r
+                               }\r
+                               is_first_rep = 0;\r
+                       }\r
+                       /*close adaptation set*/\r
+                       fprintf(mpd, "  </AdaptationSet>\n");\r
+               }\r
+\r
+               fprintf(mpd, " </Period>\n");\r
+       }\r
+       fprintf(mpd, "</MPD>");\r
+\r
+exit:\r
+\r
+       if (mpd) {\r
+               fclose(mpd);\r
+               if (!e && dash_dynamic)\r
+                       gf_move_file(szTempMPD, mpdfile);\r
+       }\r
+       return e;\r
+}\r
+\r
+\r
+\r
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS\r
+GF_EXPORT\r
+GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, Double max_duration_sec)\r
+{\r
+       return gf_media_isom_segment_file(input, output_file, max_duration_sec, NULL, NULL, 0);\r
+}\r
+\r
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/\r
+\r
+\r
index ed764fb5deafee051fd5b2d91d08e10f7dffb207..614d9fa67876117abfcb8fdc991fbb50ca860baf 100644 (file)
@@ -1,12 +1,34 @@
-/* \r
- * Copyright (c) TELECOM ParisTech 2011\r
+/*\r
+ *                     GPAC - Multimedia Framework C SDK\r
+ *\r
+ *                     Authors: Jonathan Sillan\r
+ *                     Copyright (c) Telecom ParisTech 2011-2012\r
+ *                                     All rights reserved\r
+ *\r
+ *  This file is part of GPAC / media tools sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
  */\r
 \r
+\r
 #include <gpac/dsmcc.h>\r
 \r
-#ifndef GPAC_DISABLE_MPEG2TS\r
-/* DSMCC */\r
+#ifdef GPAC_ENABLE_DSMCC\r
 \r
+/* DSMCC */\r
 \r
 \r
 /* static functions */\r
@@ -150,8 +172,8 @@ GF_Err gf_m2ts_process_dsmcc(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMC
        }\r
        *first_section_received = 1;*/\r
        dsmcc->last_section_number = gf_bs_read_int(bs,8);      \r
-       //printf("\nsection_number %d last_section_number %d\n",dsmcc->section_number,dsmcc->last_section_number);\r
-       //printf("dsmcc->table_id %d \n",dsmcc->table_id);\r
+       //fprintf(stderr, "\nsection_number %d last_section_number %d\n",dsmcc->section_number,dsmcc->last_section_number);\r
+       //fprintf(stderr, "dsmcc->table_id %d \n",dsmcc->table_id);\r
        switch (dsmcc->table_id) {\r
                case GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA:\r
                        {\r
@@ -205,7 +227,7 @@ static GF_Err gf_m2ts_dsmcc_download_data(GF_M2TS_DSMCC_OVERLORD *dsmcc_overlord
        gf_m2ts_dsmcc_process_message_header(&DataMessage->DownloadDataHeader,data,bs,data_shift,1);\r
        dsmcc->DSMCC_Extension = DataMessage;\r
 \r
-       //printf("DataMessage->DownloadDataHeader.messageId %d \n",DataMessage->DownloadDataHeader.messageId);\r
+       //fprintf(stderr, "DataMessage->DownloadDataHeader.messageId %d \n",DataMessage->DownloadDataHeader.messageId);\r
 \r
        switch (DataMessage->DownloadDataHeader.messageId)\r
        {\r
@@ -292,7 +314,7 @@ static GF_Err gf_m2ts_dsmcc_download_data(GF_M2TS_DSMCC_OVERLORD *dsmcc_overlord
 \r
 \r
                        DownloadDataBlock->moduleId = gf_bs_read_int(bs,16);\r
-                       //printf("DownloadDataBlock->moduleId %d \n",DownloadDataBlock->moduleId);\r
+                       //fprintf(stderr, "DownloadDataBlock->moduleId %d \n",DownloadDataBlock->moduleId);\r
                        DownloadDataBlock->moduleVersion = gf_bs_read_int(bs,8); \r
                        DownloadDataBlock->reserved = gf_bs_read_int(bs,8);\r
                        if(DownloadDataBlock->reserved != 0xFF){\r
@@ -305,7 +327,7 @@ static GF_Err gf_m2ts_dsmcc_download_data(GF_M2TS_DSMCC_OVERLORD *dsmcc_overlord
                                GF_M2TS_DSMCC_MODULE* dsmcc_module = gf_list_get(dsmcc_overlord->dsmcc_modules,i);\r
                                /* Test if the data are compatible with the module configuration */\r
                                if(!dsmcc_download_data_validation(dsmcc_overlord,DownloadDataBlock,dsmcc_module,DataMessage->DownloadDataHeader.downloadId)){\r
-                                       //printf("DownloadDataBlock->blockNumber %d \n\n",DownloadDataBlock->blockNumber);\r
+                                       //fprintf(stderr, "DownloadDataBlock->blockNumber %d \n\n",DownloadDataBlock->blockNumber);\r
                                        DownloadDataBlock->dataBlocksize = (DataMessage->DownloadDataHeader.messageLength - 6);                                 \r
                                        if(dsmcc_module->block_size < DownloadDataBlock->dataBlocksize){\r
                                                GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error block_size should be >= to DownloadDataBlock->dataBlocksize , abording the processing \n"));\r
@@ -447,7 +469,7 @@ static GF_Err gf_m2ts_dsmcc_process_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HE
        } else if (mode == 1) {\r
                MessageHeader->downloadId = gf_bs_read_int(bs,32);\r
        }\r
-       //printf("MessageHeader->downloadId %d \n",MessageHeader->downloadId);\r
+       //fprintf(stderr, "MessageHeader->downloadId %d \n",MessageHeader->downloadId);\r
        MessageHeader->reserved = gf_bs_read_int(bs,8);\r
        if (MessageHeader->reserved != 0xFF) {\r
                GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] DataHeader reserved slot does not have the correct value, abording the processing \n"));\r
@@ -1915,4 +1937,4 @@ static void dsmcc_free_biop_context(GF_M2TS_DSMCC_SERVICE_CONTEXT* Context,u32 s
        gf_free(Context);\r
 }\r
 \r
-#endif //GPAC_DISABLE_MPEG2TS
\ No newline at end of file
+#endif //GPAC_ENABLE_DSMCC\r
index 1882d24eef75029c7873b026402e20fed87ab8ee..7ef620e7e3823223402b4cdd665af97c44408e02 100644 (file)
@@ -3,8 +3,7 @@
 #include <string.h>
 
 
-#ifndef GPAC_DISABLE_MPEG2TS
-
+#ifdef GPAC_ENABLE_MPE
 
 static void gf_m2ts_Delete_IpPacket(GF_M2TS_IP_Packet *ip_packet);
 
@@ -45,7 +44,7 @@ static void on_dvb_mpe_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
                                gf_m2ts_process_mpe(ts, mpe, data, u32_data_size, u32_table_id);
                        }
                        else {
-                               //printf("Time Slice Parameters for MPE-FEC have not been found yet \n");
+                               //fprintf(stderr, "Time Slice Parameters for MPE-FEC have not been found yet \n");
                        }
                        break;                          
                default:
@@ -142,16 +141,16 @@ void gf_dvb_mpe_section_del(GF_M2TS_ES *es)
        u32 i;
        for (i = 0; i < length; i ++) {
                if (i%line_length == 0) { 
-                       printf("%2d: ", i/line_length); 
+                       fprintf(stderr, "%2d: ", i/line_length); 
                } else if (i%8 == 0) {
-                       printf(" "); 
+                       fprintf(stderr, " "); 
                }
-               printf("%02x", data[i]);
+               fprintf(stderr, "%02x", data[i]);
                if ((i+1)%line_length == 0) { 
-                       printf("\n"); 
+                       fprintf(stderr, "\n"); 
                }
        }
-       if (last_line) printf("\n"); 
+       if (last_line) fprintf(stderr, "\n"); 
 }
 */
 
@@ -170,7 +169,7 @@ void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_MPE *mpe, unsigned
 
        i_streams = 0;
 
-//     printf("Processing MPE/MPE-FEC data PID %d (%d/%d)\n",mpe->pid, data[6],data[7]);
+//     fprintf(stderr, "Processing MPE/MPE-FEC data PID %d (%d/%d)\n",mpe->pid, data[6],data[7]);
        
        if (!gf_m2ts_crc32_check(data, data_size - 4)) {
                 GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("CRC error in the MPE/MPE-FEC data \n"));
@@ -179,12 +178,12 @@ void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_MPE *mpe, unsigned
        /*get number of rows of mpe_fec_frame from descriptor*/
        section_number = data[6];               
        last_section_number = data[7];
-       //printf( "table_id: %x section_length: %d section_number: %d last : %d \n", data[0], (data[1] & 0xF)<<8|data[2], section_number, last_section_number); 
+       //fprintf(stderr,  "table_id: %x section_length: %d section_number: %d last : %d \n", data[0], (data[1] & 0xF)<<8|data[2], section_number, last_section_number);        
        
        if (ts->direct_mpe) {
                if (table_id != GF_M2TS_TABLE_ID_DSM_CC_PRIVATE) return;
                if (section_number != last_section_number) {
-                       fprintf(stdout, "MPE IP datagram on several section not supported\n");
+                       fprintf(stderr, "MPE IP datagram on several section not supported\n");
                        return;
                }
                /* send the IP data :
@@ -271,7 +270,7 @@ void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_MPE *mpe, unsigned
                        //data += (mff->rows +12+4 );
                        break;
                default:
-               //      printf ("Unknown table id %x \n", table_id );
+               //      fprintf(stderr, "Unknown table id %x \n", table_id );
                        len_left = 0; 
                }
                
@@ -350,13 +349,13 @@ void gf_m2ts_process_ipdatagram(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts)
                        socket_simu(ip_packet,ts, 1);
 
                        if(ip_packet->u8_rx_adr[3] == 8){
-                        printf("\n");
+                        fprintf(stderr, "\n");
                        }
 
                        /* compare the destination ip adress and the ESG Bootstrap adress */
                        Boostrap_ip = gf_m2ts_compare_ip(ip_packet->u8_rx_adr,ip_adress_bootstrap);
                        if(Boostrap_ip){
-                               printf("ESG Bootstrap found !\n");              
+                               fprintf(stderr, "ESG Bootstrap found !\n");             
                        }                
                 }else{
                         offset += (ip_packet->u32_total_length);
@@ -470,7 +469,7 @@ u32 gf_m2ts_ipdatagram_reader(u8 *datagram,GF_M2TS_IP_Packet *ip_packet, u32 off
        /*ip_packet->data = gf_malloc((ip_packet->u32_total_length-ip_packet->u32_hdr_length)*sizeof(char));
        memcpy(ip_packet->data,datagram+offset+20,(ip_packet->u32_total_length-ip_packet->u32_hdr_length)*sizeof(char));*/
 
-       printf("TX addr: %d.%d.%d.%d RX addr : %d.%d.%d.%d port:%d(0x%x) \n",ip_packet->u8_tx_adr[0],ip_packet->u8_tx_adr[1],ip_packet->u8_tx_adr[2],ip_packet->u8_tx_adr[3],ip_packet->u8_rx_adr[0],ip_packet->u8_rx_adr[1],ip_packet->u8_rx_adr[2],ip_packet->u8_rx_adr[3],ip_packet->u32_rx_udp_port,ip_packet->u32_rx_udp_port);
+       fprintf(stderr, "TX addr: %d.%d.%d.%d RX addr : %d.%d.%d.%d port:%d(0x%x) \n",ip_packet->u8_tx_adr[0],ip_packet->u8_tx_adr[1],ip_packet->u8_tx_adr[2],ip_packet->u8_tx_adr[3],ip_packet->u8_rx_adr[0],ip_packet->u8_rx_adr[1],ip_packet->u8_rx_adr[2],ip_packet->u8_rx_adr[3],ip_packet->u32_rx_udp_port,ip_packet->u32_rx_udp_port);
 
        return 1;
 
@@ -506,17 +505,17 @@ void gf_m2ts_process_int(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ip_table, unsi
 
        GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform ; 
        assert( ts );
-//     fprintf(stdout, "Processing IP/MAC Notification table (PID %d) %s\n", ip_table->pid, (status==GF_M2TS_TABLE_REPEAT)?"repeated":"");
+//     fprintf(stderr, "Processing IP/MAC Notification table (PID %d) %s\n", ip_table->pid, (status==GF_M2TS_TABLE_REPEAT)?"repeated":"");
        //if ( status == GF_M2TS_TABLE_REPEAT ) return ; 
        if ( ip_platform == NULL ) 
        {
                GF_SAFEALLOC(ip_platform,GF_M2TS_IP_PLATFORM );
                ip_platform->ip_streams= gf_list_new();
-               //printf ( " \n initialize the Iip_platform \n");
+               //fprintf(stderr,  " \n initialize the Iip_platform \n");
                section_DSMCC_INT (ip_platform, data, data_size);
                ts->ip_platform = ip_platform;
        }
-       //printf ("processing the INT table \n");
+       //fprintf(stderr, "processing the INT table \n");
 
 
 
@@ -596,12 +595,12 @@ u32  platform_descriptorDSMCC_INT_UNT(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data
         
   case GF_M2TS_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR:
          {
-                 //printf (" Information on the ip platform found \n");
+                 //fprintf(stderr, " Information on the ip platform found \n");
                  gf_ip_platform_descriptor(ip_platform, data);
          }break;
   case GF_M2TS_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR:
          {
-                 //printf (" Information on the ip platform found \n");
+                 //fprintf(stderr, " Information on the ip platform found \n");
                  gf_ip_platform_provider_descriptor(ip_platform, data);
          }break; 
 
@@ -757,8 +756,8 @@ void encode_fec(MPE_FEC_FRAME * mff)
                /* ************** */
                /* Encode data into codeword, adding NPAR parity bytes */
                encode_data(adt_rs_en_buffer, cols, adt_rs_en_buffer);
-               printf("Encoded data is   : \"%s\"\n", adt_rs_en_buffer);
-               printf("data with error is: \"%s\"\n", adt_rs_en_buffer);
+               fprintf(stderr, "Encoded data is   : \"%s\"\n", adt_rs_en_buffer);
+               fprintf(stderr, "data with error is: \"%s\"\n", adt_rs_en_buffer);
                /*set a row of RS into RS table*/
                setRowRS ( mff, i , (unsigned char *)(adt_rs_en_buffer + cols) );
        }
@@ -772,7 +771,7 @@ void decode_fec(MPE_FEC_FRAME * mff)
        u8 *data;
        u8 linebuffer[255];
 
-       //printf("Starting FEC decoding ...\n");
+       //fprintf(stderr, "Starting FEC decoding ...\n");
        
        data = gf_malloc((mff->rows*191)*sizeof(char));
        memset(data,0,sizeof(data));
@@ -782,12 +781,12 @@ void decode_fec(MPE_FEC_FRAME * mff)
        memset(linebuffer, 0, 255);
        offset = 0;
 
-       /*printf("ADT data\n");
+       /*fprintf(stderr, "ADT data\n");
        print_bytes(mff->p_adt, 32, 1, 0);
        print_bytes(mff->p_adt+512, 32, 1, 0);
        print_bytes(mff->p_adt+512+512, 32, 1, 0);
        print_bytes(mff->p_adt+512+512+512, 32, 1, 1);
-       printf("RS data\n");
+       fprintf(stderr, "RS data\n");
        print_bytes(mff->p_rs, 32, 1, 0);
        print_bytes(mff->p_rs+512, 32, 1, 0);
        print_bytes(mff->p_rs+512+512, 32, 1, 0);
@@ -809,7 +808,7 @@ void decode_fec(MPE_FEC_FRAME * mff)
                        /* TODO: set the erasures and errors based on the MFF */
                        if(correct_errors_erasures (linebuffer, ML, nerasures,  erasures) == 0)
                        {
-                               //printf("Correction Error line %d \n", i);
+                               //fprintf(stderr, "Correction Error line %d \n", i);
                        }               
 
                        /* TODO: replace the current line in MFF */
@@ -818,7 +817,7 @@ void decode_fec(MPE_FEC_FRAME * mff)
        memcpy(data+offset,linebuffer,sizeof(data));
        offset += 191;
        }
-       //printf("FEC decoding done.\n");
+       //fprintf(stderr, "FEC decoding done.\n");
        memcpy(mff->p_adt,data,sizeof(data));
        //gf_m2ts_ipdatagram_reader(mff->p_adt,ip_datagram);
 
@@ -939,7 +938,7 @@ void gf_m2ts_print_mpe_info(GF_M2TS_Demuxer *ts)
        if (!ts->ip_platform) return;
 
        /* provider and ip platform name */
-       printf(" IP Platform : %s provided by %s \n",ip_platform->name,ip_platform->provider_name);
+       fprintf(stderr, " IP Platform : %s provided by %s \n",ip_platform->name,ip_platform->provider_name);
 
        i_streams = 0;
        i_targets = 0;
@@ -950,8 +949,8 @@ void gf_m2ts_print_mpe_info(GF_M2TS_Demuxer *ts)
        for(i=0;i<i_streams;i++)
        {
                ip_stream_buff=gf_list_get(ip_platform->ip_streams, i);
-               printf("PID:%d \n",ip_stream_buff->PID);
-               printf("Target IP Adress : \n");        
+               fprintf(stderr, "PID:%d \n",ip_stream_buff->PID);
+               fprintf(stderr, "Target IP Adress : \n");       
                /*Print the target IP adress  */
                i_targets = gf_list_count(ip_stream_buff->targets);
                for(j=0;j<i_targets;j++)
@@ -961,73 +960,73 @@ void gf_m2ts_print_mpe_info(GF_M2TS_Demuxer *ts)
                        l=0;
                                                
                        ip_adress = ip_targets->address;
-                       printf("%d.%d.%d.%d/%d ",ip_adress[0],ip_adress[1],ip_adress[2],ip_adress[3],ip_targets->slash_mask);
-                       printf("RX port :");
+                       fprintf(stderr, "%d.%d.%d.%d/%d ",ip_adress[0],ip_adress[1],ip_adress[2],ip_adress[3],ip_targets->slash_mask);
+                       fprintf(stderr, "RX port :");
                        while(ip_targets->rx_port[l] != 0)
                        {
-                               printf(" %d ",ip_targets->rx_port[l]);
+                               fprintf(stderr, " %d ",ip_targets->rx_port[l]);
                                l++;
                        }
-                       printf("\n");
+                       fprintf(stderr, "\n");
                        
                        
                }
 
                /*Print the time slice fec descriptor */
-               printf("Time Slice Fec Descriptor : \n");
+               fprintf(stderr, "Time Slice Fec Descriptor : \n");
 
                if(ip_stream_buff->time_slice_fec.time_slicing==0)
                {
-                       printf(" No Time Slicing \n");
+                       fprintf(stderr, " No Time Slicing \n");
                }else 
                {
-                               printf(" Time Slicing\n");
+                               fprintf(stderr, " Time Slicing\n");
                }
 
                if(ip_stream_buff->time_slice_fec.mpe_fec==0)
                {
-                       printf(" No MPE FEC used \n");
+                       fprintf(stderr, " No MPE FEC used \n");
                }else 
                {
-                               printf(" MPE FEC used \n");
+                               fprintf(stderr, " MPE FEC used \n");
                }
                
                        switch(ip_stream_buff->time_slice_fec.frame_size)
                        {
                        case 0:
                                {
-                                       printf(" Frame size : 256 rows \n");
-                                       printf(" Max Burst Duration 512 kbits\n");
+                                       fprintf(stderr, " Frame size : 256 rows \n");
+                                       fprintf(stderr, " Max Burst Duration 512 kbits\n");
                                }break;
                        case 1:
                                {
-                                       printf(" Frame size : 512 rows \n");
-                                       printf(" Max Burst Duration 1024 kbits\n");
+                                       fprintf(stderr, " Frame size : 512 rows \n");
+                                       fprintf(stderr, " Max Burst Duration 1024 kbits\n");
                                }break;
                        case 2:
                                {
-                                       printf(" Frame size : 768 rows \n");
-                                       printf(" Max Burst Duration 1536 kbits\n");
+                                       fprintf(stderr, " Frame size : 768 rows \n");
+                                       fprintf(stderr, " Max Burst Duration 1536 kbits\n");
                                }break;
                        case 3:
                                {
-                                       printf(" Frame size : 1024 rows \n");
-                                       printf(" Max Burst Duration 2048 kbits\n");
+                                       fprintf(stderr, " Frame size : 1024 rows \n");
+                                       fprintf(stderr, " Max Burst Duration 2048 kbits\n");
                                }break;
                        default:
                                break;
                        }
 
-                       printf(" Time Slice Fec ID : %x\n",ip_stream_buff->time_slice_fec.time_slice_fec_id);
+                       fprintf(stderr, " Time Slice Fec ID : %x\n",ip_stream_buff->time_slice_fec.time_slice_fec_id);
 
                        /* Locayion descriptor */
 
-                       printf("Location Descriptor \n");
-                       printf("Network ID:%d \n",ip_stream_buff->location.network_id);
-                       printf("Original Network ID:%d \n",ip_stream_buff->location.original_network_id);
-                       printf("Transport Stream ID:%d \n",ip_stream_buff->location.transport_stream_id);
-                       printf("Service ID:%d \n",ip_stream_buff->location.service_id);
-                       printf("Component Tag:%d \n",ip_stream_buff->location.component_tag);           
+                       fprintf(stderr, "Location Descriptor \n");
+                       fprintf(stderr, "Network ID:%d \n",ip_stream_buff->location.network_id);
+                       fprintf(stderr, "Original Network ID:%d \n",ip_stream_buff->location.original_network_id);
+                       fprintf(stderr, "Transport Stream ID:%d \n",ip_stream_buff->location.transport_stream_id);
+                       fprintf(stderr, "Service ID:%d \n",ip_stream_buff->location.service_id);
+                       fprintf(stderr, "Component Tag:%d \n",ip_stream_buff->location.component_tag);          
 
 
                        getchar(); // attendre l'appuie d'une touche
@@ -1100,7 +1099,7 @@ void socket_simu(GF_M2TS_IP_Packet *ip_packet, GF_M2TS_Demuxer *ts, Bool yield)
 
        e = gf_sk_send(Sock_Struct->sock, ip_packet->data, ip_packet->u32_udp_data_size - 8);
        if (e != GF_OK){ 
-               fprintf(stdout, "Error sending to \n");
+               fprintf(stderr, "Error sending to \n");
        }
        if (yield) gf_sleep(10);
 
@@ -1123,7 +1122,7 @@ Bool init_frame(MPE_FEC_FRAME * mff, u32 rows)
        mff->p_rs = (u8 *)gf_calloc(MPE_RS_COLS*rows,sizeof(u8));
 
 
-       printf("MPE_RS_COLS*rows :%d \n",MPE_RS_COLS*rows);
+       fprintf(stderr, "MPE_RS_COLS*rows :%d \n",MPE_RS_COLS*rows);
 
        mff->capacity_total = mff->col_adt*rows;                                 
        mff->p_error_adt = (u32 *)gf_calloc(mff->col_adt*rows,sizeof(u32)); 
@@ -1132,7 +1131,7 @@ Bool init_frame(MPE_FEC_FRAME * mff, u32 rows)
        mff->current_offset_rs = 0;
        mff->ADT_done = 0;
        mff->PID = 0;
-//     printf("MFF: rows: %d, adt_col: %d, rs_col : %d, capacity : %d\n", mff->rows, mff->col_adt, mff->col_rs, mff->capacity_total );
+//     fprintf(stderr, "MFF: rows: %d, adt_col: %d, rs_col : %d, capacity : %d\n", mff->rows, mff->col_adt, mff->col_rs, mff->capacity_total );
         mff->mpe_holes = gf_list_new();
        mff->initialized = 1;
        return 1;
@@ -1195,7 +1194,7 @@ void setRowRS(MPE_FEC_FRAME *mff, u32 index, u8 *p_rs)
 void addPadding(MPE_FEC_FRAME *mff , u32 offset)
 {
        u32 i = 0; 
-       printf("add paddings from %d to the end %d\n", offset, mff->capacity_total );
+       fprintf(stderr, "add paddings from %d to the end %d\n", offset, mff->capacity_total );
        for ( i = offset ; i <mff->capacity_total; i ++ )
        mff -> p_adt [i] = 0xff ; 
 }
@@ -1207,13 +1206,13 @@ static void print_bytes2(u8 * data, u32 length ) /*print_bytes2 */
        u32 k = 0; 
        for ( i = 0; i < length ; i ++ ) {
                if (k == 0) {
-                       printf("%x0  : ", row_num); 
+                       fprintf(stderr, "%x0  : ", row_num); 
                        k = 0;  
                }
-               printf("%#x ", data[i]);
+               fprintf(stderr, "%#x ", data[i]);
                k++;
                if (k == 16) {
-                       printf("\n");
+                       fprintf(stderr, "\n");
                        k = 0;
                        row_num ++;
                }
@@ -1230,17 +1229,17 @@ void setIpDatagram(MPE_FEC_FRAME * mff, u32 offset, u8* dgram, u32 length )
        
 
        if (offset >= mff->capacity_total) {
-               printf ("Offset %d bigger than capacity %d \n", offset, mff->capacity_total );
+               fprintf(stderr, "Offset %d bigger than capacity %d \n", offset, mff->capacity_total );
        }
        if (offset+length >= mff->capacity_total) {
-               printf ("Offset+length %d+%d bigger than capacity %d \n", offset, length, mff->capacity_total );
+               fprintf(stderr, "Offset+length %d+%d bigger than capacity %d \n", offset, length, mff->capacity_total );
        }
        if (mff->current_offset_adt != offset) {
                if (mff->current_offset_adt > offset) {
-                       printf ("We missed an offset reset (%d to %d)\n", mff->current_offset_adt, offset);
+                       fprintf(stderr, "We missed an offset reset (%d to %d)\n", mff->current_offset_adt, offset);
                        mff->current_offset_adt = offset; 
                } else {
-                       printf ("there is an error hole in the ADT from %d to %d \n", mff->current_offset_adt, offset);
+                       fprintf(stderr, "there is an error hole in the ADT from %d to %d \n", mff->current_offset_adt, offset);
                }
                setErrorIndicator( mff->p_error_adt , mff->current_offset_adt , (offset - mff->current_offset_adt)*sizeof(u32)  ) ;
                mpe_error_holes->offset = mff->current_offset_adt;
@@ -1257,7 +1256,7 @@ void setIpDatagram(MPE_FEC_FRAME * mff, u32 offset, u8* dgram, u32 length )
 void setColRS( MPE_FEC_FRAME * mff, u32 offset, u8 * pds, u32 length ) 
 {
        if ( mff->current_offset_rs != offset)  {
-               printf ("there is an error hole in the RS from %d to %d \n", mff->current_offset_rs, offset );
+               fprintf(stderr, "there is an error hole in the RS from %d to %d \n", mff->current_offset_rs, offset );
                setErrorIndicator( mff->p_error_rs , mff->current_offset_rs , (offset - mff->current_offset_rs)*sizeof(u32));
                mff->current_offset_rs = offset;        
        } 
@@ -1301,23 +1300,23 @@ u32  getErrasurePositions( MPE_FEC_FRAME *mff , u32 row, u32 *errasures)
                }
                base += mff->rows ; 
        }
-       printf (" the erasure locations is:\n");
+       fprintf(stderr, " the erasure locations is:\n");
        for ( i = 0; i < nb ; i ++ )
-               printf("%d ", errasures[i]);
+               fprintf(stderr, "%d ", errasures[i]);
        return nb;
 }
 
 void setErrorIndicator(u32 * data , u32 offset, u32 length)
 {
-//     printf("setting the error indication \n");
+//     fprintf(stderr, "setting the error indication \n");
        memset(data+offset, 1, length);
 }
 
 
 /*void descriptor_PRIVATE (u8 *b, DTAG_SCOPE tag_scope){
-       printf ("private descriptor \n");
+       fprintf(stderr, "private descriptor \n");
        return ;
 }*/
 
 
-#endif //GPAC_DISABLE_MPEG2TS
+#endif //GPAC_ENABLE_MPE
index 4a15a7b8bea25e373ad61d3cb05cd6bdbc8f9846..e3072e88251191fdd38149b5d4aeeeea41b17d0d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato / Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre, Cyril Concolato 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / mp4 simple streamer application
index fdf04ee8b8842cd245bd3c2d602dd7b0bd3a2f74..6e2ef1c482265e8ff22bf7fb9e825dcc0de08c67 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
index 39e9d8feb4fab9fc1e25f6d8bd56908fb2b71f88..d4263e5cbc73267133036e0ff5a67d61e290992f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre - 2005
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
index 7ce1c691d975c92ddbcb7ee34548efd4c8081aa5..05ebaee38c4e7018cf6bbb8a57011722f08e6486 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre 
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
@@ -67,7 +68,8 @@ void gf_media_get_sample_average_infos(GF_ISOFile *file, u32 Track, u32 *avgSize
                bw += 8*samp->dataLength;
                
                //get the CTS delta
-               if (samp->CTS_Offset > *maxCTSDelta) *maxCTSDelta = samp->CTS_Offset;
+               if ((samp->CTS_Offset>=0) && ((u32)samp->CTS_Offset > *maxCTSDelta))
+                       *maxCTSDelta = samp->CTS_Offset;
                gf_isom_sample_del(&samp);
        }
        if (count>1) *TimeDelta = (u32) (tdelta/ (count-1) );
index 9b8f18989e63201ca609918d3f4ad901f5b000bc..1d982045297d68a898df14bfeaf1f5882f9995bf 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
 
 
 
-#include <gpac/media_tools.h>
+#include <gpac/internal/media_dev.h>
 #include <gpac/constants.h>
 #include <gpac/config_file.h>
 
+#ifndef GPAC_DISABLE_ISOM_WRITE
+GF_EXPORT
+GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den)
+{
+       u32 tk_w, tk_h, stype;
+       GF_Err e;
+
+       e = gf_isom_get_visual_info(file, track, 1, &tk_w, &tk_h);
+       if (e) return e;
+
+       stype = gf_isom_get_media_subtype(file, track, 1);
+       if ((stype==GF_ISOM_SUBTYPE_AVC_H264) || (stype==GF_ISOM_SUBTYPE_AVC2_H264) ) {
+#ifndef GPAC_DISABLE_AV_PARSERS
+               GF_AVCConfig *avcc = gf_isom_avc_config_get(file, track, 1);
+               AVC_ChangePAR(avcc, ar_num, ar_den);
+               e = gf_isom_avc_config_update(file, track, 1, avcc);
+               gf_odf_avc_cfg_del(avcc);
+               if (e) return e;
+#endif
+       }
+       else if (stype==GF_ISOM_SUBTYPE_MPEG4) {
+               GF_ESD *esd = gf_isom_get_esd(file, track, 1);
+               if (!esd || !esd->decoderConfig || (esd->decoderConfig->streamType!=4) ) {
+                       if (esd)  gf_odf_desc_del((GF_Descriptor *) esd);
+                       return GF_NOT_SUPPORTED;
+               }
+#ifndef GPAC_DISABLE_AV_PARSERS
+               if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) {
+                       e = gf_m4v_rewrite_par(&esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength, ar_num, ar_den);
+                       if (!e) e = gf_isom_change_mpeg4_description(file, track, 1, esd);
+                       gf_odf_desc_del((GF_Descriptor *) esd);
+                       if (e) return e;
+               }
+#endif
+       } else {
+               return GF_BAD_PARAM;
+       }
+
+       e = gf_isom_set_pixel_aspect_ratio(file, track, 1, ar_num, ar_den);
+       if (e) return e;
+
+       if ((ar_den>=0) && (ar_num>=0)) {
+               if (ar_den) tk_w = tk_w * ar_num / ar_den;
+               else if (ar_num) tk_h = tk_h * ar_den / ar_num;
+       }
+       /*revert to full frame for track layout*/
+       else {
+               e = gf_isom_get_visual_info(file, track, 1, &tk_w, &tk_h);
+               if (e) return e;
+       }
+       return gf_isom_set_track_layout_info(file, track, tk_w<<16, tk_h<<16, 0, 0, 0);
+}
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 GF_EXPORT
 GF_Err gf_media_get_file_hash(const char *file, u8 hash[20]) 
 {
+#ifdef GPAC_DISABLE_CORE_TOOLS
+       return GF_NOT_SUPPORTED;
+#else
        u8 block[1024];
        u32 read;
        u64 size, tot;
@@ -92,66 +149,11 @@ GF_Err gf_media_get_file_hash(const char *file, u8 hash[20])
 #endif
        fclose(in);
        return GF_OK;
+#endif
 }
 
 #ifndef GPAC_DISABLE_ISOM
 
-GF_Err gf_media_get_rfc_6381_codec_name(GF_ISOFile *movie, u32 track, char *szCodec)
-{
-       GF_ESD *esd;
-       GF_AVCConfig *avcc;
-       GF_AVCConfigSlot *sps;
-       u32 subtype = gf_isom_get_media_subtype(movie, track, 1);
-
-       switch (subtype) {
-       case GF_ISOM_SUBTYPE_MPEG4:
-               esd = gf_isom_get_esd(movie, track, 1);
-               switch (esd->decoderConfig->streamType) {
-               case GF_STREAM_AUDIO:
-                       if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) {
-                               /*5 first bits of AAC config*/
-                               u8 audio_object_type = (esd->decoderConfig->decoderSpecificInfo->data[0] & 0xF8) >> 3;
-                               sprintf(szCodec, "mp4a.%02x.%02x", esd->decoderConfig->objectTypeIndication, audio_object_type);
-                       } else {
-                               sprintf(szCodec, "mp4a.%02x", esd->decoderConfig->objectTypeIndication);
-                       }
-                       break;
-               case GF_STREAM_VISUAL:
-#ifndef GPAC_DISABLE_AV_PARSERS
-                       if (esd->decoderConfig->decoderSpecificInfo) {
-                               GF_M4VDecSpecInfo dsi;
-                               gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);
-                               sprintf(szCodec, "mp4v.%02x.%02x", esd->decoderConfig->objectTypeIndication, dsi.VideoPL);
-                       } else
-#endif
-                       {
-                               sprintf(szCodec, "mp4v.%02x", esd->decoderConfig->objectTypeIndication);
-                       }
-                       break;
-               default:
-                       sprintf(szCodec, "mp4s.%02x", esd->decoderConfig->objectTypeIndication);
-                       break;
-               }
-               gf_odf_desc_del((GF_Descriptor *)esd);
-               return GF_OK;
-
-       case GF_ISOM_SUBTYPE_AVC_H264:
-       case GF_ISOM_SUBTYPE_AVC2_H264:
-       case GF_ISOM_SUBTYPE_SVC_H264:
-               avcc = gf_isom_avc_config_get(movie, track, 1);
-               sps = gf_list_get(avcc->sequenceParameterSets, 0);
-               sprintf(szCodec, "%s.%02x%02x%02x", gf_4cc_to_str(subtype), (u8) sps->data[1], (u8) sps->data[2], (u8) sps->data[3]);
-               gf_odf_avc_cfg_del(avcc);
-               return GF_OK;
-
-       default:
-               GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISOM Tools] codec parameters not known - setting codecs string to default value \"%s\"\n", gf_4cc_to_str(subtype) ));
-               sprintf(szCodec, "%s", gf_4cc_to_str(subtype));
-               return GF_OK;
-       }
-       return GF_OK;
-}
-
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
 static const u32 ISMA_VIDEO_OD_ID = 20;
@@ -728,1191 +730,6 @@ GF_Err gf_media_make_psp(GF_ISOFile *mp4)
        return GF_OK;
 }
 
-typedef struct
-{
-       Bool is_ref_track;
-       Bool done;
-       u32 TrackID;
-       u32 SampleNum, SampleCount;
-       u32 FragmentLength;
-       u32 OriginalTrack;
-       u32 finalSampleDescriptionIndex;
-       u32 TimeScale, MediaType, DefaultDuration, InitialTSOffset;
-       u64 last_sample_cts, next_sample_dts;
-       Bool all_sample_raps;
-} TrackFragmenter;
-
-static u64 get_next_sap_time(GF_ISOFile *input, u32 track, u32 sample_count, u32 sample_num)
-{
-       GF_ISOSample *samp;
-       u64 time;
-       Bool is_rap, has_roll;
-       u32 i, found_sample = 0;
-       for (i=sample_num; i<=sample_count; i++) {
-               if (gf_isom_get_sample_sync(input, track, i)) {
-                       found_sample = i;
-                       break;
-               }
-               gf_isom_get_sample_rap_roll_info(input, track, i, &is_rap, &has_roll, NULL);
-               if (is_rap || has_roll) {
-                       found_sample = i;
-                       break;
-               }
-       }
-       if (!found_sample) return 0;
-       samp = gf_isom_get_sample_info(input, track, found_sample, NULL, NULL);
-       time = samp->DTS;
-       gf_isom_sample_del(&samp);
-       return time;
-}
-
-
-#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-
-GF_EXPORT
-GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const char *mpd_name, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, Bool single_segment_mode, const char *dash_ctx_file, GF_ISOFile *sample_descs, u32 rep_idx)
-{
-       u8 NbBits;
-       u32 i, TrackNum, descIndex, j, count, nb_sync, ref_track_id, nb_tracks_done;
-       u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, nb_samp, nb_done;
-       u32 nb_video, nb_audio, nb_text, nb_scene;
-       u8 defaultPadding;
-       u16 defaultDegradationPriority;
-       GF_Err e;
-       char sOpt[100], sKey[100];
-       char szCodecs[200], szCodec[100];
-       u32 cur_seg, fragment_index, max_sap_type;
-       GF_ISOFile *output;
-       GF_ISOSample *sample, *next;
-       GF_List *fragmenters;
-       u32 MaxFragmentDuration, MaxSegmentDuration, SegmentDuration, maxFragDurationOverSegment;
-       Double average_duration, file_duration, period_duration, max_segment_duration;
-       u32 nb_segments, width, height, sample_rate, nb_channels;
-       char langCode[5];
-       u32 index_start_range, index_end_range;
-       Bool force_switch_segment = 0;
-       Bool switch_segment = 0;
-       Bool split_seg_at_rap = (dash_mode==2) ? 1 : 0;
-       Bool split_at_rap = 0;
-       Bool has_rap = 0;
-       Bool next_sample_rap = 0;
-       Bool flush_all_samples = 0;
-       Bool simulation_pass = 0;
-       u64 last_ref_cts = 0;
-       u64 start_range, end_range, file_size, init_seg_size, ref_track_first_dts, ref_track_next_cts;
-       u32 tfref_timescale = 0;
-       u32 bandwidth = 0;
-       TrackFragmenter *tf, *tfref;
-       FILE *mpd = NULL;
-       FILE *mpd_segs = NULL;
-       char *SegName = NULL;
-       const char *opt;
-       GF_Config *dash_ctx = NULL;
-       Bool store_dash_params = 0;
-       Bool dash_moov_setup = 0;
-       Bool segments_start_with_sap = 1;
-       Bool first_sample_in_segment = 0;
-       u32 *segments_info = NULL;
-       u32 nb_segments_info = 0;
-       Bool audio_only = 1;
-
-
-       SegmentDuration = 0;
-       nb_samp = 0;
-       fragmenters = NULL;
-       if (!seg_ext) seg_ext = "m4s";
-
-       //create output file
-       if (dash_mode) {
-               u32 len;
-               
-               if (dash_ctx_file) {
-                       dash_ctx = gf_cfg_new(NULL, dash_ctx_file);
-                       if (!dash_ctx) {
-                               FILE *t = fopen(dash_ctx_file, "wt");
-                               if (t) fclose(t);
-                               dash_ctx = gf_cfg_new(NULL, dash_ctx_file);
-                               
-                               if (dash_ctx) store_dash_params=1;
-                       }
-               }
-               len = strlen(output_file);
-               len += 100;
-               SegName = gf_malloc(sizeof(char)*len);
-               if (!SegName) return GF_OUT_OF_MEM;
-
-               opt = dash_ctx ? gf_cfg_get_key(dash_ctx, "DASH", "InitializationSegment") : NULL;
-               if (opt) {
-                       output = gf_isom_open(opt, GF_ISOM_OPEN_CAT_FRAGMENTS, NULL);
-                       dash_moov_setup = 1;
-               } else {
-                       strcpy(SegName, output_file);
-                       strcat(SegName, ".mp4");
-                       output = gf_isom_open(SegName, GF_ISOM_OPEN_WRITE, NULL);
-               }
-               if (!output) {
-                       e = gf_isom_last_error(NULL);
-                       goto err_exit;
-               }
-
-               if (store_dash_params) {
-                       gf_cfg_set_key(dash_ctx, "DASH", "InitializationSegment", SegName);
-               }
-               mpd = gf_f64_open(mpd_name, "a+t");
-               mpd_segs = gf_temp_file_new();
-       } else {
-               output = gf_isom_open(output_file, GF_ISOM_OPEN_WRITE, NULL);
-               if (!output) return gf_isom_last_error(NULL);
-       }
-       
-       nb_sync = 0;
-       nb_samp = 0;
-       fragmenters = gf_list_new();
-
-       if (! dash_moov_setup) {
-               e = gf_isom_clone_movie(input, output, 0, 0);
-               if (e) goto err_exit;
-       }
-
-       MaxFragmentDuration = (u32) (max_duration_sec * 1000);  
-       MaxSegmentDuration = (u32) (dash_duration_sec * 1000);
-
-       /*in single segment mode, only one big SIDX is written between the end of the moov and the first fragment. 
-       To speed-up writing, we do a first fragmentation pass without writing any sample to compute the number of segments and fragments per segment
-       in order to allocate / write to file the sidx before the fragmentation. The sidx will then be rewritten when closing the last segment*/
-       if (single_segment_mode) simulation_pass = 1;
-       index_start_range = index_end_range = 0;        
-
-       tfref = NULL;
-       file_duration = 0;
-       width = height = sample_rate = nb_channels = 0;
-       langCode[0]=0;
-       langCode[4]=0;
-       szCodecs[0] = 0;
-
-       nb_video = nb_audio = nb_text = nb_scene = 0;
-       //duplicates all tracks
-       for (i=0; i<gf_isom_get_track_count(input); i++) {
-               u32 _w, _h, _sr, _nb_ch;
-
-               u32 mtype = gf_isom_get_media_type(input, i+1);
-               if (mtype == GF_ISOM_MEDIA_HINT) continue;
-
-               if (! dash_moov_setup) {
-                       e = gf_isom_clone_track(input, i+1, output, 0, &TrackNum);
-                       if (e) goto err_exit;
-
-                       if (gf_isom_is_track_in_root_od(input, i+1)) gf_isom_add_track_to_root_od(output, TrackNum);
-
-                       //if only one sample, don't fragment track
-                       count = gf_isom_get_sample_count(input, i+1);
-                       if (count==1) {
-                               sample = gf_isom_get_sample(input, i+1, 1, &descIndex);
-                               e = gf_isom_add_sample(output, TrackNum, 1, sample);
-                               gf_isom_sample_del(&sample);
-                               if (e) goto err_exit;
-
-                               continue;
-                       }
-               } else {
-                       TrackNum = gf_isom_get_track_by_id(output, gf_isom_get_track_id(input, i+1));
-                       count = gf_isom_get_sample_count(input, i+1);
-               }
-
-               if (mtype == GF_ISOM_MEDIA_VISUAL) nb_video++;
-               else if (mtype == GF_ISOM_MEDIA_AUDIO) nb_audio++;
-               else if (mtype == GF_ISOM_MEDIA_TEXT) nb_text++;
-               else if (mtype == GF_ISOM_MEDIA_SCENE) nb_scene++;
-               else if (mtype == GF_ISOM_MEDIA_DIMS) nb_scene++;
-
-               if (mtype != GF_ISOM_MEDIA_AUDIO) audio_only = 0;
-
-               //setup fragmenters
-               if (! dash_moov_setup) {
-                       gf_isom_get_fragment_defaults(input, i+1,
-                                                                        &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority);
-
-                       //new initialization segment, setup fragmentation
-                       e = gf_isom_setup_track_fragment(output, gf_isom_get_track_id(output, TrackNum),
-                                               defaultDescriptionIndex, defaultDuration,
-                                               defaultSize, (u8) defaultRandomAccess,
-                                               defaultPadding, defaultDegradationPriority);
-                       if (e) goto err_exit;
-
-               } else {
-                       gf_isom_get_fragment_defaults(output, TrackNum,
-                                                                        &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority);
-               }
-
-               gf_media_get_rfc_6381_codec_name(output, TrackNum, szCodec);
-               if (strlen(szCodecs)) strcat(szCodecs, ",");
-               strcat(szCodecs, szCodec);
-
-               GF_SAFEALLOC(tf, TrackFragmenter);
-               tf->TrackID = gf_isom_get_track_id(output, TrackNum);
-               tf->SampleCount = gf_isom_get_sample_count(input, i+1);
-               tf->OriginalTrack = i+1;
-               tf->TimeScale = gf_isom_get_media_timescale(input, i+1);
-               tf->MediaType = gf_isom_get_media_type(input, i+1);
-               tf->DefaultDuration = defaultDuration;
-
-               if (gf_isom_get_sync_point_count(input, i+1)>nb_sync) { 
-                       tfref = tf;
-                       nb_sync = gf_isom_get_sync_point_count(input, i+1);
-               } else if (!gf_isom_has_sync_points(input, i+1)) {
-                       tf->all_sample_raps = 1;
-               }
-
-               tf->finalSampleDescriptionIndex = 1;
-
-               /*figure out if we have an initial TS*/
-               if (!dash_moov_setup) {
-                       if (gf_isom_get_edit_segment_count(input, i+1)) {
-                               u64 EditTime, SegmentDuration, MediaTime;
-                               u8 EditMode;
-                               gf_isom_get_edit_segment(input, i+1, 1, &EditTime, &SegmentDuration, &MediaTime, &EditMode);
-                               if (EditMode==GF_ISOM_EDIT_EMPTY) {
-                                       tf->InitialTSOffset = (u32) (SegmentDuration * tf->TimeScale / gf_isom_get_timescale(input));
-                               }
-                               /*and remove edit segments*/
-                               gf_isom_remove_edit_segments(output, TrackNum);
-                       }
-                       /*locate sample description in list if given*/
-                       if (sample_descs) {
-                               u32 s_count;
-                               u32 sample_descs_track = gf_isom_get_track_by_id(sample_descs, tf->TrackID);
-                               if (!sample_descs_track) {
-                                       e = GF_BAD_PARAM;
-                                       goto err_exit;
-
-                               }
-
-#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-                               //the initialization segment is not yet setup for fragmentation
-                               if (! gf_isom_is_track_fragmented(sample_descs, tf->TrackID)) {
-                                       e = gf_isom_setup_track_fragment(sample_descs, sample_descs_track,
-                                                               defaultDescriptionIndex, defaultDuration,
-                                                               defaultSize, (u8) defaultRandomAccess,
-                                                               defaultPadding, defaultDegradationPriority);
-                                       if (e) goto err_exit;
-                               }
-                               /*otherwise override the fragment defauls so that we are consistent with the shared init segment*/
-                               else {
-                                       e = gf_isom_get_fragment_defaults(sample_descs, sample_descs_track,
-                                                                                        &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority);
-                                       if (e) goto err_exit;
-
-                                       e = gf_isom_change_track_fragment_defaults(output, TrackNum,
-                                                                                        defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, defaultPadding, defaultDegradationPriority);
-                                       if (e) goto err_exit;
-                               }
-#endif
-
-                               /*reset all sample desc and clone with new ones*/
-                               gf_isom_clone_sample_descriptions(output, TrackNum, sample_descs, sample_descs_track, 1);
-
-                               /*and search in new ones the new index*/
-                               s_count = gf_isom_get_sample_description_count(sample_descs, sample_descs_track); 
-                               if (s_count>1) {
-                                       u32 k;
-                                       /*remove all sample descs*/
-                                       for (k=0; k<s_count; k++) {
-                                               /*search in original file if we have the sample desc*/
-                                               if (gf_isom_is_same_sample_description(input, TrackNum, 1, sample_descs, sample_descs_track, k+1)) {
-                                                       tf->finalSampleDescriptionIndex = k+1;
-                                               }
-                                       }
-                               }
-                       }
-               }
-               /*restore track decode times*/
-               else {
-                       char *opt, sKey[100];
-                       sprintf(sKey, "TrackID_%d", tf->TrackID);
-                       opt = (char *)gf_cfg_get_key(dash_ctx, sKey, "NextDecodingTime");
-                       if (opt) tf->InitialTSOffset = atoi(opt);
-               }
-       
-               switch (mtype) {
-               case GF_ISOM_MEDIA_TEXT:
-                       gf_isom_get_media_language(input, i+1, langCode);
-               case GF_ISOM_MEDIA_VISUAL:
-                       if (!tfref && (count >=10)) {
-                               tfref = tf;
-                       }
-               case GF_ISOM_MEDIA_SCENE:
-               case GF_ISOM_MEDIA_DIMS:
-                       gf_isom_get_track_layout_info(input, i+1, &_w, &_h, NULL, NULL, NULL);
-                       if (_w>width) width = _w;
-                       if (_h>height) height = _h;
-                       break;
-               case GF_ISOM_MEDIA_AUDIO:
-                       gf_isom_get_audio_info(input, i+1, 1, &_sr, &_nb_ch, NULL);
-                       if (_sr>sample_rate) sample_rate=_sr;
-                       if (_nb_ch>nb_channels) nb_channels = _nb_ch;
-                       gf_isom_get_media_language(input, i+1, langCode);
-                       break;
-               }
-
-               if (file_duration < ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale ) {
-                       file_duration = ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale;
-               }
-               gf_list_add(fragmenters, tf);
-
-               nb_samp += count;
-       }
-
-       if (!tfref) tfref = gf_list_get(fragmenters, 0);
-       tfref->is_ref_track = 1;
-       tfref_timescale = tfref->TimeScale;
-       ref_track_id = tfref->TrackID;
-       if (tfref->all_sample_raps) split_seg_at_rap = 1;
-
-       //flush movie
-#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
-       e = gf_isom_finalize_for_fragment(output, dash_mode ? 1 : 0);
-       if (e) goto err_exit;
-#endif
-
-       start_range = 0;
-       file_size = gf_isom_get_file_size(output);
-       end_range = file_size - 1;
-       init_seg_size = file_size;
-
-       if (dash_ctx) {
-               if (store_dash_params) {
-                       char szVal[1024];
-                       sprintf(szVal, LLU, init_seg_size);
-                       gf_cfg_set_key(dash_ctx, "DASH", "InitializationSegmentSize", szVal);
-               } else {
-                       const char *opt = gf_cfg_get_key(dash_ctx, "DASH", "InitializationSegmentSize");
-                       if (opt) init_seg_size = atoi(opt);
-               }
-       }
-
-restart_fragmentation_pass:
-
-       average_duration = 0;
-       nb_segments = 0;
-
-       nb_tracks_done = 0;
-       ref_track_first_dts = (u64) -1;
-       nb_done = 0;
-
-       maxFragDurationOverSegment=0;
-       if (dash_mode) switch_segment=1;
-
-       if (!seg_rad_name) use_url_template = 0;
-
-       cur_seg=1;
-       fragment_index=1;
-       period_duration = 0;
-       split_at_rap = 0;
-       has_rap = 0;
-       next_sample_rap = 0;
-       flush_all_samples = 0;
-       force_switch_segment = 0;
-       max_sap_type = 0;
-       ref_track_next_cts = 0;
-
-       /*setup previous URL list*/
-       if (dash_ctx) {
-               const char *opt;
-               count = gf_cfg_get_key_count(dash_ctx, "URLs");
-               for (i=0; i<count; i++) {
-                       const char *key_name = gf_cfg_get_key_name(dash_ctx, "URLs", i);
-                       opt = gf_cfg_get_key(dash_ctx, "URLs", key_name);
-                       fprintf(mpd_segs, "    %s\n", opt);     
-               }
-
-               opt = gf_cfg_get_key(dash_ctx, "DASH", "NextSegmentIndex");
-               if (opt) cur_seg = atoi(opt);
-               opt = gf_cfg_get_key(dash_ctx, "DASH", "NextFragmentIndex");
-               if (opt) fragment_index = atoi(opt);
-               opt = gf_cfg_get_key(dash_ctx, "DASH", "PeriodDuration");
-               if (opt) period_duration = atof(opt);
-       }
-       gf_isom_set_next_moof_number(output, fragment_index);
-
-
-       max_segment_duration = 0;
-
-       while ( (count = gf_list_count(fragmenters)) ) {
-
-               if (switch_segment) {
-                       SegmentDuration = 0;
-                       switch_segment = 0;
-                       first_sample_in_segment = 1;
-
-                       if (simulation_pass) {
-                               segments_info = gf_realloc(segments_info, sizeof(u32) * (nb_segments_info+1) );
-                               segments_info[nb_segments_info] = 0;
-                               nb_segments_info++;
-                               e = GF_OK;
-                       } else {
-                               start_range = gf_isom_get_file_size(output);
-                               if (seg_rad_name) {
-                                       sprintf(SegName, "%s%d.%s", seg_rad_name, cur_seg, seg_ext);
-                                       e = gf_isom_start_segment(output, SegName);
-                                       if (!use_url_template) {
-                                               fprintf(mpd_segs, "     <SegmentURL media=\"%s\"/>\n", SegName);        
-                                               if (dash_ctx) {
-                                                       char szKey[100], szVal[4046];
-                                                       sprintf(szKey, "UrlInfo%d", gf_cfg_get_key_count(dash_ctx, "URLs") + 1 );
-                                                       sprintf(szVal, "<SegmentURL sourceURL=\"%s\"/>", SegName);
-                                                       gf_cfg_set_key(dash_ctx, "URLs", szKey, szVal);
-                                               }
-                                       }
-                               } else {
-                                       e = gf_isom_start_segment(output, NULL);
-                               }
-                       }
-
-                       cur_seg++;
-                       if (e) goto err_exit;
-               } 
-
-               maxFragDurationOverSegment=0;
-
-               sample = NULL;
-
-               if (simulation_pass) {
-                       segments_info[nb_segments_info-1] ++;
-                       e = GF_OK;
-               } else {
-                       e = gf_isom_start_fragment(output, 1);
-                       if (e) goto err_exit;
-       
-
-                       for (i=0; i<count; i++) {
-                               tf = (TrackFragmenter *)gf_list_get(fragmenters, i);
-                               if (tf->done) continue;
-                               gf_isom_set_traf_base_media_decode_time(output, tf->TrackID, tf->InitialTSOffset + tf->next_sample_dts);
-                       }
-               
-               }
-
-               //process track by track
-               for (i=0; i<count; i++) {
-                       Bool has_roll, is_rap;
-                       s32 roll_distance;
-                       u32 SAP_type = 0;
-                       /*start with ref*/
-                       if (tfref && split_seg_at_rap ) {
-                               if (i==0) {
-                                       tf = tfref;
-                                       has_rap=0;
-                               } else {
-                                       tf = (TrackFragmenter *)gf_list_get(fragmenters, i-1);
-                                       if (tf == tfref) {
-                                               tf = (TrackFragmenter *)gf_list_get(fragmenters, i);
-                                       }
-                               }
-                       } else {
-                               tf = (TrackFragmenter *)gf_list_get(fragmenters, i);
-                               if (tf == tfref) 
-                                       has_rap=0;
-                       } 
-                       if (tf->done) continue;
-
-                       //ok write samples
-                       while (1) {
-                               Bool stop_frag = 0;
-
-                               /*first sample*/
-                               if (!sample) {
-                                       sample = gf_isom_get_sample(input, tf->OriginalTrack, tf->SampleNum + 1, &descIndex);
-                                       if (!sample) {
-                                               e = gf_isom_last_error(input);
-                                               goto err_exit;
-                                       }
-
-                                       /*also get SAP type - this is not needed if sample is not NULL as SAP tye was computed for "next sample" in previous loop*/
-                                       if (sample->IsRAP) {
-                                               SAP_type = 1;
-                                       } else {
-                                               SAP_type = 0;
-                                               e = gf_isom_get_sample_rap_roll_info(input, tf->OriginalTrack, tf->SampleNum + 1, &is_rap, &has_roll, &roll_distance);
-                                               if (e==GF_OK) {
-                                                       if (is_rap) SAP_type = 3;
-                                                       else if (has_roll && (roll_distance>=0) ) SAP_type = 4;
-                                               }
-                                       }
-                               }
-                               gf_isom_get_sample_padding_bits(input, tf->OriginalTrack, tf->SampleNum+1, &NbBits);
-
-                               next = gf_isom_get_sample(input, tf->OriginalTrack, tf->SampleNum + 2, &j);
-                               if (next) {
-                                       defaultDuration = (u32) (next->DTS - sample->DTS);
-                               } else {
-                                       defaultDuration = tf->DefaultDuration;
-                               }
-
-                               if (tf==tfref) {
-                                       if (segments_start_with_sap && first_sample_in_segment ) {
-                                               first_sample_in_segment = 0;
-                                               if (! SAP_type) segments_start_with_sap = 0;
-                                       }
-                                       if (ref_track_first_dts > sample->DTS) 
-                                               ref_track_first_dts = sample->DTS;
-
-                                       if (next) {
-                                               u64 next_cts = next->DTS + next->CTS_Offset;
-                                               if (ref_track_next_cts<next_cts) {
-                                                       ref_track_next_cts = next_cts;
-                                               }
-                                       } else {
-                                               u64 cts = gf_isom_get_media_duration(input, tf->OriginalTrack);
-                                               if (cts>ref_track_next_cts) ref_track_next_cts = cts;
-                                               else ref_track_next_cts += defaultDuration;
-                                       }
-                               }
-
-                               if (SAP_type > max_sap_type) max_sap_type = SAP_type;
-
-                               if (simulation_pass) {
-                                       e = GF_OK;
-                               } else {
-                                       /*override descIndex with final index used in file*/
-                                       descIndex = tf->finalSampleDescriptionIndex;
-                                       e = gf_isom_fragment_add_sample(output, tf->TrackID, sample, descIndex,
-                                                                        defaultDuration, NbBits, 0);
-                                       if (e) 
-                                               goto err_exit;
-
-                                       /*copy subsample information*/
-                                       e = gf_isom_fragment_copy_subsample(output, tf->TrackID, input, tf->OriginalTrack, tf->SampleNum + 1);
-                                       if (e) 
-                                               goto err_exit;
-
-                                       gf_set_progress("ISO File Fragmenting", nb_done, nb_samp);
-                                       nb_done++;
-                               }
-
-                               tf->last_sample_cts = sample->DTS + sample->CTS_Offset;
-                               tf->next_sample_dts = sample->DTS + defaultDuration;
-
-                               gf_isom_sample_del(&sample);
-                               sample = next;
-                               tf->FragmentLength += defaultDuration;
-                               tf->SampleNum += 1;
-
-                               /*compute SAP type*/
-                               if (sample) {
-                                       if (sample->IsRAP) {
-                                               SAP_type = 1;
-                                       } else {
-                                               SAP_type = 0;
-                                               e = gf_isom_get_sample_rap_roll_info(input, tf->OriginalTrack, tf->SampleNum + 1, &is_rap, &has_roll, NULL);
-                                               if (e==GF_OK) {
-                                                       if (is_rap)
-                                                               SAP_type = 3;
-                                                       else if (has_roll && (roll_distance>=0) )
-                                                               SAP_type = 4;
-                                               }
-                                       }
-                               }
-
-                               if (next && SAP_type) {
-                                       if (tf==tfref) {
-                                               if (split_seg_at_rap) {
-                                                       u64 next_sap_time;
-                                                       /*duration of fragment if we add this rap*/
-                                                       u32 frag_dur = (tf->FragmentLength+defaultDuration)*1000/tf->TimeScale;
-                                                       next_sample_rap = 1;
-                                                       next_sap_time = get_next_sap_time(input, tf->OriginalTrack, tf->SampleCount, tf->SampleNum + 2);
-                                                       /*if no more SAP after this one, do not switch segment*/
-                                                       if (next_sap_time) {
-                                                               u32 scaler;
-                                                               /*this is the fragment duration from last sample added to next SAP*/
-                                                               frag_dur += (u32) (next_sap_time - tf->next_sample_dts - defaultDuration)*1000/tf->TimeScale;
-                                                               /*if media segment about to be produced is longer than max segment length, force segment split*/
-                                                               if (SegmentDuration + frag_dur > MaxSegmentDuration) {
-                                                                       split_at_rap = 1;
-                                                                       /*force new segment*/
-                                                                       force_switch_segment = 1;
-                                                               }
-
-                                                               /*if adding this SAP will result in stoping the fragment "soon" after it, stop now and start with SAP
-                                                               if all samples are RAPs, just stop fragment if we exceed the requested duration by adding the next sample
-                                                               otherwise, take 3 samples (should be refined of course)*/
-                                                               scaler = 3;
-                                                               if (tf->all_sample_raps) scaler = 1;
-                                                               if ( (tf->FragmentLength + scaler*defaultDuration)*1000 >= MaxFragmentDuration * tf->TimeScale)
-                                                                       stop_frag = 1;
-                                                       }
-                                                       if (split_at_rap && !tf->all_sample_raps) {
-                                                               stop_frag = 1;
-                                                               /*override fragment duration for the rest of this fragment*/
-                                                               MaxFragmentDuration = tf->FragmentLength*1000/tf->TimeScale;
-                                                       }
-                                               } else if (!has_rap) {
-                                                       if (tf->FragmentLength == defaultDuration) has_rap = 2;
-                                                       else has_rap = 1;
-                                               }
-                                       } 
-                               } else {
-                                       next_sample_rap = 0;
-                               }
-
-                               if (tf->SampleNum==tf->SampleCount) {
-                                       stop_frag = 1;
-                               } else if (tf==tfref) {
-                                       /*fragmenting on "clock" track: no drift control*/
-                    if (tf->FragmentLength*1000 >= MaxFragmentDuration*tf->TimeScale)
-                                               stop_frag = 1;
-                               }
-                               /*do not abort fragment if ref track is done, put everything in the last fragment*/
-                               else if (!flush_all_samples) {
-                                       /*fragmenting on "non-clock" track: drift control*/
-                                       if (tf->last_sample_cts * tfref_timescale >= last_ref_cts * tf->TimeScale)
-                                               stop_frag = 1;
-                               }
-
-                               if (stop_frag) {
-                                       gf_isom_sample_del(&next);
-                                       sample = next = NULL;
-                                       if (maxFragDurationOverSegment<=tf->FragmentLength*1000/tf->TimeScale) {
-                                               maxFragDurationOverSegment = tf->FragmentLength*1000/tf->TimeScale;
-                                       }
-                                       tf->FragmentLength = 0;
-
-                                       if (tf==tfref) last_ref_cts = tf->last_sample_cts;
-
-                                       break;
-                               }
-                       }
-
-                       if (tf->SampleNum==tf->SampleCount) {
-                               tf->done = 1;
-                               nb_tracks_done++;
-                               if (tf == tfref) {
-                                       tfref = NULL;
-                                       flush_all_samples = 1;
-                               }
-                       }
-               }
-
-               if (dash_mode) {
-
-                       SegmentDuration += maxFragDurationOverSegment;
-                       maxFragDurationOverSegment=0;
-
-                       /*next fragment will exceed segment length, abort fragment now (all samples RAPs)*/
-                       if (tfref && tfref->all_sample_raps && (SegmentDuration + MaxFragmentDuration >= MaxSegmentDuration)) {
-                               force_switch_segment = 1;
-                       }
-
-                       if (force_switch_segment || ((SegmentDuration >= MaxSegmentDuration) && (!split_seg_at_rap || next_sample_rap))) {
-                               average_duration += SegmentDuration;
-                               nb_segments++;
-                               if (max_segment_duration * 1000 <= SegmentDuration) {
-                                       max_segment_duration = SegmentDuration;
-                                       max_segment_duration /= 1000;
-                               }
-
-
-#if 0
-                               if (split_seg_at_rap) has_rap = 0;
-                               fprintf(stdout, "Seg#%d: Duration %d%s - Track times (ms): ", nb_segments, SegmentDuration, (has_rap == 2) ? " - Starts with RAP" : ((has_rap == 1) ? " - Contains RAP" : "") );
-                               for (i=0; i<count; i++) {
-                                       tf = (TrackFragmenter *)gf_list_get(fragmenters, i);
-                                       fprintf(stdout, "%d ", (u32) ( (tf->last_sample_cts*1000.0)/tf->TimeScale) );
-                               }
-                               fprintf(stdout, "\n ");
-#endif
-                               force_switch_segment=0;
-                               switch_segment=1;
-                               SegmentDuration=0;
-                               split_at_rap = 0;
-                               has_rap = 0;
-                               /*restore fragment duration*/
-                               MaxFragmentDuration = (u32) (max_duration_sec * 1000);
-
-                               if (!simulation_pass) {
-                                       u64 idx_start_range, idx_end_range;
-                                       
-                                       gf_isom_close_segment(output, subsegs_per_sidx, ref_track_id, ref_track_first_dts, ref_track_next_cts, daisy_chain_sidx, flush_all_samples ? 1 : 0, &idx_start_range, &idx_end_range);
-                                       ref_track_first_dts = (u64) -1;
-
-                                       if (!seg_rad_name) {
-                                               file_size = gf_isom_get_file_size(output);
-                                               end_range = file_size - 1;
-                                               if (!single_segment_mode) {
-                                                       fprintf(mpd_segs, "     <SegmentURL mediaRange=\""LLD"-"LLD"\" indexRange=\""LLD"-"LLD"\"/>\n", start_range, end_range, idx_start_range, idx_end_range);        
-                                                       if (dash_ctx) {
-                                                               char szKey[100], szVal[4046];
-                                                               sprintf(szKey, "UrlInfo%d", gf_cfg_get_key_count(dash_ctx, "URLs") + 1 );
-                                                               sprintf(szVal, "<SegmentURL mediaRange=\""LLD"-"LLD"\" indexRange=\""LLD"-"LLD"\"/>", start_range, end_range, idx_start_range, idx_end_range);
-                                                               gf_cfg_set_key(dash_ctx, "URLs", szKey, szVal);
-                                                       }
-                                               }
-                                       } else {
-                                               file_size += gf_isom_get_file_size(output);
-                                       }
-                               }
-                       } 
-                       /*next fragment will exceed segment length, abort fragment at next rap (possibly after MaxSegmentDuration)*/
-                       if (split_seg_at_rap && SegmentDuration && (SegmentDuration + MaxFragmentDuration >= MaxSegmentDuration)) {
-                               split_at_rap = 1;
-                       }
-               }
-               
-               if (nb_tracks_done==count) break;
-       }
-
-       if (simulation_pass) {
-               /*OK, we have all segments and frags per segments*/
-               gf_isom_allocate_sidx(output, subsegs_per_sidx, daisy_chain_sidx, nb_segments_info, segments_info, &index_start_range, &index_end_range );
-               gf_free(segments_info);
-               segments_info = NULL;
-               simulation_pass = 0;
-               /*reset fragmenters*/
-               for (i=0; i<gf_list_count(fragmenters); i++) {
-                       tf = gf_list_get(fragmenters, i);
-                       tf->done = 0;
-                       tf->last_sample_cts = 0;
-                       tf->next_sample_dts = 0;
-                       tf->FragmentLength = 0;
-                       tf->SampleNum = 0;
-                       if (tf->is_ref_track) tfref = tf;
-               }
-               goto restart_fragmentation_pass;
-       }
-
-       if (dash_mode) {
-               char buffer[1000];
-
-               /*flush last segment*/
-               if (!switch_segment) {
-                       u64 idx_start_range, idx_end_range;
-
-                       if (max_segment_duration * 1000 <= SegmentDuration) {
-                               max_segment_duration = SegmentDuration;
-                               max_segment_duration /= 1000;
-                       }
-
-                       gf_isom_close_segment(output, subsegs_per_sidx, ref_track_id, ref_track_first_dts, ref_track_next_cts, daisy_chain_sidx, 1, &idx_start_range, &idx_end_range);
-                       nb_segments++;
-
-                       if (!seg_rad_name) {
-                               file_size = gf_isom_get_file_size(output);
-                               end_range = file_size - 1;
-                               if (!single_segment_mode) {
-                                       fprintf(mpd_segs, "     <SegmentURL mediaRange=\""LLD"-"LLD"\" indexRange=\""LLD"-"LLD"\"/>\n", start_range, end_range, idx_start_range, idx_end_range);        
-                                       if (dash_ctx) {
-                                               char szKey[100], szVal[4046];
-                                               sprintf(szKey, "UrlInfo%d", gf_cfg_get_key_count(dash_ctx, "URLs") + 1 );
-                                               sprintf(szVal, "<SegmentURL mediaRange=\""LLD"-"LLD"\" indexRange=\""LLD"-"LLD"\"/>", start_range, end_range, idx_start_range, idx_end_range);
-                                               gf_cfg_set_key(dash_ctx, "URLs", szKey, szVal);
-                                       }
-                               }
-                       } else {
-                               file_size += gf_isom_get_file_size(output);
-                       }
-               }
-
-               period_duration += file_duration;
-               //u32 h = (u32) (period_duration/3600);
-               //u32 m = (u32) (period_duration-h*60)/60;
-               bandwidth = (u32) (file_size * 8 / file_duration);
-
-               fprintf(mpd, "   <Representation id=\"%d\" mimeType=\"%s/mp4\" codecs=\"%s\"", rep_idx ? rep_idx : 1, audio_only ? "audio" : "video", szCodecs);
-               if (width && height) fprintf(mpd, " width=\"%d\" height=\"%d\"", width, height);
-               if (sample_rate && nb_channels) fprintf(mpd, " sampleRate=\"%d\" numChannels=\"%d\"", sample_rate, nb_channels);
-               if (langCode[0]) fprintf(mpd, " lang=\"%s\"", langCode);
-               if (segments_start_with_sap || split_seg_at_rap) {
-                       fprintf(mpd, " startWithSAP=\"%d\"", max_sap_type);
-               } else {
-                       fprintf(mpd, " startWithSAP=\"false\"");
-               }
-               if (single_segment_mode && segments_start_with_sap) fprintf(mpd, " subsegmentStartsWithSAP=\"true\"");
-               
-               fprintf(mpd, " bandwidth=\"%d\"", bandwidth);           
-               fprintf(mpd, ">\n");
-
-               if (dash_ctx) {
-                       Double seg_dur;
-                       opt = gf_cfg_get_key(dash_ctx, "DASH", "MaxSegmentDuration");
-                       if (opt) {
-                               seg_dur = atof(opt);
-                               if (seg_dur < max_segment_duration) {
-                                       sprintf(sOpt, "%f", max_segment_duration);
-                                       gf_cfg_set_key(dash_ctx, "DASH", "MaxSegmentDuration", sOpt);
-                                       seg_dur = max_segment_duration;
-                               } else {
-                                       max_segment_duration = seg_dur;
-                               }
-                       } else {
-                               sprintf(sOpt, "%f", max_segment_duration);
-                               gf_cfg_set_key(dash_ctx, "DASH", "MaxSegmentDuration", sOpt);
-                       }
-               }
-
-               if (use_url_template) {
-                       sprintf(SegName, "%s$Number$.%s", seg_rad_name, seg_ext);
-                       fprintf(mpd, "    <SegmentTemplate timescale=\"1000\" duration=\"%d\" media=\"%s\" startNumber=\"1\"", (u32) (max_segment_duration*1000), SegName);     
-                       if (!sample_descs) fprintf(mpd, " initialization=\"%s.mp4\"", output_file);     
-                       fprintf(mpd, "/>\n");
-               } else if (single_segment_mode) {
-                       fprintf(mpd, "    <BaseURL>%s</BaseURL>\n", gf_isom_get_filename(output) );     
-                       fprintf(mpd, "    <SegmentBase indexRangeExact=\"true\" indexRange=\"%d-%d\"/>\n", index_start_range, index_end_range); 
-               } else {
-                       if (!seg_rad_name) {
-                               fprintf(mpd, "    <BaseURL>%s.mp4</BaseURL>\n", output_file );  
-                       }
-                       fprintf(mpd, "    <SegmentList timescale=\"1000\" duration=\"%d\">\n", (u32) (max_segment_duration*1000));      
-                       //if (!sample_descs) 
-                       {
-                               fprintf(mpd, "     <Initialization");   
-                               if (!seg_rad_name) {
-                                       fprintf(mpd, " range=\"0-"LLD"\"", init_seg_size-1);
-                               } else {
-                                       fprintf(mpd, " sourceURL=\"%s.mp4\"", output_file);
-                               }
-                               fprintf(mpd, "/>\n");
-                       }
-               }
-
-
-               gf_f64_seek(mpd_segs, 0, SEEK_SET);
-               while (!feof(mpd_segs)) {
-                       u32 r = fread(buffer, 1, 100, mpd_segs);
-                       gf_fwrite(buffer, 1, r, mpd);
-               }
-
-               if (!use_url_template && !single_segment_mode) {
-                       fprintf(mpd, "    </SegmentList>\n");
-               }
-
-               fprintf(mpd, "   </Representation>\n");
-       }
-
-       /*store context*/
-       if (dash_ctx) {
-               for (i=0; i<gf_list_count(fragmenters); i++) {
-                       tf = (TrackFragmenter *)gf_list_get(fragmenters, i);
-                       
-                       sprintf(sKey, "TrackID_%d", tf->TrackID);
-                       sprintf(sOpt, LLU, tf->InitialTSOffset + tf->next_sample_dts);
-                       gf_cfg_set_key(dash_ctx, sKey, "NextDecodingTime", sOpt);
-               }
-               sprintf(sOpt, "%d", cur_seg);
-               gf_cfg_set_key(dash_ctx, "DASH", "NextSegmentIndex", sOpt);
-
-               fragment_index = gf_isom_get_next_moof_number(output);
-               sprintf(sOpt, "%d", fragment_index);
-               gf_cfg_set_key(dash_ctx, "DASH", "NextFragmentIndex", sOpt);
-               sprintf(sOpt, "%f", period_duration);
-               gf_cfg_set_key(dash_ctx, "DASH", "PeriodDuration", sOpt);
-       }
-
-err_exit:
-       if (fragmenters){
-               while (gf_list_count(fragmenters)) {
-                       tf = (TrackFragmenter *)gf_list_get(fragmenters, 0);
-                       gf_free(tf);
-                       gf_list_rem(fragmenters, 0);
-               }
-               gf_list_del(fragmenters);
-       }
-       if (e) gf_isom_delete(output);
-       else gf_isom_close(output);
-       gf_set_progress("ISO File Fragmenting", nb_samp, nb_samp);
-       if (SegName) gf_free(SegName);
-       if (mpd) fclose(mpd);
-       if (mpd_segs) fclose(mpd_segs);
-       if (dash_ctx) gf_cfg_del(dash_ctx);
-       return e;
-}
-
-#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
-
-GF_EXPORT
-GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bool single_segment, char *dash_ctx, GF_ISOFile *init_segment, Double period_duration)
-{
-       u32 h, m;
-       Double s;
-       FILE *mpd = fopen(mpd_name, "wt");
-       if (!mpd) return GF_IO_ERR;
-
-       h = (u32) (period_duration/3600);
-       m = (u32) (period_duration-h*60)/60;
-       s = period_duration - h*3600 - m*60;
-
-       /*TODO what should we put for minBufferTime */
-       fprintf(mpd, "<MPD type=\"static\" xmlns=\"urn:mpeg:DASH:schema:MPD:2011\" profiles=\"%s\" minBufferTime=\"PT1.5S\" mediaPresentationDuration=\"PT%dH%dM%.2fS\">\n", 
-               single_segment ? "urn:mpeg:dash:profile:isoff-on-demand:2011" : "urn:mpeg:dash:profile:full:2011",
-               h, m, s);
-    fprintf(mpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n");
-       if (title)
-               fprintf(mpd, "  <Title>Media Presentation Description for file %s generated with GPAC </Title>\n", title);
-    fprintf(mpd, " </ProgramInformation>\n");
-    fprintf(mpd, " <Period start=\"PT0S\" duration=\"PT%dH%dM%.2fS\">\n", h, m, s);    
-       fprintf(mpd, "  <AdaptationSet>\n");
-
-       if (init_segment) {
-               u32 i;
-               char langCode[4];
-               langCode[3] = 0;
-
-               for (i=0; i<gf_isom_get_track_count(init_segment); i++) {
-                       u32 trackID = gf_isom_get_track_id(init_segment, i+1);
-
-                       gf_isom_get_media_language(init_segment, i+1, langCode);
-
-                       switch (gf_isom_get_media_type(init_segment, i+1) ) {
-                       case GF_ISOM_MEDIA_TEXT:
-                               fprintf(mpd, "    <ContentComponent id=\"%d\" contentType=\"text\" lang=\"%s\"/>\n", trackID, langCode);
-                               break;
-                       case GF_ISOM_MEDIA_VISUAL:
-                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"video\"/>\n", trackID);
-                               break;
-                       case GF_ISOM_MEDIA_SCENE:
-                       case GF_ISOM_MEDIA_DIMS:
-                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"application\" lang=\"%s\"/>\n", trackID, langCode);
-                               break;
-                       case GF_ISOM_MEDIA_AUDIO:
-                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"audio\" lang=\"%s\"/>\n", trackID, langCode);
-                               break;
-                       }
-               }
-
-               if (use_url_template) {
-                       fprintf(mpd, "   <SegmentTemplate initialization=\"%s\"/>\n", gf_isom_get_filename(init_segment) );     
-               } else if (0 && !single_segment) {
-                       fprintf(mpd, "   <SegmentList>\n");     
-                       fprintf(mpd, "    <Initialization sourceURL=\"%s\"/>\n", gf_isom_get_filename(init_segment) );  
-                       fprintf(mpd, "   </SegmentList>\n");    
-               }
-       }
-
-       fclose(mpd);
-       return GF_OK;
-}
-
-GF_EXPORT
-GF_Err gf_media_mpd_end(char *mpd_name)
-{
-       FILE *mpd = fopen(mpd_name, "a+t");
-       if (!mpd_name) return GF_IO_ERR;
-
-    fprintf(mpd, "  </AdaptationSet>\n");
-    fprintf(mpd, " </Period>\n");
-    fprintf(mpd, "</MPD>");
-
-       fclose(mpd);
-       return GF_OK;
-}
-
-GF_EXPORT
-GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import_fps)
-{
-       int readen=0;
-       GF_Err e;
-       u32 state, offset;
-       u32 cur_chap;
-       u64 ts;
-       u32 i, h, m, s, ms, fr, fps;
-       char line[1024];
-       char szTitle[1024];
-       FILE *f = gf_f64_open(chap_file, "rt");
-       if (!f) return GF_URL_ERROR;
-
-       readen = fread(line, 1, 4, f);
-       if (readen < 4){
-               e = GF_URL_ERROR;
-               goto err_exit;
-       }
-       offset = 0;
-       if ((line[0]==(char)(0xFF)) && (line[1]==(char)(0xFE))) {
-               if (!line[2] && !line[3]){
-                       e = GF_NOT_SUPPORTED;
-                       goto err_exit;
-               }
-               offset = 2;
-       } else if ((line[0]==(char)(0xFE)) && (line[1]==(char)(0xFF))) {
-               if (!line[2] && !line[3]){
-                       e = GF_NOT_SUPPORTED;
-                       goto err_exit;
-               }
-               offset = 2;
-       } else if ((line[0]==(char)(0xEF)) && (line[1]==(char)(0xBB)) && (line[2]==(char)(0xBF))) {
-               /*we handle UTF8 as asci*/
-               offset = 3;
-       } else {
-               offset = 0;
-       }
-       gf_f64_seek(f, offset, SEEK_SET);
-
-       e = gf_isom_remove_chapter(file, 0, 0);
-       if (e) goto err_exit;
-
-       /*try to figure out the frame rate*/
-       for (i=0; i<gf_isom_get_track_count(file); i++) {
-               GF_ISOSample *samp;
-               u32 ts, inc;
-               if (gf_isom_get_media_type(file, i+1) != GF_ISOM_MEDIA_VISUAL) continue;
-               if (gf_isom_get_sample_count(file, i+1) < 20) continue;
-               samp = gf_isom_get_sample_info(file, 1, 2, NULL, NULL);
-               inc = (u32) samp->DTS;
-               if (!inc) inc=1;
-               ts = gf_isom_get_media_timescale(file, i+1);
-               import_fps = ts;
-               import_fps /= inc;
-               gf_isom_sample_del(&samp);
-               GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[Chapter import] Guessed video frame rate %g (%u:%u)\n", import_fps, ts, inc));
-               break;
-       }
-
-
-       cur_chap = 0;
-       ts = 0;
-       state = 0;
-       while (fgets(line, 1024, f) != NULL) {
-               char *title = NULL;
-               u32 off = 0;
-               char *sL;
-               while (1) {
-                       u32 len = strlen(line);
-                       if (!len) break;
-                       switch (line[len-1]) {
-                       case '\n': case '\t': case '\r': case ' ':
-                               line[len-1] = 0;
-                               continue;
-                       }
-                       break;
-               }
-
-               while (line[off]==' ') off++;
-               if (!strlen(line+off)) continue;
-               sL = line+off;
-
-               szTitle[0] = 0;
-               /*ZoomPlayer chapters*/
-               if (!strnicmp(sL, "AddChapter(", 11)) {
-                       u32 nb_fr;
-                       sscanf(sL, "AddChapter(%u,%s)", &nb_fr, szTitle);
-                       ts = nb_fr;
-                       ts *= 1000;
-                       if (import_fps) ts = (u64) (((s64) ts ) / import_fps);
-                       else ts /= 25;
-                       sL = strchr(sL, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0;
-               } else if (!strnicmp(sL, "AddChapterBySecond(", 19)) {
-                       u32 nb_s;
-                       sscanf(sL, "AddChapterBySecond(%u,%s)", &nb_s, szTitle);
-                       ts = nb_s;
-                       ts *= 1000;
-                       sL = strchr(sL, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0;
-               } else if (!strnicmp(sL, "AddChapterByTime(", 17)) {
-                       u32 h, m, s;
-                       sscanf(sL, "AddChapterByTime(%u,%u,%u,%s)", &h, &m, &s, szTitle);
-                       ts = 3600*h + 60*m + s;
-                       ts *= 1000;
-                       sL = strchr(sL, ',');
-                       if (sL) sL = strchr(sL+1, ',');
-                       if (sL) sL = strchr(sL+1, ',');
-                       strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0;
-               }
-               /*regular or SMPTE time codes*/
-               else if ((strlen(sL)>=8) && (sL[2]==':') && (sL[5]==':')) {
-                       title = NULL;
-                       if (strlen(sL)==8) {
-                               sscanf(sL, "%02u:%02u:%02u", &h, &m, &s);
-                               ts = (h*3600 + m*60+s)*1000;
-                       }
-                       else {
-                               char szTS[20], *tok;
-                               strncpy(szTS, sL, 18);
-                               tok = strrchr(szTS, ' ');
-                               if (tok) {
-                                       title = strchr(sL, ' ') + 1;
-                                       while (title[0]==' ') title++;
-                                       if (strlen(title)) strcpy(szTitle, title);
-                                       tok[0] = 0;
-                               }
-                               ts = 0;
-                               h = m = s = ms = 0;
-
-                               if (sscanf(szTS, "%u:%u:%u;%u/%u", &h, &m, &s, &fr, &fps)==5) {
-                                       ts = (h*3600 + m*60+s)*1000 + 1000*fr/fps;
-                               } else if (sscanf(szTS, "%u:%u:%u;%u", &h, &m, &s, &fr)==4) {
-                                       ts = (h*3600 + m*60+s);
-                                       if (import_fps)
-                                               ts = (s64) (((import_fps*((s64)ts) + fr) * 1000 ) / import_fps);
-                                       else
-                                               ts = ((ts*25 + fr) * 1000 ) / 25;
-                               } else if (sscanf(szTS, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
-                                       ts = (h*3600 + m*60+s)*1000+ms;
-                               } else if (sscanf(szTS, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
-                                       ts = (h*3600 + m*60+s)*1000+ms;
-                               } else if (sscanf(szTS, "%u:%u:%u:%u", &h, &m, &s, &ms) == 4) {
-                                       ts = (h*3600 + m*60+s)*1000+ms;
-                               } else if (sscanf(szTS, "%u:%u:%u", &h, &m, &s) == 3) {
-                                       ts = (h*3600 + m*60+s) * 1000;
-                               }
-                       }
-               }
-               /*CHAPTERX= and CHAPTERXNAME=*/
-               else if (!strnicmp(sL, "CHAPTER", 7)) {
-                       u32 idx;
-                       char szTemp[20], *str;
-                       strncpy(szTemp, sL, 19);
-                       str = strrchr(szTemp, '=');
-                       if (!str) continue;
-                       str[0] = 0;
-                       strlwr(szTemp);
-                       idx = cur_chap;
-                       str = strchr(sL, '=');
-                       str++;
-                       if (strstr(szTemp, "name")) {
-                               sscanf(szTemp, "chapter%uname", &idx);
-                               strcpy(szTitle, str);
-                               if (idx!=cur_chap) {
-                                       cur_chap=idx;
-                                       state = 0;
-                               }
-                               state++;
-                       } else {
-                               sscanf(szTemp, "chapter%u", &idx);
-                               if (idx!=cur_chap) {
-                                       cur_chap=idx;
-                                       state = 0;
-                               }
-                               state++;
-
-                               ts = 0;
-                               h = m = s = ms = 0;
-                               if (sscanf(str, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
-                                       ts = (h*3600 + m*60+s)*1000+ms;
-                               } else if (sscanf(str, "%u:%u:%u:%u", &h, &m, &s, &ms) == 4) {
-                                       ts = (h*3600 + m*60+s)*1000+ms;
-                               } else if (sscanf(str, "%u:%u:%u", &h, &m, &s) == 3) {
-                                       ts = (h*3600 + m*60+s) * 1000;
-                               }
-                       }
-                       if (state==2) {
-                               e = gf_isom_add_chapter(file, 0, ts, szTitle);
-                               if (e) goto err_exit;
-                               state = 0;
-                       }
-                       continue;
-               }
-               else continue;
-
-               if (strlen(szTitle)) {
-                       e = gf_isom_add_chapter(file, 0, ts, szTitle);
-               } else {
-                       e = gf_isom_add_chapter(file, 0, ts, NULL);
-               }
-               if (e) goto err_exit;
-       }
-
-
-err_exit:
-       fclose(f);
-       return e;
-}
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
@@ -1988,14 +805,16 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track)
        }
 
        if (subtype == GF_ISOM_SUBTYPE_AC3) {
+               GF_AC3Config *ac3 = gf_isom_ac3_config_get(mp4, track, 1);
                esd = gf_odf_desc_esd_new(0);
                esd->slConfig->timestampResolution = gf_isom_get_media_timescale(mp4, track);
                esd->ESID = gf_isom_get_track_id(mp4, track);
                esd->OCRESID = esd->ESID;
                esd->decoderConfig->streamType = GF_STREAM_AUDIO;
-               esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AC3;
+               esd->decoderConfig->objectTypeIndication = (ac3 && ac3->is_ec3) ? GPAC_OTI_AUDIO_AC3_ENHANCED : GPAC_OTI_AUDIO_AC3;
                gf_odf_desc_del((GF_Descriptor*)esd->decoderConfig->decoderSpecificInfo);
                esd->decoderConfig->decoderSpecificInfo = NULL;
+               if (ac3) gf_free(ac3);
                return esd;
        }
 
@@ -2060,3 +879,726 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track)
 
 #endif /*GPAC_DISABLE_ISOM*/
 
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
+static s32 gf_get_DQId(GF_ISOFile *file, u32 track)
+{
+       GF_AVCConfig *svccfg;
+       GF_ISOSample *samp;
+       u32 di = 0;
+       char *buffer;
+       GF_BitStream *bs;
+       u32 max_size = 4096;
+       u32 size, nalu_size_length;
+       u8 nal_type;
+
+       svccfg = gf_isom_svc_config_get(file, track, 1);
+       if (!svccfg)
+               return 0;
+       samp = gf_isom_get_sample(file, track, 1, &di);
+       if (!samp)
+               return -1;
+       bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ);
+       buffer = (char*)gf_malloc(sizeof(char) * max_size);
+       nalu_size_length = 8 * svccfg->nal_unit_size;
+       while (gf_bs_available(bs))
+       {
+               size = gf_bs_read_int(bs, nalu_size_length);
+               if (size>max_size) {
+                       buffer = (char*)gf_realloc(buffer, sizeof(char)*size);
+                       max_size = size;
+               }
+               gf_bs_read_data(bs, buffer, size);
+               nal_type = buffer[0] & 0x1F;
+               if (nal_type == GF_AVC_NALU_SVC_SLICE)
+                       return buffer[2] & 0x7F;
+       }
+       return -1;
+}
+static u32 gf_isom_get_track_id_max(GF_ISOFile *file)
+{
+       u32 num_track, i, trackID;
+       u32 max_id = 0;
+
+       num_track = gf_isom_get_track_count(file);
+       for (i = 1; i <= num_track; i++)
+       {
+               trackID = gf_isom_get_track_id(file, i);
+               if (max_id < trackID)
+                       max_id = trackID;
+       }
+
+       return max_id;
+}
+
+/* Split SVC layers */
+GF_EXPORT
+GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll)
+{
+       GF_AVCConfig *avccfg, *svccfg;
+       u32 num_svc_track, num_sample, svc_track, dst_track, ref_trackID, ref_trackNum, max_id;
+       u32 di, width, height, size, nalu_size_length;
+       u32 i, j, t;
+       GF_Err e; 
+       GF_AVCConfigSlot *slc;
+       AVCState avc;
+       s32 sps_id, pps_id;
+       GF_ISOSample *samp;
+       GF_BitStream *bs;
+       GF_BitStream ** sample_bs;
+       u8 nal_type, nal_hdr;
+       GF_ISOSample  *dst_samp;
+       GF_BitStream *dst_bs;
+       char *buffer; 
+       //u8 dependency_id, quality_id, temporal_id, avc_dependency_id, avc_quality_id;
+       u32 max_size = 4096;
+       s32 *sps_track, *sps, *pps;
+       u32 num_pps, num_sps;
+       u64 offset;
+       Bool is_splited;
+       Bool *first_sample_track;
+       u64 *first_DTS_track;
+       u32 NALUnitHeader;
+       u8 track_ref_index;
+       s8 sample_offset;
+       u32 data_offset;
+       u32 data_length;
+       u32 count, timescale;
+
+       avccfg = gf_isom_avc_config_get(file, track, 1);
+       svccfg = gf_isom_svc_config_get(file, track, 1);
+
+       is_splited = (avccfg) ? 0 : 1;
+
+       /*if we have not any SVC -> stop*/
+       if (!svccfg)
+               return GF_OK;
+
+       timescale = gf_isom_get_media_timescale(file, track);
+
+       num_sps = gf_list_count(svccfg->sequenceParameterSets);
+       num_pps = gf_list_count(svccfg->pictureParameterSets);
+       /*we have a splited file with 1 SVC / track*/
+       if (is_splited && num_pps == 1)
+       {
+               /*use 'all' mode -> stop*/
+               if (splitAll)
+                       return GF_OK;
+               /*use 'base' mode -> merge SVC tracks*/
+               else
+                       return gf_media_merge_svc(file, track, 0);
+       }
+       num_svc_track = splitAll ? num_sps : 1;
+       max_id = gf_isom_get_track_id_max(file);
+       di = 0;
+       
+       memset(&avc, 0, sizeof(AVCState));
+       avc.sps_active_idx = -1;
+       nalu_size_length = 8 * svccfg->nal_unit_size;
+       /*read all sps*/
+       sps =  (s32 *) gf_malloc(num_sps * sizeof(s32));
+       sps_track = (s32 *) gf_malloc(num_sps * sizeof(s32));
+       for (i = 0; i < num_sps; i++)
+       {
+               slc = gf_list_get(svccfg->sequenceParameterSets, i);
+               sps_id = AVC_ReadSeqInfo(slc->data+1, slc->size-1, &avc,0, NULL);
+               if (sps_id < 0) {
+                       return GF_NON_COMPLIANT_BITSTREAM;
+               }
+               sps[i] = sps_id;
+               sps_track[i] = i;
+       }
+       /*read all pps*/
+       pps =  (s32 *) gf_malloc(num_pps * sizeof(s32));
+       for (j = 0; j < num_pps; j++)
+       {
+               slc = gf_list_get(svccfg->pictureParameterSets, j);
+               pps_id = AVC_ReadPictParamSet(slc->data+1, slc->size-1, &avc);
+               if (pps_id < 0) {
+                       return GF_NON_COMPLIANT_BITSTREAM;
+               }
+               pps[j] = pps_id;
+       }
+       if (!is_splited)
+               ref_trackID = gf_isom_get_track_id(file, track);
+       else
+       {
+               gf_isom_get_reference(file, track, GF_ISOM_REF_BASE, 1, &ref_trackNum);
+               ref_trackID = gf_isom_get_track_id(file, ref_trackNum);
+       }
+       /*read first sample for determinating the order of SVC tracks*/
+       count = 0;
+       samp = gf_isom_get_sample(file, track, 1, &di);
+       if (!samp)
+               return GF_IO_ERR;
+       bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ);
+       offset = 0;
+       buffer = (char*)gf_malloc(sizeof(char) * max_size);
+       while (gf_bs_available(bs))
+       {
+               size = gf_bs_read_int(bs, nalu_size_length);
+               if (size>max_size) {
+                       buffer = (char*)gf_realloc(buffer, sizeof(char)*size);
+                       max_size = size;
+               }
+               nal_hdr = gf_bs_read_u8(bs);
+               nal_type = nal_hdr & 0x1F;
+               AVC_ParseNALU(bs, nal_hdr, &avc);
+               gf_bs_seek(bs, offset+nalu_size_length/8);
+               gf_bs_read_data(bs, buffer, size);
+               offset += size + nalu_size_length/8;
+               if (nal_type == GF_AVC_NALU_SVC_SLICE)
+               {
+                       /*verify the order of SPS, reorder if necessary*/
+                       if (avc.s_info.pps->sps_id != sps[count])
+                       {
+                               for (i = count+1; i < num_sps; i++)
+                               {
+                                       /*swap two SPS*/
+                                       if (avc.s_info.pps->sps_id == sps[i])
+                                       {
+                                               sps[i] = sps[count];
+                                               sps[count] = avc.s_info.pps->sps_id;
+                                               sps_track[count] = i;
+                                               break;
+                                       }
+                               }
+                               /*for testing: ensure that there are not two NALU which use the same SPS, so that we can use sps for separating layers*/
+                               assert(i < num_sps);
+                       }
+                       count++;
+               }
+       }
+       /*for testing: ensure that the number of SPS is equal to the number of SVC layers*/
+       assert(count == num_sps);
+
+       gf_free(buffer);
+       buffer = NULL;
+       
+       for (t = 0; t < num_svc_track; t++)
+       {
+               GF_AVCConfig *cfg;
+
+               e = GF_OK;
+               svc_track = gf_isom_new_track(file, t+1+max_id, GF_ISOM_MEDIA_VISUAL, timescale);
+               if (!svc_track) 
+               {
+                       e = gf_isom_last_error(file);
+                       return e;
+               }
+               gf_isom_set_track_enabled(file, svc_track, 1);
+               gf_isom_set_track_reference(file, svc_track, GF_ISOM_REF_BASE, ref_trackID);
+               cfg = gf_odf_avc_cfg_new();
+               cfg->complete_representation = 1; //SVC
+               e = gf_isom_svc_config_new(file, svc_track, cfg, NULL, NULL, &di);
+               if (e)
+                       return e;
+               if (splitAll)
+               {
+                       sps_id = sps[t];
+                       width = avc.sps[sps_id].width;
+                       height = avc.sps[sps_id].height;
+                       gf_isom_set_visual_info(file, svc_track, di, width, height);
+                       cfg->configurationVersion = 1;
+                       cfg->chroma_bit_depth = 8 + avc.sps[sps_id].chroma_bit_depth_m8;
+                       cfg->chroma_format = avc.sps[sps_id].chroma_format;
+                       cfg->luma_bit_depth = 8 + avc.sps[sps_id].luma_bit_depth_m8;
+                       cfg->profile_compatibility = avc.sps[sps_id].prof_compat;
+                       cfg->AVCLevelIndication = avc.sps[sps_id].level_idc;
+                       cfg->AVCProfileIndication = avc.sps[sps_id].profile_idc;
+                       cfg->nal_unit_size = svccfg->nal_unit_size;
+                       gf_list_add(cfg->sequenceParameterSets,  gf_list_get(svccfg->sequenceParameterSets, sps_track[t]));
+                       for (j = 0; j < num_pps; j++)
+                       {
+                               pps_id = pps[j];
+                               if (avc.pps[pps_id].sps_id == sps_id)
+                               {
+                                       gf_list_add(cfg->pictureParameterSets,  gf_list_get(svccfg->pictureParameterSets, j));
+                               }
+                       }
+               }
+               else
+               {
+                       for (i = 0; i < num_sps; i++)
+                       {
+                               sps_id = sps[i];
+                               width = avc.sps[sps_id].width;
+                               height = avc.sps[sps_id].height;
+                               gf_isom_set_visual_info(file, svc_track, di, width, height);
+                               cfg->configurationVersion = 1;
+                               cfg->chroma_bit_depth = 8 + avc.sps[sps_id].chroma_bit_depth_m8;
+                               cfg->chroma_format = avc.sps[sps_id].chroma_format;
+                               cfg->luma_bit_depth = 8 + avc.sps[sps_id].luma_bit_depth_m8;
+                               cfg->profile_compatibility = avc.sps[sps_id].prof_compat;
+                               cfg->AVCLevelIndication = avc.sps[sps_id].level_idc;
+                               cfg->AVCProfileIndication = avc.sps[sps_id].profile_idc;
+                               cfg->nal_unit_size = svccfg->nal_unit_size;
+                               gf_list_add(cfg->sequenceParameterSets,  gf_list_get(svccfg->sequenceParameterSets, sps_track[i]));
+                               for (j = 0; j < num_pps; j++)
+                               {
+                                       slc = gf_list_get(svccfg->pictureParameterSets, t);
+                                       pps_id = AVC_ReadPictParamSet(slc->data+1, slc->size-1, &avc);
+                                       if (pps_id < 0) {
+                                               return GF_NON_COMPLIANT_BITSTREAM;
+                                       }
+                                       if (avc.pps[pps_id].sps_id == sps_id)
+                                       {
+                                               gf_list_add(cfg->pictureParameterSets,  gf_list_get(svccfg->pictureParameterSets, j));
+                                       }
+                               }
+                       }
+               }
+               gf_isom_svc_config_update(file, svc_track, 1, cfg, 0);
+       }
+
+       num_sample = gf_isom_get_sample_count(file, track);
+       first_sample_track = (Bool *) gf_malloc((num_svc_track+1) * sizeof(Bool));
+       for (t = 0; t <= num_svc_track; t++)
+               first_sample_track[t] = 1;
+       first_DTS_track = (u64 *) gf_malloc((num_svc_track+1) * sizeof(u64));
+       for (t = 0; t <= num_svc_track; t++)
+               first_DTS_track[t] = 0;
+
+       for (i = 1; i <= num_sample; i++)
+       {
+               u32 *prev_layer;
+               u32 count_prev_layer;
+
+               prev_layer = (u32 *) gf_malloc(num_svc_track * sizeof(u32));
+               count_prev_layer = 0;
+               
+
+               samp = gf_isom_get_sample(file, track, i, &di);
+               if (!samp)
+                       return GF_IO_ERR;
+
+               /* Create (num_svc_track) SVC bitstreams + 1 AVC bitstream*/
+               sample_bs = (GF_BitStream **) gf_malloc(sizeof(GF_BitStream *) * (num_svc_track+1));
+               for (j = 0; j <= num_svc_track; j++)
+                       sample_bs[j] = (GF_BitStream *) gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+
+               bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ);
+               offset = 0;
+               buffer = (char*)gf_malloc(sizeof(char) * max_size);
+               while (gf_bs_available(bs))
+               {
+                       size = gf_bs_read_int(bs, nalu_size_length);
+                       if (size>max_size) {
+                               buffer = (char*)gf_realloc(buffer, sizeof(char)*size);
+                               max_size = size;
+                       }
+                       nal_hdr = gf_bs_read_u8(bs);
+                       nal_type = nal_hdr & 0x1F;
+                       AVC_ParseNALU(bs, nal_hdr, &avc);
+                       gf_bs_seek(bs, offset+nalu_size_length/8);
+                       gf_bs_read_data(bs, buffer, size);
+                       offset += size + nalu_size_length/8;
+                       
+                       switch (nal_type) {
+                               //case GF_AVC_NALU_SVC_PREFIX_NALU:
+                               case GF_AVC_NALU_SVC_SLICE:
+                                       dst_track = 0;
+                                       if (splitAll)
+                                       {
+                                               for (t = 0; t < num_svc_track; t++) // num_svc_track == num_pps
+                                               {
+                                                       if (sps_track[t] == (avc.s_info.pps)->sps_id)
+                                                       {
+                                                               dst_track = t + 1;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       else
+                                               dst_track = 1;
+                                       dst_bs = sample_bs[dst_track];
+                                       /*write extractor*/
+                                       if (!gf_bs_get_position(dst_bs))
+                                       {
+                                               //reference to base layer
+                                               gf_bs_write_int(dst_bs, 14, nalu_size_length); // extractor 's size = 14
+                                               NALUnitHeader = 0; //reset
+                                               NALUnitHeader |= 0x1F000000; // NALU type = 31
+                                               gf_bs_write_u32(dst_bs, NALUnitHeader);
+                                               //track_ref_index is a trackID, not a trackNum. So when rewrite, gf_isom_get_track_id must be used to find trackNum
+                                               track_ref_index = ref_trackID; 
+                                               gf_bs_write_u8(dst_bs, track_ref_index);
+                                               sample_offset = 0;
+                                               gf_bs_write_u8(dst_bs, sample_offset);
+                                               data_offset = 0;
+                                               gf_bs_write_u32(dst_bs, data_offset);
+                                               data_length = 0;
+                                               gf_bs_write_u32(dst_bs, data_length);
+                                               //reference to previous layer(s)
+                                               for (t = 0; t < count_prev_layer; t++)
+                                               {
+                                                       gf_bs_write_int(dst_bs, 14, nalu_size_length);
+                                                       NALUnitHeader = 0;
+                                                       NALUnitHeader |= 0x1F000000;
+                                                       gf_bs_write_u32(dst_bs, NALUnitHeader);
+                                                       track_ref_index = max_id + prev_layer[t];
+                                                       gf_bs_write_u8(dst_bs, track_ref_index);
+                                                       sample_offset = 0;
+                                                       gf_bs_write_u8(dst_bs, sample_offset);
+                                                       data_offset = (t+1) * (nalu_size_length/8 + 14); // (nalu_size_length/8) bytes of NALU length field + 14 bytes of extractor per layer
+                                                       gf_bs_write_u32(dst_bs, data_offset);
+                                                       data_length = 0;
+                                                       gf_bs_write_u32(dst_bs, data_length);
+                                               }
+                                       }
+                                       prev_layer[count_prev_layer] = dst_track;
+                                       count_prev_layer++;
+                                       break;
+                               default:
+                                       dst_bs = sample_bs[0];
+                       }
+
+                       gf_bs_write_int(dst_bs, size, nalu_size_length);
+                       gf_bs_write_data(dst_bs, buffer, size);
+               }
+
+               for (j = 0; j <= num_svc_track; j++)
+               {
+                       if (gf_bs_get_position(sample_bs[j]))
+                       {
+                               if (first_sample_track[j])
+                               {
+                                       first_sample_track[j] = 0;
+                                       first_DTS_track[j] = samp->DTS;
+                               }
+                               dst_samp = gf_isom_sample_new();
+                               dst_samp->CTS_Offset = samp->CTS_Offset;
+                               dst_samp->DTS = samp->DTS - first_DTS_track[j];
+                               dst_samp->IsRAP = samp->IsRAP;
+                               gf_bs_get_content(sample_bs[j], &dst_samp->data, &dst_samp->dataLength);
+                               if (j) //SVC
+                                       e = gf_isom_add_sample(file, track+j, di, dst_samp);
+                               else
+                                       e = gf_isom_update_sample(file, track, i, dst_samp, 1);
+                               if (e)
+                                       return e;
+                               gf_isom_sample_del(&dst_samp);
+                               dst_samp = NULL;
+                       }
+                       gf_bs_del(sample_bs[j]);
+                       sample_bs[j] = NULL;
+               }
+               gf_free(sample_bs);
+               gf_free(bs);
+       }
+
+       /*add Editlist entry if DTS of the first sample is not zero*/
+       for (t = 0; t <= num_svc_track; t++)
+       {
+               if (first_DTS_track[t])
+               {
+                       u32 media_ts, moov_ts, offset;
+                       u64 dur;
+                       media_ts = gf_isom_get_media_timescale(file, t);
+                       moov_ts = gf_isom_get_timescale(file);
+                       offset = (u32)(first_DTS_track[t]) * moov_ts / media_ts;
+                       dur = gf_isom_get_media_duration(file, t) * moov_ts / media_ts;
+                       gf_isom_set_edit_segment(file, t, 0, offset, 0, GF_ISOM_EDIT_EMPTY);
+                       gf_isom_set_edit_segment(file, t, offset, dur, 0, GF_ISOM_EDIT_NORMAL);
+               }
+       }
+       
+       /*if this is a merged file: delete SVC config*/
+       if (!is_splited)
+               gf_isom_svc_config_del(file, track, 1);
+       /*if this is as splited file: delete this track*/
+       else
+       {
+               gf_isom_remove_track(file, track);
+       }
+       return GF_OK;
+}
+
+/* Merge SVC layers*/
+GF_EXPORT
+GF_Err gf_media_merge_svc(GF_ISOFile *file, u32 track, Bool mergeAll)
+{
+       GF_AVCConfig *avccfg, *svccfg, *cfg;
+       u32 merge_track;
+       u32 num_track, num_sample;
+       GF_ISOSample *avc_samp, *samp, *dst_samp;
+       GF_BitStream *bs, *dst_bs;
+       GF_Err e;
+       u32 size;
+       u32 i, t;
+       u32 di = 0;
+       char *buffer;
+       u32 max_size = 4096;
+       u32 nalu_size_length;
+       u32 ref_trackNum, ref_trackID;
+       s32 *DQId;
+       u32 count;
+       u32 *list_track_sorted;
+       u32 *cur_sample, *max_sample;
+       u32 width = 0, height = 0;
+       u64 *DTS_offset;
+       u32 nb_EditList;
+       u32 media_ts, moov_ts;
+       u64 EditTime, SegmentDuration, MediaTime;
+       u8 EditMode;
+       Bool first_sample;
+       u64 first_DTS, offset, dur;
+       u32 max_id;
+       u32 timescale;
+       u8 nal_type;
+
+       avc_samp = samp = NULL;
+
+       avccfg = gf_isom_avc_config_get(file, track, 1);
+       if (!avccfg && mergeAll)
+               return GF_BAD_PARAM;
+       timescale = gf_isom_get_media_timescale(file, track);
+
+       num_track = gf_isom_get_track_count(file);
+       if (num_track == 1) {
+               if (avccfg) gf_odf_avc_cfg_del(avccfg);
+               return GF_OK;
+       }
+
+       /*create a new merged track*/
+       max_id = gf_isom_get_track_id_max(file);
+       merge_track = gf_isom_new_track(file, max_id+1, GF_ISOM_MEDIA_VISUAL, timescale);
+       gf_isom_set_track_enabled(file, merge_track, 1);
+       /*add avc configuration if any*/
+       if (avccfg)
+               gf_isom_avc_config_new(file, merge_track, avccfg, NULL, NULL, &di);
+
+       svccfg = gf_odf_avc_cfg_new();
+       svccfg->complete_representation = 1; 
+       e = gf_isom_svc_config_new(file, merge_track, svccfg, NULL, NULL, &di);
+       if (e) goto exit;
+
+       if (avccfg) {
+               ref_trackNum = track;
+               ref_trackID = gf_isom_get_track_id(file, track);
+       } else {
+               gf_isom_get_reference(file, track, GF_ISOM_REF_BASE, 1, &ref_trackNum);
+               ref_trackID = gf_isom_get_track_id(file, ref_trackNum);
+       }
+
+       list_track_sorted = (u32 *) gf_malloc(num_track * sizeof(u32));
+       DQId = (s32 *) gf_malloc(num_track * sizeof(s32));
+       count = 0;
+       for (t = 1; t <= num_track; t++) {
+               u32 pos = 0;
+               s32 track_DQId = gf_get_DQId(file, t);
+               if (track_DQId < 0) {
+                       e = GF_ISOM_INVALID_MEDIA;
+                       goto exit;
+               }
+               if ((t != track) && !gf_isom_has_track_reference(file, t, GF_ISOM_REF_BASE, ref_trackID))
+                       continue;
+               while ((pos < count ) && (DQId[pos] <= track_DQId))
+                       pos++;
+               for (i = count; i > pos; i--)
+               {
+                       list_track_sorted[i] = list_track_sorted[i-1];
+                       DQId[i] = DQId[i-1];
+               }
+               list_track_sorted[pos] = t;
+               DQId[pos] = track_DQId;
+               count++;
+       }
+
+       if (mergeAll)
+       {
+               gf_isom_get_visual_info(file, list_track_sorted[0], 1, &width, &height);
+       }
+       else
+       {
+               for (t = 0; t < count; t++)
+                       gf_isom_get_visual_info(file, list_track_sorted[t], 1, &width, &height);
+       }
+       gf_isom_set_visual_info(file, merge_track, 1, width, height);
+
+       for (t = 0; t < count; t++)
+       {
+               cfg = gf_isom_svc_config_get(file, list_track_sorted[t], 1);
+               if (!cfg)
+                       continue;
+               svccfg->configurationVersion = 1;
+               svccfg->chroma_bit_depth = cfg->chroma_bit_depth;
+               svccfg->chroma_format = cfg->chroma_format;
+               svccfg->luma_bit_depth = cfg->luma_bit_depth;
+               svccfg->profile_compatibility = cfg->profile_compatibility;
+               svccfg->AVCLevelIndication = cfg->AVCLevelIndication;
+               svccfg->AVCProfileIndication = cfg->AVCProfileIndication;
+               svccfg->nal_unit_size = cfg->nal_unit_size;
+               for (i = 0; i < gf_list_count(cfg->sequenceParameterSets); i++)
+               {
+                       gf_list_add(svccfg->sequenceParameterSets,  gf_list_get(cfg->sequenceParameterSets, i));
+                       }
+               for (i = 0; i < gf_list_count(cfg->pictureParameterSets); i++)
+               {
+                       gf_list_add(svccfg->pictureParameterSets, gf_list_get(cfg->pictureParameterSets, i));
+               }
+               if (mergeAll)
+                       gf_isom_svc_config_update(file, merge_track, 1, svccfg, 1);
+               else
+                       gf_isom_svc_config_update(file, merge_track, 1, svccfg, 0);
+               
+               gf_odf_avc_cfg_del(cfg);
+       }
+
+       cur_sample = (u32 *) gf_malloc(count * sizeof(u32));
+       max_sample = (u32 *) gf_malloc(count * sizeof(u32));
+       for (t = 0; t < count; t++)
+       {
+               cur_sample[t] = 1;
+               max_sample[t] = gf_isom_get_sample_count(file, list_track_sorted[t]);
+       }
+
+       DTS_offset = (u64 *) gf_malloc(count * sizeof(u64));
+       for (t = 0; t < count; t++)
+       {
+               nb_EditList = gf_isom_get_edit_segment_count(file, list_track_sorted[t]);
+               if (!nb_EditList)
+                       DTS_offset[t] = 0;
+               else
+               {
+                       media_ts = gf_isom_get_media_timescale(file, list_track_sorted[t]);
+                       moov_ts = gf_isom_get_timescale(file);
+                       for (i = 1; i <= nb_EditList; i++)
+                       {
+                               e = gf_isom_get_edit_segment(file, list_track_sorted[t], i, &EditTime, &SegmentDuration, &MediaTime, &EditMode);
+                               if (e) goto exit;
+
+                               if (!EditMode)
+                               {
+                                       DTS_offset[t] = SegmentDuration * media_ts / moov_ts;
+                               }
+                       }
+               }
+       }
+
+       num_sample = gf_isom_get_sample_count(file, ref_trackNum);
+       nalu_size_length = 8 * svccfg->nal_unit_size;
+       first_sample = 1;
+       first_DTS = 0;
+       for (i = 1; i <= num_sample; i++)
+       {
+               dst_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+               /*add extractor if nessassary*/
+               if (!mergeAll)
+               {
+                       u32 NALUnitHeader = 0;
+                       u8 track_ref_index;
+                       s8 sample_offset;
+                       u32 data_offset;
+                       u32 data_length;
+
+                       gf_bs_write_int(dst_bs, 14, nalu_size_length); // extractor 's size = 14
+                       NALUnitHeader |= 0x1F000000; // NALU type = 31
+                       gf_bs_write_u32(dst_bs, NALUnitHeader);
+                       track_ref_index = ref_trackID;
+                       gf_bs_write_u8(dst_bs, track_ref_index);
+                       sample_offset = 0;
+                       gf_bs_write_u8(dst_bs, sample_offset);
+                       data_offset = 0;
+                       gf_bs_write_u32(dst_bs, data_offset);
+                       data_length = 0;
+                       gf_bs_write_u32(dst_bs, data_length);
+               }
+               buffer = (char*)gf_malloc(sizeof(char) * max_size);
+
+               avc_samp = gf_isom_get_sample(file, ref_trackNum, i, &di);
+               if (!avc_samp) {
+                       e = gf_isom_last_error(file);
+                       goto exit;
+               }
+
+               for (t = 0; t < count; t++)
+               {
+                       if (cur_sample[t] > max_sample[t])
+                               continue;
+                       samp = gf_isom_get_sample(file, list_track_sorted[t], cur_sample[t], &di);
+                       if (!samp) {
+                               e = gf_isom_last_error(file);
+                               goto exit;
+                       }
+
+                       if ((samp->DTS + DTS_offset[t]) != avc_samp->DTS)
+                               continue;
+                       bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ);
+                       while (gf_bs_available(bs))
+                       {
+                               size = gf_bs_read_int(bs, nalu_size_length);
+                               if (size>max_size) {
+                                       buffer = (char*)gf_realloc(buffer, sizeof(char)*size);
+                                       max_size = size;
+                               }                       
+                               gf_bs_read_data(bs, buffer, size);
+                               nal_type = buffer[0] & 0x1F;
+                               /*skip extractor*/
+                               if (nal_type == 31)
+                                       continue;                       
+                               /*copy to new bitstream*/
+                               gf_bs_write_int(dst_bs, size, nalu_size_length);
+                               gf_bs_write_data(dst_bs, buffer, size);
+                       }
+                       gf_bs_del(bs);
+                       bs = NULL;
+                       gf_isom_sample_del(&samp);
+                       samp = NULL;
+                       cur_sample[t]++;
+               }
+               
+               /*add sapmle to track*/
+               if (gf_bs_get_position(dst_bs))
+               {
+                       if (first_sample)
+                       {
+                               first_DTS = avc_samp->DTS;
+                               first_sample = 0;
+                       }
+                       dst_samp = gf_isom_sample_new();
+                       dst_samp->CTS_Offset = avc_samp->CTS_Offset;
+                       dst_samp->DTS = avc_samp->DTS - first_DTS;
+                       dst_samp->IsRAP = avc_samp->IsRAP;
+                       gf_bs_get_content(dst_bs, &dst_samp->data, &dst_samp->dataLength);
+                       e = gf_isom_add_sample(file, merge_track, 1, dst_samp);
+                       gf_bs_del(dst_bs);
+                       dst_bs = NULL;
+                       gf_isom_sample_del(&dst_samp);
+                       if (e)
+                               goto exit;
+               }
+               gf_isom_sample_del(&avc_samp);
+               avc_samp = NULL;
+       }
+
+       /*Add EditList if nessessary*/
+       if (!first_DTS)
+       {
+               media_ts = gf_isom_get_media_timescale(file, merge_track);
+               moov_ts = gf_isom_get_timescale(file);
+               offset = (u32)(first_DTS) * moov_ts / media_ts;
+               dur = gf_isom_get_media_duration(file, merge_track) * moov_ts / media_ts;
+               gf_isom_set_edit_segment(file, merge_track, 0, offset, 0, GF_ISOM_EDIT_EMPTY);
+               gf_isom_set_edit_segment(file, merge_track, offset, dur, 0, GF_ISOM_EDIT_NORMAL);
+       }
+
+       /*Delete SVC track(s) that references to ref_track*/
+       for (t = 1; t <= num_track; t++)
+       {
+               if ((t != track) && !gf_isom_has_track_reference(file, t, GF_ISOM_REF_BASE, ref_trackID))
+                       continue;
+               gf_isom_remove_track(file, t);
+               num_track--; //we removed one track from file
+               t--;
+       }
+
+exit:
+       if (avc_samp) gf_isom_sample_del(&avc_samp);
+       if (samp) gf_isom_sample_del(&samp);
+       if (avccfg) gf_odf_avc_cfg_del(avccfg);
+       if (svccfg) gf_odf_avc_cfg_del(svccfg);
+       return e;
+}
+
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
+
index ac98067ac289675ea253ee184c2557a5cfb2791a..ed1f57855d3295a851866fad91472ebca393f2de 100644 (file)
@@ -1,8 +1,9 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *    Copyright (c)2008-200X Telecom ParisTech - All rights reserved
- *                     Authors: Jean Le Feuvre
+ *                     Authors: Jean Le Feuvre , Cyril Concolato, Romain Bouqueau
+ *                     Copyright (c) Telecom ParisTech 2000-2012
+ *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG2-TS sub-project
  *
@@ -26,7 +27,7 @@
 #include <gpac/constants.h>
 #include <gpac/media_tools.h>
 
-#if !defined(GPAC_DISABLE_MPEG2TS_MUX) && !defined(GPAC_DISABLE_MPEG2TS)
+#if !defined(GPAC_DISABLE_MPEG2TS_MUX)
 
 /*num ms between PCR*/
 #define PCR_UPDATE_MS  200
@@ -400,7 +401,7 @@ void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16
        /*MPEG-4 tables are input streams for the mux, the bitrate is updated when fetching AUs*/
 }
 
-static u32 gf_m2ts_add_adaptation(GF_BitStream *bs, u16 pid,  
+static u32 gf_m2ts_add_adaptation(GF_M2TS_Mux_Program *prog, GF_BitStream *bs, u16 pid,  
                                   Bool has_pcr, u64 pcr_time, 
                                   Bool is_rap, 
                                   u32 padding_length)
@@ -425,10 +426,13 @@ static u32 gf_m2ts_add_adaptation(GF_BitStream *bs, u16 pid,
                gf_bs_write_int(bs,     0, 6); // reserved
                PCR_ext = pcr_time - PCR_base*300;
                gf_bs_write_long_int(bs, PCR_ext, 9);
-
+               if (prog->last_pcr > pcr_time) {
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Sending PCR "LLD" earlier than previous PCR "LLD" - drift %f sec\n", pid, pcr_time, prog->last_pcr, (prog->last_pcr - pcr_time) /27000000.0 ));
+               }
+               prog->last_pcr = pcr_time;
 
 #ifndef GPAC_DISABLE_LOG
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding adaptation field size %d - RAP %d - Padding %d - PCR %d\n", pid, adaptation_length, is_rap, padding_length, pcr_time));
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding adaptation field size %d - RAP %d - Padding %d - PCR "LLD"\n", pid, adaptation_length, is_rap, padding_length, pcr_time));
        } else {
                GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding adaptation field size %d - RAP %d - Padding %d\n", pid, adaptation_length, is_rap, padding_length));
 #endif
@@ -495,7 +499,7 @@ void gf_m2ts_mux_table_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet)
        else stream->continuity_counter=0;
 
        if (adaptation_field_control != GF_M2TS_ADAPTATION_NONE)
-               gf_m2ts_add_adaptation(bs, stream->pid, 0, 0, 0, padding_length);
+               gf_m2ts_add_adaptation(stream->program, bs, stream->pid, 0, 0, 0, padding_length);
 
        /*pointer field*/
        if (!stream->current_section_offset) {
@@ -702,6 +706,10 @@ static void gf_m2ts_remap_timestamps_for_pes(GF_M2TS_Mux_Stream *stream, u32 pck
                GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: DTS "LLD" is less than initial DTS "LLD" - adjusting\n", stream->pid, *dts, stream->program->initial_ts));
                stream->program->initial_ts = *dts;
        }
+       else if (*dts < stream->last_dts) {
+               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: DTS "LLD" is less than last sent DTS "LLD"\n", stream->pid, *dts, stream->last_dts));
+               stream->last_dts = *dts;
+       }
 
        /*offset our timestamps*/
        *cts += stream->program->pcr_offset;
@@ -786,7 +794,6 @@ u32 gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream
        if (!(stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS))
                stream->curr_pck.dts = stream->curr_pck.cts;
 
-
        /*initializing the PCR*/
        if (!stream->program->pcr_init_time) {
                if (stream==stream->program->pcr) {
@@ -933,6 +940,8 @@ u32 gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream
                        GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
                        gf_m4a_get_config(stream->ifce->decoder_config, stream->ifce->decoder_config_size, &cfg);
 
+                       if (cfg.base_object_type>=5) cfg.base_object_type = GF_M4A_AAC_LC;
+
                        gf_bs_write_int(bs, 0xFFF, 12);/*sync*/
                        gf_bs_write_int(bs, 0, 1);/*mpeg2 aac*/
                        gf_bs_write_int(bs, 0, 2); /*layer*/
@@ -1171,7 +1180,7 @@ Bool gf_m2ts_stream_compute_pes_length(GF_M2TS_Mux_Stream *stream, u32 payload_l
        return 1;
 }
 
-
+u64 last_dts=0;
 static u32 gf_m2ts_stream_get_pes_header_length(GF_M2TS_Mux_Stream *stream)
 {
        u32 hdr_len, flags;
@@ -1229,7 +1238,7 @@ u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream,
        gf_bs_write_int(bs, 0x2, 2); // reserved
        gf_bs_write_int(bs, 0x0, 2); // scrambling
        gf_bs_write_int(bs, 0x0, 1); // priority
-       gf_bs_write_int(bs, 0x1, 1); // alignment indicator
+       gf_bs_write_int(bs, stream->pck_offset ? 0 : 1, 1); // alignment indicator - we could also check start codes to see if we are aligned at slice/video packet level
        gf_bs_write_int(bs, 0x0, 1); // copyright
        gf_bs_write_int(bs, 0x0, 1); // original or copy
        
@@ -1264,7 +1273,6 @@ u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream,
                gf_bs_write_long_int(bs, t, 15);
                gf_bs_write_int(bs, 1, 1); // marker bit
        }
-
        GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding PES header at PCR "LLD" - has PTS %d (%d) - has DTS %d (%d)\n", stream->pid, gf_m2ts_get_pcr(stream->program)/300, use_pts, cts, use_dts, dts));
 
        return pes_len+4; // 4 = start code + stream_id
@@ -1376,24 +1384,24 @@ void gf_m2ts_mux_pes_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet)
                u64 pcr = 0;
                if (needs_pcr) {
                        u32 now = gf_sys_clock();
-                       /*compute PCR*/
-                       if (stream->program->mux->real_time) {
+                       /*compute PCR - we disabled real-time clock for now and only insert PCR based on DTS / CTS*/
+                       if (0 && stream->program->mux->real_time) {
                                pcr = gf_m2ts_get_pcr(stream->program);
                        } else {
-                               pcr = (stream->curr_pck.dts - stream->program->pcr_offset) * 300;
+                               pcr = ( ((stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? stream->curr_pck.dts : stream->curr_pck.cts) - stream->program->pcr_offset) * 300;
                                if (pcr>stream->program->pcr_init_time) pcr -= stream->program->pcr_init_time;
                                else pcr = 0;
                        }
 
-                       //fprintf(stdout, "PCR Diff in ms %d - sys clock diff in ms %d - DTS diff %d\n", (u32) (pcr - stream->program->last_pcr) / 27000, now - stream->program->last_sys_clock, (stream->curr_pck.dts - stream->program->last_dts)/90);
+                       //fprintf(stderr, "PCR Diff in ms %d - sys clock diff in ms %d - DTS diff %d\n", (u32) (pcr - stream->program->last_pcr) / 27000, now - stream->program->last_sys_clock, (stream->curr_pck.dts - stream->program->last_dts)/90);
 
                        stream->program->last_sys_clock = now;
-                       stream->program->last_dts = stream->curr_pck.dts;
-                       stream->program->last_pcr = pcr;
+                       /*if stream does not use DTS, use CTS as base time for PCR*/
+                       stream->program->last_dts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? stream->curr_pck.dts : stream->curr_pck.cts;
                        stream->pcr_priority = 0;
                }
                is_rap = (hdr_len && (stream->curr_pck.flags & GF_ESI_DATA_AU_RAP) ) ? 1 : 0;
-               gf_m2ts_add_adaptation(bs, stream->pid, needs_pcr, pcr, is_rap, padding_length);
+               gf_m2ts_add_adaptation(stream->program, bs, stream->pid, needs_pcr, pcr, is_rap, padding_length);
        
                if (padding_length) 
                        stream->program->mux->tot_pes_pad_bytes += padding_length;
@@ -1445,7 +1453,7 @@ void gf_m2ts_mux_pes_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet)
                        pos += payload_to_copy;
                        copy_next = payload_length - payload_to_copy;
                        /*we might need a more than one*/
-                       while (1) {
+                       while (stream->pes_data_remain) {
                                u32 remain = 0;
                                Bool res = stream->process(stream->program->mux, stream);
                                if (!res) {
@@ -1645,6 +1653,9 @@ GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, str
                        stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG2;
                        break;
                case GPAC_OTI_AUDIO_AAC_MPEG4:
+               case GPAC_OTI_AUDIO_AAC_MPEG2_MP:
+               case GPAC_OTI_AUDIO_AAC_MPEG2_LCP:
+               case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP:
                        stream->mpeg2_stream_type = GF_M2TS_AUDIO_LATM_AAC;
                        stream->mpeg2_stream_type = GF_M2TS_AUDIO_AAC;
                        if (!ifce->repeat_rate) ifce->repeat_rate = 500;
@@ -2070,7 +2081,7 @@ send_pck:
                                drift += (muxer->time.sec - time.sec)*1000;
                                assert(muxer->time.sec > time.sec);
                        }
-//                     fprintf(stdout, "\nMux time - Packet PID %d time: %d ms\n", stream_to_process->pid, drift);
+//                     fprintf(stderr, "\nMux time - Packet PID %d time: %d ms\n", stream_to_process->pid, drift);
                }
                GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Send %s from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->tables ? "table" : "PES", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec));
 #endif
index 00b3cd0bd8ca4bfb9b3e711bddcc4c9f9cf70c3b..b8777bcd72574832f4bafd97b0c70730af0d5c16 100644 (file)
@@ -1,7 +1,7 @@
 /**
 *                      GPAC - Multimedia Framework C SDK
 *
-*                                      Authors: Pierre Souchay, Jean Le Feuvre
+*                      Authors: Pierre Souchay, Jean Le Feuvre
 *                      Copyright (c) Telecom ParisTech 2010-2012
 *                                      All rights reserved
 *
@@ -30,8 +30,7 @@
 #include <stdio.h>
 #include <gpac/network.h>
 
-/*#define MYLOG(xx) GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, xx )*/
-//#define MYLOG(xx) printf xx
+/*#define MYLOG(xx) GF_LOG(GF_LOG_INFO, GF_LOG_DASH, xx )*/
 #define MYLOG(xx)
 
 
@@ -233,19 +232,19 @@ GF_Err playlist_element_dump(const PlaylistElement * e, int indent) {
        int i;
        GF_Err r = GF_OK;
        for (i = 0 ; i < indent; i++)
-               printf(" ");
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, (" ") );
        if (e == NULL) {
-               printf("NULL PlaylistElement\n");
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8] NULL PlaylistElement\n"));
                return r;
        }
-       printf("PlayListElement[%p, title=%s, codecs=%s, duration=%d, bandwidth=%d, url=%s, type=%s]\n",
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8] PlayListElement[%p, title=%s, codecs=%s, duration=%d, bandwidth=%d, url=%s, type=%s]\n",
                (void*)e,
                e->title,
                e->codecs,
                e->durationInfo,
                e->bandwidth,
                e->url,
-               e->elementType == TYPE_STREAM ? "stream" : "playlist");
+               e->elementType == TYPE_STREAM ? "stream" : "playlist"));
        if (TYPE_PLAYLIST == e->elementType) {
                int sz;
                assert( e->element.playlist.elements);
@@ -264,17 +263,17 @@ GF_Err variant_playlist_dump(const VariantPlaylist * pl) {
        int i, count;
        GF_Err e = GF_OK;
        if (pl == NULL) {
-               printf("VariantPlaylist = NULL\n");
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8] VariantPlaylist = NULL\n"));
                return e;
        }
-       printf("VariantPlaylist = {\n");
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8] VariantPlaylist = {\n"));
        assert( pl->programs);
        count = gf_list_count( pl->programs);
        for (i = 0 ; i < count ; i++) {
                int j, countj;
                Program * p = gf_list_get(pl->programs, i);
                assert( p );
-               printf("  program[programId=%d]{\n",  p->programId);
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8] program[programId=%d]{\n",  p->programId));
                assert( p->bitrates );
                countj = gf_list_count(p->bitrates);
                for (j = 0; j < countj; j++) {
@@ -282,9 +281,9 @@ GF_Err variant_playlist_dump(const VariantPlaylist * pl) {
                        assert(el);
                        e |= playlist_element_dump( el, 4);
                }
-               printf("  }\n");
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8] }\n"));
        }
-       printf("}\n");
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[M3U8]}\n"));
        return e;
 }
 
@@ -316,6 +315,7 @@ typedef struct _s_accumulated_attributes {
        char * title;
        int durationInSeconds;
        int bandwidth;
+       int width, height;
        int programId;
        char * codecs;
        int targetDurationInSeconds;
@@ -433,7 +433,7 @@ static char ** parseAttributes(const char * line, s_accumulated_attributes * att
                /* Not Supported for now */
                return ret;
        }
-       ret = extractAttributes("#EXT-X-STREAM-INF:", line, 3);
+       ret = extractAttributes("#EXT-X-STREAM-INF:", line, 10);
        if (ret) {
                /* #EXT-X-STREAM-INF:[attribute=value][,attribute=value]* */
                i = 0;
@@ -454,6 +454,13 @@ static char ** parseAttributes(const char * line, s_accumulated_attributes * att
                                if (ret[i][intValue-1] == '"') {
                                        attributes->codecs = gf_strdup(&(ret[i][7]));
                                }
+                       } else if (safe_start_equals("RESOLUTION=", ret[i])) {
+                               u32 w, h;
+                               utility = &(ret[i][11]);
+                               if ((sscanf(utility, "%dx%d", &w, &h)==2) || (sscanf(utility, "%dx%d,", &w, &h)==2)) {
+                                       attributes->width = w;
+                                       attributes->height = h;
+                               }
                        }
                        i++;
                }
@@ -469,7 +476,7 @@ static char ** parseAttributes(const char * line, s_accumulated_attributes * att
                                        attributes->byteRangeStart = begin;
                                        attributes->byteRangeEnd = begin + size - 1;
                                } else {
-                                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER,("[M3U8] Invalid byte range %s\n", ret[0]));
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_DASH,("[M3U8] Invalid byte range %s\n", ret[0]));
                                }
                        }
                }
@@ -495,7 +502,7 @@ GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const
        s_accumulated_attributes attribs;
        f = gf_f64_open(file, "rt");
        if (!f) {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER,("[M3U8] Cannot Open m3u8 file %s for reading\n", file));
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH,("[M3U8] Cannot Open m3u8 file %s for reading\n", file));
                return GF_SERVICE_ERROR;
        }
        if (*playlist == NULL) {
@@ -529,14 +536,14 @@ GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const
                        continue;
                if (currentLineNumber == 1) {
                        /* Playlist MUST start with #EXTM3U */
-                       if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) {
+/*                     if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) {
                                fclose(f);
                                variant_playlist_del(pl);
-                               GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine));
+                               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine));
                                return GF_STREAM_NOT_FOUND;
                        }
                        continue;
-               }
+*/             }
                if (currentLine[0] == '#') {
                        /* A comment or a directive */
                        if (strncmp("#EXT", currentLine, 4)==0) {
@@ -562,7 +569,6 @@ GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const
                        }
                } else {
                        char * fullURL = currentLine;
-                       //printf("Line %d: '%s'\n", currentLineNumber, currentLine);
 
                        if (gf_url_is_local(currentLine)) {
                                /*
@@ -582,7 +588,6 @@ GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const
                                        fullURL = gf_url_concatenate(baseURL, currentLine);
                        }
                        assert( fullURL );
-                       /*printf("*** calculated full path = %s from %s and %s\n", fullURL, currentLine, baseURL);*/
                        }
                        {
                                u32 count;
@@ -646,6 +651,8 @@ GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const
                                        currentPlayList->title = attribs.title ? gf_strdup(attribs.title):NULL;
                                        currentPlayList->codecs = attribs.codecs ? gf_strdup(attribs.codecs):NULL;
                                        gf_list_add(program->bitrates, currentPlayList);
+                                       currentPlayList->width = attribs.width;
+                                       currentPlayList->height = attribs.height;
                                } else {
                                        /* Normal Playlist */
                                        assert( pl->programs);
index bf6b6cbec12e6e090921176d143775b0c4450bc5..d112e288015956e0b627fdfbabb7d467b8f3a3c2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
@@ -86,7 +87,7 @@ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track)
        op.b_o_s = 1;
        op.e_o_s = 0;
 
-       out = gf_f64_open(szName, "wb");
+       out = szName ? gf_f64_open(szName, "wb") : stdout;
        if (!out) return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName);
 
        theora_kgs = 0;
@@ -178,7 +179,7 @@ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track)
                gf_fwrite(og.body, 1, og.body_len, out);
        }
     ogg_stream_clear(&os);
-       fclose(out);
+       if (szName) fclose(out);
        return GF_OK;
 #endif
 }
@@ -252,7 +253,9 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper)
        GF_DecoderConfig *dcfg;
        GF_GenericSampleDescription *udesc;
        char szName[1000], szEXT[10], szNum[1000], *dsi;
+       char *ext_start = NULL;
        FILE *out;
+       Bool is_stdout=0;
        GF_BitStream *bs;
        u32 track, i, di, count, m_type, m_stype, dsi_size, is_mj2k;
 
@@ -403,11 +406,22 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper)
        }
        if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK;
 
+       ext_start = strrchr(dumper->out_name, '.');
+
+       if (dumper->out_name && !strcmp(dumper->out_name, "std"))
+               is_stdout = 1;
+
        if (dumper->sample_num) {
                GF_ISOSample *samp = gf_isom_get_sample(dumper->file, track, dumper->sample_num, &di);
                if (!samp) return GF_BAD_PARAM;
-               sprintf(szName, "%s_%d%s", dumper->out_name, dumper->sample_num, szEXT);
-               out = gf_f64_open(szName, "wb");
+               if (ext_start) {
+                       ext_start[0]=0;
+                       sprintf(szName, "%s_%d%s", dumper->out_name, dumper->sample_num, ext_start+1);
+                       ext_start[0]='.';
+               } else {
+                       sprintf(szName, "%s_%d%s", dumper->out_name, dumper->sample_num, szEXT);
+               }
+               out = is_stdout ? stdout : gf_f64_open(szName, "wb");
                bs = gf_bs_from_file(out, GF_BITSTREAM_WRITE);
                if (is_mj2k) 
                        write_jp2_file(bs, samp->data, samp->dataLength, dsi, dsi_size);
@@ -415,8 +429,11 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper)
                        gf_bs_write_data(bs, samp->data, samp->dataLength);
                gf_isom_sample_del(&samp);
                gf_bs_del(bs);
-               fclose(out);
-               if (dsi) gf_free(dsi);
+               
+               if (!is_stdout)
+                       fclose(out);
+               if (dsi)
+                       gf_free(dsi);
                return GF_OK;
        }
 
@@ -425,12 +442,23 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper)
                GF_ISOSample *samp = gf_isom_get_sample(dumper->file, track, i+1, &di);
                if (!samp) break;
 
-               if (count>=1000) {
-                       sprintf(szName, "%s_%08d%s", dumper->out_name, i+1, szEXT);
+               if (ext_start) {
+                       ext_start[0]=0;
+                       if (count>=1000) {
+                               sprintf(szName, "%s_%08d%s", dumper->out_name, dumper->sample_num, ext_start+1);
+                       } else {
+                               sprintf(szName, "%s_%03d%s", dumper->out_name, dumper->sample_num, ext_start+1);
+                       }
+                       ext_start[0]='.';
                } else {
-                       sprintf(szName, "%s_%03d%s", dumper->out_name, i+1, szEXT);
+                       if (count>=1000) {
+                               sprintf(szName, "%s_%08d%s", dumper->out_name, i+1, szEXT);
+                       } else {
+                               sprintf(szName, "%s_%03d%s", dumper->out_name, i+1, szEXT);
+                       }
                }
-               out = gf_f64_open(szName, "wb");
+
+               out = is_stdout ? stdout : gf_f64_open(szName, "wb");
                bs = gf_bs_from_file(out, GF_BITSTREAM_WRITE);
                if (dsi) gf_bs_write_data(bs, dsi, dsi_size);
                if (is_mj2k) 
@@ -440,7 +468,8 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper)
                gf_isom_sample_del(&samp);
                gf_set_progress("Media Export", i+1, count);
                gf_bs_del(bs);
-               fclose(out);
+               if (!is_stdout)
+                       fclose(out);
                if (dumper->flags & GF_EXPORT_DO_ABORT) break;
        }
        if (dsi) gf_free(dsi);
@@ -582,6 +611,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
        return GF_NOT_SUPPORTED;
 #else
        GF_Err e = GF_OK;
+       Bool add_ext;
        GF_DecoderConfig *dcfg;
        GF_GenericSampleDescription *udesc;
        char szName[1000], szEXT[5], GUID[16];
@@ -595,6 +625,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
        u32 aac_type, is_aac;
        char *dsi;
        QCPRateTable rtable[8];
+       Bool is_stdout=0;
 
        dsi_size = 0;
        dsi = NULL;
@@ -608,6 +639,8 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
        m_type = gf_isom_get_media_type(dumper->file, track);
        m_stype = gf_isom_get_media_subtype(dumper->file, track, 1);
        has_qcp_pad = 0;
+       if (dumper->out_name && !strcmp(dumper->out_name, "std")) 
+               is_stdout = 1;
 
        is_aac = aac_type = 0;
        qcp_type = 0;
@@ -618,6 +651,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
        if ((m_stype==GF_ISOM_SUBTYPE_MPEG4) || (m_stype==GF_ISOM_SUBTYPE_MPEG4_CRYP)) 
                dcfg = gf_isom_get_decoder_config(dumper->file, track, 1);
 
+       add_ext = (dumper->out_name && strrchr(dumper->out_name , '.')==NULL) ? 1 : 0;
        strcpy(szName, dumper->out_name ? dumper->out_name : "");
        if (dcfg) {
                switch (dcfg->streamType) {
@@ -627,16 +661,19 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                                dsi = dcfg->decoderSpecificInfo->data;
                                dcfg->decoderSpecificInfo->data = NULL;
                                dsi_size = dcfg->decoderSpecificInfo->dataLength;
-                               strcat(szName, ".cmp");
+                               if (add_ext) 
+                                       strcat(szName, ".cmp");
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-4 Visual stream to cmp");
                                break;
                        case GPAC_OTI_VIDEO_AVC:
                                avccfg = gf_isom_avc_config_get(dumper->file, track, 1);
-                               strcat(szName, ".h264");
+                               if (add_ext) 
+                                       strcat(szName, ".h264");
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AVC-H264 stream to h264");
                                break;
                        case GPAC_OTI_VIDEO_MPEG1:
-                               strcat(szName, ".m1v");
+                               if (add_ext) 
+                                       strcat(szName, ".m1v");
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-1 Visual stream to m1v");
                                break;
                        case GPAC_OTI_VIDEO_MPEG2_SIMPLE: 
@@ -645,19 +682,23 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                        case GPAC_OTI_VIDEO_MPEG2_SPATIAL: 
                        case GPAC_OTI_VIDEO_MPEG2_HIGH: 
                        case GPAC_OTI_VIDEO_MPEG2_422: 
-                               strcat(szName, ".m2v");
+                               if (add_ext) 
+                                       strcat(szName, ".m2v");
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-2 Visual stream to m2v");
                                break;
                        case GPAC_OTI_IMAGE_JPEG:
-                               strcat(szName, ".jpg");
+                               if (add_ext) 
+                                       strcat(szName, ".jpg");
                                gf_export_message(dumper, GF_OK, "Extracting JPEG image");
                                break;
                        case GPAC_OTI_IMAGE_PNG:
-                               strcat(szName, ".png");
+                               if (add_ext) 
+                                       strcat(szName, ".png");
                                gf_export_message(dumper, GF_OK, "Extracting PNG image");
                                break;
                        case GPAC_OTI_MEDIA_OGG:
-                               strcat(szName, ".ogg");
+                               if (add_ext) 
+                                       strcat(szName, ".ogg");
                                gf_export_message(dumper, GF_OK, "Extracting Ogg video");
                                is_ogg = 1;
                                break;
@@ -674,7 +715,8 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                                dsi = dcfg->decoderSpecificInfo->data;
                                dcfg->decoderSpecificInfo->data = NULL;
                                dsi_size = dcfg->decoderSpecificInfo->dataLength;
-                               strcat(szName, ".aac");
+                               if (add_ext) 
+                                       strcat(szName, ".aac");
                                is_aac = 1;
                                aac_type = dcfg->objectTypeIndication - GPAC_OTI_AUDIO_AAC_MPEG2_MP;
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-2 AAC");
@@ -689,21 +731,25 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                                dcfg->decoderSpecificInfo->data = NULL;
                                dsi_size = dcfg->decoderSpecificInfo->dataLength;
                                is_aac = 2;
-                               strcat(szName, ".aac");
+                               if (add_ext) 
+                                       strcat(szName, ".aac");
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AAC");
                                break;
                        case GPAC_OTI_AUDIO_MPEG2_PART3:
                        case GPAC_OTI_AUDIO_MPEG1:
-                               strcat(szName, ".mp3");
+                               if (add_ext) 
+                                       strcat(szName, ".mp3");
                                gf_export_message(dumper, GF_OK, "Extracting MPEG-1/2 Audio (MP3)");
                                break;
                        case GPAC_OTI_MEDIA_OGG:
-                               strcat(szName, ".ogg");
+                               if (add_ext) 
+                                       strcat(szName, ".ogg");
                                is_ogg = 1;
                                gf_export_message(dumper, GF_OK, "Extracting Ogg audio");
                                break;
                        case GPAC_OTI_AUDIO_13K_VOICE:
-                               strcat(szName, ".qcp"); qcp_type = 1;
+                               if (add_ext) 
+                                       strcat(szName, ".qcp"); qcp_type = 1;
                                memcpy(GUID, QCP_QCELP_GUID_1, sizeof(char)*16);
                                gf_export_message(dumper, GF_OK, "Extracting QCELP-13K (QCP file)");
                                break;
@@ -739,7 +785,8 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                                dsi = dcfg->decoderSpecificInfo->data;
                                dcfg->decoderSpecificInfo->data = NULL;
                                dsi_size = dcfg->decoderSpecificInfo->dataLength;
-                               strcat(szName, ".idx");
+                               if (add_ext) 
+                                       strcat(szName, ".idx");
                                gf_export_message(dumper, GF_OK, "Extracting NeroDigital VobSub subpicture stream");
                                break;
                        default:
@@ -754,13 +801,16 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                gf_odf_desc_del((GF_Descriptor *) dcfg);
        } else {
                if (m_stype==GF_ISOM_SUBTYPE_3GP_AMR) {
-                       strcat(szName, ".amr");
+                       if (add_ext) 
+                               strcat(szName, ".amr");
                        gf_export_message(dumper, GF_OK, "Extracting AMR Audio");
                } else if (m_stype==GF_ISOM_SUBTYPE_3GP_AMR_WB) {
-                       strcat(szName, ".awb");
+                       if (add_ext) 
+                               strcat(szName, ".awb");
                        gf_export_message(dumper, GF_OK, "Extracting AMR WideBand Audio");
                } else if (m_stype==GF_ISOM_SUBTYPE_3GP_QCELP) {
-                       strcat(szName, ".qcp"); qcp_type = 1;
+                       if (add_ext) 
+                               strcat(szName, ".qcp"); qcp_type = 1;
                        memcpy(GUID, QCP_QCELP_GUID_1, sizeof(char)*16);
                        gf_export_message(dumper, GF_OK, "Extracting QCELP-13K (QCP file)");
                } else if (m_stype==GF_ISOM_SUBTYPE_3GP_EVRC) {
@@ -773,22 +823,28 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                        if (dumper->flags & GF_EXPORT_PROBE_ONLY) dumper->flags |= GF_EXPORT_USE_QCP;
                } else if (m_stype==GF_ISOM_SUBTYPE_3GP_H263) {
                        gf_export_message(dumper, GF_OK, "Extracting H263 Video");
-                       strcat(szName, ".263");
+                       if (add_ext) 
+                               strcat(szName, ".263");
                } else if (m_stype==GF_ISOM_SUBTYPE_3GP_DIMS) {
                        return gf_media_export_nhml(dumper, 1);
                } else if ((m_stype==GF_ISOM_SUBTYPE_AVC_H264) || (m_stype==GF_ISOM_SUBTYPE_AVC2_H264) || (m_stype==GF_ISOM_SUBTYPE_SVC_H264) ) {
                        avccfg = gf_isom_avc_config_get(dumper->file, track, 1);
-                       strcat(szName, ".h264");
+                       if (add_ext) 
+                               strcat(szName, ".h264");
                        gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AVC-H264 stream to h264");
                } else if (m_type==GF_ISOM_MEDIA_FLASH) {
                        gf_export_message(dumper, GF_OK, "Extracting Macromedia Flash Movie");
-                       strcat(szName, ".swf");
+                       if (add_ext) 
+                               strcat(szName, ".swf");
                } else if (m_stype==GF_ISOM_SUBTYPE_AC3) {
                        gf_export_message(dumper, GF_OK, "Extracting AC3 Audio");
-                       strcat(szName, ".ac3");
+                       if (add_ext) 
+                               strcat(szName, ".ac3");
                } else {
-                       strcat(szName, ".");
-                       strcat(szName, gf_4cc_to_str(m_stype));
+                       if (add_ext) {
+                               strcat(szName, ".");
+                               strcat(szName, gf_4cc_to_str(m_stype));
+                       }
                        udesc = gf_isom_get_generic_sample_description(dumper->file, track, 1);
                        if (udesc) {
                                dsi = udesc->extension_buf; udesc->extension_buf = NULL;
@@ -810,24 +866,29 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
                return GF_OK;
        }
 
-       if (is_ogg) return gf_dump_to_ogg(dumper, szName, track);
+       if (is_ogg) return gf_dump_to_ogg(dumper, is_stdout ? NULL : szName, track);
 
        if (is_vobsub) return gf_dump_to_vobsub(dumper, szName, track, dsi, dsi_size);
 
        if (qcp_type>1) {
                if (dumper->flags & GF_EXPORT_USE_QCP) {
-                       strcat(szName, ".qcp");
+                       if (add_ext) 
+                               strcat(szName, ".qcp");
                        gf_export_message(dumper, GF_OK, "Extracting %s audio (QCP file)", (qcp_type==2) ? "SMV" : "EVRC");
                } else if (qcp_type==2) {
-                       strcat(szName, ".smv");
+                       if (add_ext) 
+                               strcat(szName, ".smv");
                        gf_export_message(dumper, GF_OK, "Extracting SMV audio");
                } else {
-                       strcat(szName, ".evc");
+                       if (add_ext) 
+                               strcat(szName, ".evc");
                        gf_export_message(dumper, GF_OK, "Extracting EVRC audio");
                }
        }
 
-       if (dumper->out_name && (dumper->flags & GF_EXPORT_MERGE)) {
+       if (is_stdout) {
+               out = stdout;
+       } else if (dumper->out_name && (dumper->flags & GF_EXPORT_MERGE)) {
                out = gf_f64_open(dumper->out_name, "a+b");
                if (out) gf_f64_seek(out, 0, SEEK_END);
        } else {
@@ -1038,7 +1099,8 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
 
        if (avccfg) gf_odf_avc_cfg_del(avccfg);
        gf_bs_del(bs);
-       fclose(out);
+       if (!is_stdout) 
+               fclose(out);
        return e;
 #endif /*GPAC_DISABLE_AV_PARSERS*/
 }
@@ -1047,6 +1109,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper)
 static GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper)
 {
        GF_Err e;
+       Bool is_stdout = 0;
        u32 max_size, tot_size, num_samples, i;
        s32 size;
        char *comp, *frame;
@@ -1081,7 +1144,13 @@ static GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper)
                }
                gf_export_message(dumper, GF_OK, "Extracting AVI video (format %s) to %s", comp, szOutFile);
 
-               fout = gf_f64_open(szOutFile, "wb");
+               if (!strcmp(dumper->out_name, "std"))
+                       is_stdout = 1;
+               else if (strrchr(dumper->out_name, '.')) {
+                       strcpy(szOutFile, dumper->out_name);
+               } 
+
+               fout = is_stdout ? stdout : gf_f64_open(szOutFile, "wb");
 
                max_size = 0;
                frame = NULL;
@@ -1101,7 +1170,8 @@ static GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper)
                        gf_set_progress("AVI Extract", i+1, num_samples);
                }
                gf_free(frame);
-               fclose(fout);
+               if(!is_stdout)
+                       fclose(fout);
                fout = NULL;
                goto exit;
        }
@@ -1136,7 +1206,14 @@ static GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper)
        }
        sprintf(szOutFile, "%s.%s", dumper->out_name, comp);
        gf_export_message(dumper, GF_OK, "Extracting AVI %s audio", comp);
-       fout = gf_f64_open(szOutFile, "wb");
+
+       if (!strcmp(dumper->out_name, "std")) {
+               is_stdout = 1;
+       } else if (strrchr(dumper->out_name, '.')) {
+               strcpy(szOutFile, dumper->out_name);
+       } 
+
+       fout = is_stdout ? stdout : gf_f64_open(szOutFile, "wb");
        num_samples = 0;
        while (1) {
                Bool continuous;
@@ -1150,7 +1227,7 @@ static GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper)
 
 
 exit:
-       if (fout) fclose(fout);
+       if (fout && !is_stdout) fclose(fout);
        AVI_close(in);
        return e;
 }
@@ -1424,7 +1501,7 @@ GF_Err gf_media_export_isom(GF_MediaExporter *dumper)
 {
        GF_ISOFile *outfile;
        GF_Err e;
-       Bool add_to_iod;
+       Bool add_to_iod, is_stdout;
        char szName[1000], *ext;
        u32 track;
        u8 mode;
@@ -1441,13 +1518,17 @@ GF_Err gf_media_export_isom(GF_MediaExporter *dumper)
                dumper->flags |= GF_EXPORT_MERGE;
                return GF_OK;
        }
-       ext = (char *) gf_isom_get_filename(dumper->file);
-       if (ext) ext = strrchr(ext, '.');
-       sprintf(szName, "%s%s", dumper->out_name, ext ? ext : ".mp4");
-
+       if (strrchr(dumper->out_name, '.')) {
+               strcpy(szName, dumper->out_name);
+       } else {        
+               ext = (char *) gf_isom_get_filename(dumper->file);
+               if (ext) ext = strrchr(ext, '.');
+               sprintf(szName, "%s%s", dumper->out_name, ext ? ext : ".mp4");
+       }
+       is_stdout = (dumper->out_name && !strcmp(dumper->out_name, "std")) ? 1 : 0;
        add_to_iod = 1;
        mode = GF_ISOM_WRITE_EDIT;
-       if (dumper->flags & GF_EXPORT_MERGE) {
+       if (!is_stdout && (dumper->flags & GF_EXPORT_MERGE)) {
                FILE *t = gf_f64_open(szName, "rb");
                if (t) {
                        add_to_iod = 0;
@@ -1455,7 +1536,7 @@ GF_Err gf_media_export_isom(GF_MediaExporter *dumper)
                        fclose(t);
                }
        }
-       outfile = gf_isom_open(szName, mode, NULL);
+       outfile = gf_isom_open(is_stdout ? "std" : szName, mode, NULL);
 
        if (mode == GF_ISOM_WRITE_EDIT) {
                gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, 0xFF);
@@ -1513,7 +1594,11 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper)
        }
        if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK;
 
-       sprintf(szName, "%s.avi", dumper->out_name);
+       if (strrchr(dumper->out_name, '.')) {
+               strcpy(szName, dumper->out_name);
+       } else {
+               sprintf(szName, "%s.avi", dumper->out_name);
+       }
        avi_out = AVI_open_output_file(szName);
        if (!avi_out) {
                gf_odf_desc_del((GF_Descriptor *)esd);
@@ -1547,7 +1632,7 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper)
 
                /*compute VfW delay*/
                if (gf_isom_has_time_offset(dumper->file, track)) {
-                       u32 max_CTSO;
+                       s32 max_CTSO;
                        u64 DTS;
                        DTS = max_CTSO = 0;
                        for (i=0; i<count; i++) {
@@ -1681,7 +1766,7 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc)
                        if (mtype==GF_ISOM_MEDIA_VISUAL) {
                                fprintf(nhml, "codecVendor=\"%s\" codecVersion=\"%d\" codecRevision=\"%d\" ", gf_4cc_to_str(sdesc->vendor_code), sdesc->version, sdesc->revision);
                                fprintf(nhml, "width=\"%d\" height=\"%d\" compressorName=\"%s\" temporalQuality=\"%d\" spatialQuality=\"%d\" horizontalResolution=\"%d\" verticalResolution=\"%d\" bitDepth=\"%d\" ",
-                                       sdesc->width, sdesc->height, sdesc->compressor_name, sdesc->temporal_quality, sdesc->spacial_quality, sdesc->h_res, sdesc->v_res, sdesc->depth);
+                                       sdesc->width, sdesc->height, sdesc->compressor_name, sdesc->temporal_quality, sdesc->spatial_quality, sdesc->h_res, sdesc->v_res, sdesc->depth);
                        } else if (mtype==GF_ISOM_MEDIA_AUDIO) {
                                fprintf(nhml, "codecVendor=\"%s\" codecVersion=\"%d\" codecRevision=\"%d\" ", gf_4cc_to_str(sdesc->vendor_code), sdesc->version, sdesc->revision);
                                fprintf(nhml, "sampleRate=\"%d\" numChannels=\"%d\" bitsPerSample=\"%d\" ", sdesc->samplerate, sdesc->nb_channels, sdesc->bits_per_sample);
@@ -1833,6 +1918,7 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper)
        GF_SAFMuxer *mux;
        char *data;
        u32 size;
+       Bool is_stdout = 0;
        FILE *saf_f;
        SAFInfo safs[1024];
 
@@ -1895,9 +1981,11 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper)
        }
        gf_export_message(dumper, GF_OK, "SAF: Multiplexing %d tracks", s_count);
 
+       if (dumper->out_name && !strcmp(dumper->out_name, "std"))
+               is_stdout = 1;
        strcpy(out_file, dumper->out_name);
        strcat(out_file, ".saf");
-       saf_f = gf_f64_open(out_file, "wb");
+       saf_f = is_stdout ? stdout : gf_f64_open(out_file, "wb");
 
        samp_done = 0;
        while (samp_done<tot_samp) {
@@ -1925,7 +2013,8 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper)
                gf_fwrite(data, size, 1, saf_f);
                gf_free(data);
        }
-       fclose(saf_f);
+       if (!is_stdout)
+               fclose(saf_f);
 
        gf_saf_mux_del(mux);
        return GF_OK;
@@ -1960,6 +2049,7 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper)
        GF_M2TS_PES *stream;
        u32 i;
        u64 size, fsize, fdone;
+       Bool is_stdout=0;
        GF_M2TS_Demuxer *ts;
        FILE *src, *dst;
 
@@ -2006,7 +2096,6 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper)
                gf_m2ts_demux_del(ts);
                return gf_export_message(dumper, GF_URL_ERROR, "Cannot find PID %d in transport stream", dumper->trackID);
        }
-       gf_m2ts_reset_parsers(ts);
 
        sprintf(szFile, "%s_pid%d", dumper->out_name ? dumper->out_name : "", stream->pid);
        switch (stream->stream_type) {
@@ -2043,12 +2132,17 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper)
                gf_export_message(dumper, GF_OK, "Extracting Unknown stream to raw");
                break;
        }
-       dst = gf_f64_open(szFile, "wb");
+
+       if (dumper->out_name && !strcmp(dumper->out_name, "std"))
+               is_stdout=1;
+
+       dst = is_stdout ? stdout : gf_f64_open(szFile, "wb");
        if (!dst) {
                fclose(src);
                gf_m2ts_demux_del(ts);
                return gf_export_message(dumper, GF_IO_ERR, "Cannot open file %s for writing", szFile);
        }
+
        gf_m2ts_reset_parsers(ts);
        gf_f64_seek(src, 0, SEEK_SET);
        fdone = 0;
@@ -2064,7 +2158,9 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper)
                if (dumper->flags & GF_EXPORT_DO_ABORT) break;
        }
        gf_set_progress("MPEG-2 TS Extract", fsize, fsize);
-       fclose(dst);
+
+       if (!is_stdout)
+               fclose(dst);
        fclose(src);
        gf_m2ts_demux_del(ts);
        return GF_OK;
index e80f7087f8e96bb3d90f9fff3af8d4b7f9046d20..30c6365328cc7a0400f89cb99fc20bebdcb4daeb 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre, Romain Bouqueau, Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
@@ -170,8 +171,6 @@ static void get_video_timing(Double fps, u32 *timescale, u32 *dts_inc)
        }
 }
 
-
-
 static GF_Err gf_import_still_image(GF_MediaImporter *import, Bool mult_desc_allowed)
 {
        GF_BitStream *bs;
@@ -1038,8 +1037,6 @@ static GF_Err gf_import_avi_video(GF_MediaImporter *import)
        char *comp, *frame;
        avi_t *in;
 
-       if (import->trackID>1) return GF_OK;
-
        test = gf_f64_open(import->in_name, "rb");
        if (!test) return gf_import_message(import, GF_URL_ERROR, "Opening %s failed", import->in_name);
        fclose(test);
@@ -1069,7 +1066,10 @@ static GF_Err gf_import_avi_video(GF_MediaImporter *import)
                AVI_close(in);
                return GF_OK;
        }
-
+       if (import->trackID>1) {
+               AVI_close(in);
+               return GF_OK;
+       }
        destroy_esd = 0;
        frame = NULL;
        AVI_seek_start(in);
@@ -1399,11 +1399,10 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import)
        unsigned char temp[4];
        avi_t *in;
 
-       if (import->flags & GF_IMPORT_PROBE_ONLY) return GF_OK;
-
        /*video only, ignore*/
        if (import->trackID==1) return GF_OK;
 
+
        test = gf_f64_open(import->in_name, "rb");
        if (!test) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name);
        fclose(test);
@@ -1771,8 +1770,11 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import)
                                goto exit;
                        }
                        /*if not first sample and same DTS as previous sample, force DTS++*/
-                       if (i && (samp->DTS==sampDTS)) {
-                               samp->DTS++;
+                       if (i && (samp->DTS<=sampDTS)) {
+                               if (i+1 < num_samples) {
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[ISOM import] 0-duration sample detected at DTS %d - adjusting\n", samp->DTS));
+                               }
+                               samp->DTS = sampDTS + 1;
                        }
                        e = gf_isom_add_sample(import->dest, track, di, samp);
                }
@@ -1781,7 +1783,14 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import)
                gf_set_progress("Importing ISO File", i+1, num_samples);
                if (duration && (sampDTS > duration) ) break;
                if (import->flags & GF_IMPORT_DO_ABORT) break;
-               if (e) goto exit;
+               if (e)
+                       goto exit;
+       }
+
+       if (gf_isom_has_time_offset(import->orig, track_in)==2) {
+               e = gf_isom_set_composition_offset_mode(import->dest, track, 1);
+               if (e)
+                       goto exit;
        }
 
        if (import->esd) {
@@ -2652,7 +2661,7 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc)
                        sdesc.vendor_code = GF_4CC(att->value[0], att->value[1], att->value[2], att->value[3]);
                }
                else if (!stricmp(att->name, "temporalQuality")) sdesc.temporal_quality = atoi(att->value);
-               else if (!stricmp(att->name, "spatialQuality")) sdesc.spacial_quality = atoi(att->value);
+               else if (!stricmp(att->name, "spatialQuality")) sdesc.spatial_quality = atoi(att->value);
                else if (!stricmp(att->name, "horizontalResolution")) sdesc.h_res = atoi(att->value);
                else if (!stricmp(att->name, "verticalResolution")) sdesc.v_res = atoi(att->value);
                else if (!stricmp(att->name, "bitDepth")) sdesc.depth = atoi(att->value);
@@ -2677,6 +2686,9 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc)
                        }
                }
                else if (!stricmp(att->name, "content_script_types")) dims.content_script_types = att->value;
+               else if (!stricmp(att->name, "mime_type")) dims.mime_type = att->value;
+        else if (!stricmp(att->name, "media_namespace")) dims.mime_type = att->value;
+               else if (!stricmp(att->name, "media_schema_location")) dims.xml_schema_loc = att->value;
 
        }
        if (sdesc.samplerate && !timescale) timescale = sdesc.samplerate;
@@ -2780,7 +2792,16 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc)
                if (e) goto exit;
 
                gf_import_message(import, GF_OK, "3GPP DIMS import");
-       } else {
+    } else if (mtype == GF_ISOM_MEDIA_SUBM) {
+               track = gf_isom_new_track(import->dest, tkID, mtype, timescale);
+               if (!track) { e = gf_isom_last_error(import->dest); goto exit; }
+               e = gf_isom_new_generic_subtitle_description(import->dest, track, 
+                                                    (char *)dims.contentEncoding, (char *)dims.xml_schema_loc, (char *)dims.mime_type, 
+                                                    (sdesc.codec_tag == GF_4CC( 'm', 'e', 't', 'x' ) ? 1 : 0), 
+                                                    (import->flags & GF_IMPORT_USE_DATAREF) ? szMedia : NULL, NULL, &di);
+               if (e) goto exit;
+
+    } else {
                char szT[5];
                sdesc.extension_buf = specInfo;
                sdesc.extension_buf_size = specInfoSize;
@@ -3910,7 +3931,6 @@ restart_import:
                }
                switch (nal_type) {
                case GF_AVC_NALU_SVC_SUBSEQ_PARAM:
-                       if (import->flags & GF_IMPORT_SVC_NONE) break;
                        is_subseq = 1;
                case GF_AVC_NALU_SEQ_PARAM:
                        idx = AVC_ReadSeqInfo(buffer+1/*skip NALU type*/, nal_size-1, &avc, is_subseq, NULL);
@@ -3930,6 +3950,10 @@ restart_import:
                                        add_sps = 1;
                                }
                                dstcfg = svccfg;
+                               if (import->flags & GF_IMPORT_SVC_NONE) {
+                                       add_sps = 0;
+                                       skip_nal = 1;
+                               }
                        } else {
                                if ((avc.sps[idx].state & AVC_SPS_PARSED) && !(avc.sps[idx].state & AVC_SPS_DECLARED)) {
                                        avc.sps[idx].state |= AVC_SPS_DECLARED;
@@ -3940,7 +3964,11 @@ restart_import:
                        when concatenated bitstreams). Since we cannot put two SPS with the same idx in the decoder config, we keep them in the
                        video bitstream*/
                        if (avc.sps[idx].state & AVC_SUBSPS_DECLARED) {
-                               copy_size = nal_size;
+                               if (import->flags & GF_IMPORT_SVC_NONE) {
+                                       copy_size = 0;
+                               } else {
+                                       copy_size = nal_size;
+                               }
                        }
 
                        if (add_sps) {
@@ -3948,6 +3976,10 @@ restart_import:
                                dstcfg->profile_compatibility = avc.sps[idx].prof_compat;
                                dstcfg->AVCProfileIndication = avc.sps[idx].profile_idc;
                                dstcfg->AVCLevelIndication = avc.sps[idx].level_idc;
+                               dstcfg->chroma_format = avc.sps[idx].chroma_format;
+                               dstcfg->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8;
+                               dstcfg->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8;
+
                                slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
                                slc->size = nal_size;
                                slc->id = idx;
@@ -3956,8 +3988,8 @@ restart_import:
                                gf_list_add(dstcfg->sequenceParameterSets, slc);
                                /*disable frame rate scan, most bitstreams have wrong values there*/
                                if (detect_fps && avc.sps[idx].vui.timing_info_present_flag && avc.sps[idx].vui.fixed_frame_rate_flag
-                                       /*if detected FPS is greater than 120, assume wrong timing info*/
-                                       && (avc.sps[idx].vui.time_scale <= 120*avc.sps[idx].vui.num_units_in_tick)
+                                       /*if detected FPS is greater than 1000, assume wrong timing info*/
+                                       && (avc.sps[idx].vui.time_scale <= 1000*avc.sps[idx].vui.num_units_in_tick)
                                        ) {
                                        /*ISO/IEC 14496-10 n11084 Table E-6*/
 /* not used :                          u8 DeltaTfiDivisorTable[] = {1,1,1,2,2,2,2,3,3,4,6}; */
@@ -4081,7 +4113,10 @@ restart_import:
                        break;
 
                case GF_AVC_NALU_SVC_PREFIX_NALU:
-                       if (import->flags & GF_IMPORT_SVC_NONE) break;
+                       if (import->flags & GF_IMPORT_SVC_NONE) {
+                               copy_size = 0;
+                               break;
+                       }
                        assert(prev_nalu_prefix_size==0);
                        copy_size = nal_size;
                        break;
@@ -4098,7 +4133,11 @@ restart_import:
                                        }
                                }                               
                        }
-                       if (import->flags & GF_IMPORT_SVC_NONE) break;
+                       if (import->flags & GF_IMPORT_SVC_NONE) {
+                               skip_nal = 0;
+                               copy_size = 0;
+                               break;
+                       }
                        if (! skip_nal) {
                                copy_size = nal_size;
                                switch (avc.s_info.slice_type) {
@@ -4110,6 +4149,28 @@ restart_import:
                        break;
 
                case GF_AVC_NALU_SEQ_PARAM_EXT:
+                       idx = AVC_ReadSeqParamSetExtId(buffer+1/*skip NALU type*/, nal_size-1);
+                       if (idx<0) {
+                               e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Error parsing Sequence Param Extension");
+                               goto exit;
+                       }
+
+                       if (! (avc.sps[idx].state & AVC_SPS_EXT_DECLARED)) {
+                               avc.sps[idx].state |= AVC_SPS_EXT_DECLARED;
+
+                               slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
+                               slc->size = nal_size;
+                               slc->id = idx;
+                               slc->data = (char*)gf_malloc(sizeof(char)*slc->size);
+                               memcpy(slc->data, buffer, sizeof(char)*slc->size);
+
+                               if (!avccfg->sequenceParameterSetExtensions)
+                                       avccfg->sequenceParameterSetExtensions = gf_list_new();
+
+                               gf_list_add(avccfg->sequenceParameterSetExtensions, slc);
+                       }
+                       break;
+
                case GF_AVC_NALU_SLICE_AUX:
 
                default:
@@ -4293,17 +4354,30 @@ restart_import:
                                        is_paff = 1;
 
                                slice_is_ref = (avc.s_info.nal_unit_type==GF_AVC_NALU_IDR_SLICE);
-                               if (slice_is_ref) nb_idr++;
+                               if (slice_is_ref) 
+                                       nb_idr++;
                                slice_force_ref = 0;
 
                                /*we only indicate TRUE IDRs for sync samples (cf AVC file format spec).
                                SEI recovery should be used to build sampleToGroup & RollRecovery tables*/
                                if (first_nal) {
                                        first_nal = 0;
-                                       if (avc.sei.recovery_point.valid) {
+                                       if (avc.sei.recovery_point.valid || (import->flags & GF_IMPORT_FORCE_SYNC)) {
+                                               Bool bIntraSlice = AVC_SliceIsIntra(&avc);
+                                               assert(avc.s_info.nal_unit_type!=GF_AVC_NALU_IDR_SLICE || bIntraSlice);
+
                                                sei_recovery_frame_count = avc.sei.recovery_point.frame_cnt;
+
+                                               /*we allow to mark I-frames as sync on open-GOPs (with sei_recovery_frame_count=0) when forcing sync even when the SEI RP is not available*/
+                                               if (!avc.sei.recovery_point.valid && bIntraSlice) {
+                                                       sei_recovery_frame_count = 0;
+                                                       if (use_opengop_gdr == 1) {
+                                                               use_opengop_gdr = 2; /*avoid message flooding*/
+                                                               GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AVC Import] No valid SEI Recovery Point found although needed - forcing\n"));
+                                                       }
+                                               }
                                                avc.sei.recovery_point.valid = 0;
-                                               if ((import->flags & GF_IMPORT_FORCE_SYNC) && (sei_recovery_frame_count==0)) 
+                                               if (bIntraSlice && (import->flags & GF_IMPORT_FORCE_SYNC) && (sei_recovery_frame_count==0)) 
                                                        slice_force_ref = 1;
                                        }
                                        sample_is_rap = AVC_SliceIsIDR(&avc);
@@ -4371,7 +4445,7 @@ restart_import:
                                }
 
                                /*compute max delay (applicable when B slice are present)*/
-                               if (poc_diff && (s32)(cur_samp-(ref_frame-1)-last_poc/poc_diff)>(s32)max_total_delay) {
+                               if (ref_frame && poc_diff && (s32)(cur_samp-(ref_frame-1)-last_poc/poc_diff)>(s32)max_total_delay) {
                                        max_total_delay = cur_samp - (ref_frame-1) - last_poc/poc_diff;
                                }
                        }
@@ -4508,7 +4582,7 @@ restart_import:
        if (gf_list_count(avccfg->sequenceParameterSets) || !gf_list_count(svccfg->sequenceParameterSets) ) {
                gf_isom_avc_config_update(import->dest, track, 1, avccfg);
                if (gf_list_count(svccfg->sequenceParameterSets)) {
-                       gf_isom_svc_config_update(import->dest, track, 1, svccfg, 1);
+                               gf_isom_svc_config_update(import->dest, track, 1, svccfg, 1);
                }
        } else {
                gf_isom_svc_config_update(import->dest, track, 1, svccfg, 0);
@@ -5503,7 +5577,7 @@ void m2ts_rewrite_avc_sample(GF_MediaImporter *import, GF_TSImport *tsimp)
        start = 0;
        bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_WRITE);
        while (1) {
-               if (!samp->data[start+sc_pos] && !samp->data[start+sc_pos+1] && !samp->data[start+sc_pos+2] && (samp->data[start+sc_pos+3]==1)) {
+               if (!samp->data[sc_pos] && !samp->data[sc_pos+1] && !samp->data[sc_pos+2] && (samp->data[sc_pos+3]==1)) {
                        gf_bs_seek(bs, start);
                        gf_bs_write_u32(bs, (u32) sc_pos-start-4);
                        start = sc_pos;
@@ -6249,7 +6323,7 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import)
                if (tsimp.track) {
                        MP4T_RecomputeBitRate(import->dest, tsimp.track);
                        /* creation of the edit lists */
-                       if (es->first_dts != es->program->first_dts) {
+                       if ((es->first_dts != es->program->first_dts) && gf_isom_get_sample_count(import->dest, tsimp.track) ){
                                u32 media_ts, moov_ts, offset;
                                u64 dur;
                                media_ts = gf_isom_get_media_timescale(import->dest, tsimp.track);
@@ -6606,12 +6680,14 @@ GF_Err gf_import_ac3(GF_MediaImporter *import)
        if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo);
        import->esd->decoderConfig->decoderSpecificInfo = NULL;
 
-       cfg.acmod = hdr.acmod;
+       cfg.is_ec3 = 0;
+       cfg.nb_streams = 1;
        cfg.brcode = hdr.brcode;
-       cfg.bsid = hdr.bsid;
-       cfg.bsmod = hdr.bsmod;
-       cfg.fscod = hdr.fscod;
-       cfg.lfon = hdr.lfon;
+       cfg.streams[0].acmod = hdr.acmod;
+       cfg.streams[0].bsid = hdr.bsid;
+       cfg.streams[0].bsmod = hdr.bsmod;
+       cfg.streams[0].fscod = hdr.fscod;
+       cfg.streams[0].lfon = hdr.lfon;
 
        gf_isom_ac3_config_new(import->dest, track, &cfg, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di);
        gf_isom_set_audio_info(import->dest, track, di, sr, nb_chan, 16);
@@ -6667,6 +6743,252 @@ exit:
 }
 #endif
 
+GF_EXPORT
+GF_Err gf_media_import_chapters_file(GF_MediaImporter *import)
+{
+       int readen=0;
+       GF_Err e;
+       u32 state, offset;
+       u32 cur_chap;
+       u64 ts;
+       u32 i, h, m, s, ms, fr, fps;
+       char line[1024];
+       char szTitle[1024];
+       FILE *f = gf_f64_open(import->in_name, "rt");
+       if (!f) return GF_URL_ERROR;
+
+       readen = fread(line, 1, 4, f);
+       if (readen < 4){
+               e = GF_URL_ERROR;
+               goto err_exit;
+       }
+       offset = 0;
+       if ((line[0]==(char)(0xFF)) && (line[1]==(char)(0xFE))) {
+               if (!line[2] && !line[3]){
+                       e = GF_NOT_SUPPORTED;
+                       goto err_exit;
+               }
+               offset = 2;
+       } else if ((line[0]==(char)(0xFE)) && (line[1]==(char)(0xFF))) {
+               if (!line[2] && !line[3]){
+                       e = GF_NOT_SUPPORTED;
+                       goto err_exit;
+               }
+               offset = 2;
+       } else if ((line[0]==(char)(0xEF)) && (line[1]==(char)(0xBB)) && (line[2]==(char)(0xBF))) {
+               /*we handle UTF8 as asci*/
+               offset = 3;
+       } else {
+               offset = 0;
+       }
+       gf_f64_seek(f, offset, SEEK_SET);
+
+       if (import->flags & GF_IMPORT_PROBE_ONLY) {
+               Bool is_chap_or_sub = 0;
+               import->nb_tracks = 0;
+               while (!is_chap_or_sub && (fgets(line, 1024, f) != NULL)) {
+                       char *sep;
+                       strlwr(line);
+
+                       if (strstr(line, "addchapter(")) is_chap_or_sub = 1;
+                       else if (strstr(line, "-->")) is_chap_or_sub = 1;
+                       else if ((sep = strstr(line, "chapter")) != NULL) {
+                               sep+=7;
+                               if (!strncmp(sep+1, "name", 4)) is_chap_or_sub = 1;
+                               else if (!strncmp(sep+2, "name", 4)) is_chap_or_sub = 1;
+                               else if (!strncmp(sep+3, "name", 4)) is_chap_or_sub = 1;
+                               else if (strstr(line, "Zoom") || strstr(line, "zoom")) is_chap_or_sub = 1;
+                       }
+               }
+               fclose(f);
+               if (is_chap_or_sub) {
+                       import->nb_tracks = 1;
+                       import->tk_info[0].media_type = GF_4CC('C','H','A','P');
+                       import->tk_info[0].type = GF_4CC('t','e','x','t');
+                       return GF_OK;
+               }
+               return GF_NOT_SUPPORTED;
+       }
+
+       e = gf_isom_remove_chapter(import->dest, 0, 0);
+       if (e) goto err_exit;
+
+       if (!import->video_fps) {
+               /*try to figure out the frame rate*/
+               for (i=0; i<gf_isom_get_track_count(import->dest); i++) {
+                       GF_ISOSample *samp;
+                       u32 ts, inc;
+                       if (gf_isom_get_media_type(import->dest, i+1) != GF_ISOM_MEDIA_VISUAL) continue;
+                       if (gf_isom_get_sample_count(import->dest, i+1) < 20) continue;
+                       samp = gf_isom_get_sample_info(import->dest, 1, 2, NULL, NULL);
+                       inc = (u32) samp->DTS;
+                       if (!inc) inc=1;
+                       ts = gf_isom_get_media_timescale(import->dest, i+1);
+                       import->video_fps = ts;
+                       import->video_fps /= inc;
+                       gf_isom_sample_del(&samp);
+                       GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[Chapter import] Guessed video frame rate %g (%u:%u)\n", import->video_fps, ts, inc));
+                       break;
+               }
+               if (!import->video_fps) 
+                       import->video_fps = 25;
+       }
+
+       cur_chap = 0;
+       ts = 0;
+       state = 0;
+       while (fgets(line, 1024, f) != NULL) {
+               char *title = NULL;
+               u32 off = 0;
+               char *sL;
+               while (1) {
+                       u32 len = strlen(line);
+                       if (!len) break;
+                       switch (line[len-1]) {
+                       case '\n': case '\t': case '\r': case ' ':
+                               line[len-1] = 0;
+                               continue;
+                       }
+                       break;
+               }
+
+               while (line[off]==' ') off++;
+               if (!strlen(line+off)) continue;
+               sL = line+off;
+
+               szTitle[0] = 0;
+               /*ZoomPlayer chapters*/
+               if (!strnicmp(sL, "AddChapter(", 11)) {
+                       u32 nb_fr;
+                       sscanf(sL, "AddChapter(%u,%s)", &nb_fr, szTitle);
+                       ts = nb_fr;
+                       ts *= 1000;
+                       ts = (u64) (((s64) ts ) / import->video_fps);
+                       sL = strchr(sL, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0;
+               } else if (!strnicmp(sL, "AddChapterBySecond(", 19)) {
+                       u32 nb_s;
+                       sscanf(sL, "AddChapterBySecond(%u,%s)", &nb_s, szTitle);
+                       ts = nb_s;
+                       ts *= 1000;
+                       sL = strchr(sL, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0;
+               } else if (!strnicmp(sL, "AddChapterByTime(", 17)) {
+                       u32 h, m, s;
+                       sscanf(sL, "AddChapterByTime(%u,%u,%u,%s)", &h, &m, &s, szTitle);
+                       ts = 3600*h + 60*m + s;
+                       ts *= 1000;
+                       sL = strchr(sL, ',');
+                       if (sL) sL = strchr(sL+1, ',');
+                       if (sL) sL = strchr(sL+1, ',');
+                       strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0;
+               }
+               /*regular or SMPTE time codes*/
+               else if ((strlen(sL)>=8) && (sL[2]==':') && (sL[5]==':')) {
+                       title = NULL;
+                       if (strlen(sL)==8) {
+                               sscanf(sL, "%02u:%02u:%02u", &h, &m, &s);
+                               ts = (h*3600 + m*60+s)*1000;
+                       }
+                       else {
+                               char szTS[20], *tok;
+                               strncpy(szTS, sL, 18);
+                               tok = strrchr(szTS, ' ');
+                               if (tok) {
+                                       title = strchr(sL, ' ') + 1;
+                                       while (title[0]==' ') title++;
+                                       if (strlen(title)) strcpy(szTitle, title);
+                                       tok[0] = 0;
+                               }
+                               ts = 0;
+                               h = m = s = ms = 0;
+
+                               if (sscanf(szTS, "%u:%u:%u;%u/%u", &h, &m, &s, &fr, &fps)==5) {
+                                       ts = (h*3600 + m*60+s)*1000 + 1000*fr/fps;
+                               } else if (sscanf(szTS, "%u:%u:%u;%u", &h, &m, &s, &fr)==4) {
+                                       ts = (h*3600 + m*60+s);
+                                       ts = (s64) (((import->video_fps*((s64)ts) + fr) * 1000 ) / import->video_fps);
+                               } else if (sscanf(szTS, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
+                                       ts = (h*3600 + m*60+s)*1000+ms;
+                               } else if (sscanf(szTS, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
+                                       ts = (h*3600 + m*60+s)*1000+ms;
+                               } else if (sscanf(szTS, "%u:%u:%u:%u", &h, &m, &s, &ms) == 4) {
+                                       ts = (h*3600 + m*60+s)*1000+ms;
+                               } else if (sscanf(szTS, "%u:%u:%u", &h, &m, &s) == 3) {
+                                       ts = (h*3600 + m*60+s) * 1000;
+                               }
+                       }
+               }
+               /*CHAPTERX= and CHAPTERXNAME=*/
+               else if (!strnicmp(sL, "CHAPTER", 7)) {
+                       u32 idx;
+                       char szTemp[20], *str;
+                       strncpy(szTemp, sL, 19);
+                       str = strrchr(szTemp, '=');
+                       if (!str) continue;
+                       str[0] = 0;
+                       strlwr(szTemp);
+                       idx = cur_chap;
+                       str = strchr(sL, '=');
+                       str++;
+                       if (strstr(szTemp, "name")) {
+                               sscanf(szTemp, "chapter%uname", &idx);
+                               strcpy(szTitle, str);
+                               if (idx!=cur_chap) {
+                                       cur_chap=idx;
+                                       state = 0;
+                               }
+                               state++;
+                       } else {
+                               sscanf(szTemp, "chapter%u", &idx);
+                               if (idx!=cur_chap) {
+                                       cur_chap=idx;
+                                       state = 0;
+                               }
+                               state++;
+
+                               ts = 0;
+                               h = m = s = ms = 0;
+                               if (sscanf(str, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
+                                       ts = (h*3600 + m*60+s)*1000+ms;
+                               } else if (sscanf(str, "%u:%u:%u:%u", &h, &m, &s, &ms) == 4) {
+                                       ts = (h*3600 + m*60+s)*1000+ms;
+                               } else if (sscanf(str, "%u:%u:%u", &h, &m, &s) == 3) {
+                                       ts = (h*3600 + m*60+s) * 1000;
+                               }
+                       }
+                       if (state==2) {
+                               e = gf_isom_add_chapter(import->dest, 0, ts, szTitle);
+                               if (e) goto err_exit;
+                               state = 0;
+                       }
+                       continue;
+               }
+               else continue;
+
+               if (strlen(szTitle)) {
+                       e = gf_isom_add_chapter(import->dest, 0, ts, szTitle);
+               } else {
+                       e = gf_isom_add_chapter(import->dest, 0, ts, NULL);
+               }
+               if (e) goto err_exit;
+       }
+
+
+err_exit:
+       fclose(f);
+       return e;
+}
+
+GF_EXPORT
+GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import_fps)
+{
+       GF_MediaImporter import;
+       memset(&import, 0, sizeof(GF_MediaImporter));
+       import.dest = file;
+       import.in_name = chap_file;
+       import.video_fps = import_fps;
+       import.streamFormat = "CHAP";
+       return gf_media_import(&import);
+}
 
 GF_EXPORT
 GF_Err gf_media_import(GF_MediaImporter *importer)
@@ -6790,8 +7112,8 @@ GF_Err gf_media_import(GF_MediaImporter *importer)
        if (!strnicmp(ext, ".saf", 4) || !strnicmp(ext, ".lsr", 4) || !stricmp(fmt, "SAF") )
                return gf_import_saf(importer);
        /*text subtitles*/
-       if (!strnicmp(ext, ".srt", 4) || !strnicmp(ext, ".sub", 4) || !strnicmp(ext, ".ttxt", 5)
-               || !stricmp(fmt, "SRT") || !stricmp(fmt, "SUB") || !stricmp(fmt, "TEXT") ) {
+       if (!strnicmp(ext, ".srt", 4) || !strnicmp(ext, ".sub", 4) || !strnicmp(ext, ".ttxt", 5) || !strnicmp(ext, ".vtt", 4)
+               || !stricmp(fmt, "SRT") || !stricmp(fmt, "SUB") || !stricmp(fmt, "TEXT") || !stricmp(fmt, "VTT")) {
 #ifndef GPAC_DISABLE_TTXT
                        return gf_import_timed_text(importer);
 #else
@@ -6809,6 +7131,9 @@ GF_Err gf_media_import(GF_MediaImporter *importer)
        if (!strnicmp(ext, ".dml", 4) || !stricmp(fmt, "DIMS") )
                return gf_import_nhml_dims(importer, 1);
 
+       if (!strnicmp(ext, ".txt", 4) || !strnicmp(ext, ".chap", 5) || !stricmp(fmt, "CHAP") )
+               return gf_media_import_chapters_file(importer);
+
        /*try XML things*/
        xml_type = gf_xml_get_root_type(importer->in_name, &e);
        if (xml_type) {
@@ -6869,56 +7194,3 @@ GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level)
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
 
-#ifndef GPAC_DISABLE_ISOM_WRITE
-GF_EXPORT
-GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den)
-{
-       u32 tk_w, tk_h, stype;
-       GF_Err e;
-
-       e = gf_isom_get_visual_info(file, track, 1, &tk_w, &tk_h);
-       if (e) return e;
-
-       stype = gf_isom_get_media_subtype(file, track, 1);
-       if ((stype==GF_ISOM_SUBTYPE_AVC_H264) || (stype==GF_ISOM_SUBTYPE_AVC2_H264) ) {
-#ifndef GPAC_DISABLE_AV_PARSERS
-               GF_AVCConfig *avcc = gf_isom_avc_config_get(file, track, 1);
-               AVC_ChangePAR(avcc, ar_num, ar_den);
-               e = gf_isom_avc_config_update(file, track, 1, avcc);
-               gf_odf_avc_cfg_del(avcc);
-               if (e) return e;
-#endif
-       }
-       else if (stype==GF_ISOM_SUBTYPE_MPEG4) {
-               GF_ESD *esd = gf_isom_get_esd(file, track, 1);
-               if (!esd || !esd->decoderConfig || (esd->decoderConfig->streamType!=4) ) {
-                       if (esd)  gf_odf_desc_del((GF_Descriptor *) esd);
-                       return GF_NOT_SUPPORTED;
-               }
-#ifndef GPAC_DISABLE_AV_PARSERS
-               if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) {
-                       e = gf_m4v_rewrite_par(&esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength, ar_num, ar_den);
-                       if (!e) e = gf_isom_change_mpeg4_description(file, track, 1, esd);
-                       gf_odf_desc_del((GF_Descriptor *) esd);
-                       if (e) return e;
-               }
-#endif
-       } else {
-               return GF_BAD_PARAM;
-       }
-
-       e = gf_isom_set_pixel_aspect_ratio(file, track, 1, ar_num, ar_den);
-       if (e) return e;
-
-       if ((ar_den>=0) && (ar_num>=0)) {
-               if (ar_den) tk_w = tk_w * ar_num / ar_den;
-               else if (ar_num) tk_h = tk_h * ar_den / ar_num;
-       }
-       /*revert to full frame for track layout*/
-       else {
-               e = gf_isom_get_visual_info(file, track, 1, &tk_w, &tk_h);
-               if (e) return e;
-       }
-       return gf_isom_set_track_layout_info(file, track, tk_w<<16, tk_h<<16, 0, 0, 0);
-}
-#endif /*GPAC_DISABLE_ISOM_WRITE*/
index 21c6c7a9b851fb3fb3ad4cb7914b911dda5fb993..67727ee36a15b8eeae18a446ea9e9eb112a18360 100644 (file)
@@ -1,8 +1,8 @@
 /*
 *                      GPAC - Multimedia Framework C SDK
 *
-*                      Authors: Cyril Concolato - Jean Le Feuvre
-*                      Copyright (c) Telecom ParisTech 2010-
+ *                     Authors: Jean Le Feuvre, Cyril COncolato
+ *                     Copyright (c) Telecom ParisTech 2000-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / 3GPP/MPEG Media Presentation Description input module
 #include <gpac/internal/m3u8.h>
 #include <gpac/network.h>
 
+#ifndef _WIN32_WCE
+/*for mktime*/
+#include <time.h>
+#endif
 
 static Bool gf_mpd_parse_bool(char *attr)
 {
        if (!strcmp(attr, "true")) return 1;
+       if (!strcmp(attr, "1")) return 1;
        return 0;
 }
 
@@ -40,6 +45,14 @@ static char *gf_mpd_parse_string(char *attr)
        return gf_strdup(attr);
 }
 
+static Bool gf_mpd_valid_child(GF_MPD *mpd, GF_XMLNode *child)
+{
+       if (child->type != GF_XML_NODE_TYPE) return 0;
+       if (!mpd->xml_namespace && !child->ns) return 1;
+       if (mpd->xml_namespace && child->ns && !strcmp(mpd->xml_namespace, child->ns) ) return 1;
+       return 0;
+}
+
 static char *gf_mpd_parse_text_content(GF_XMLNode *child)
 {
        u32 child_index = 0;
@@ -60,6 +73,13 @@ static u32 gf_mpd_parse_int(char *attr)
        return atoi(attr);
 }
 
+static u64 gf_mpd_parse_long_int(char *attr)
+{
+       u64 longint;
+       sscanf(attr, LLU, &longint);
+       return longint;
+}
+
 static Double gf_mpd_parse_double(char *attr)
 {
        return atof(attr);
@@ -75,8 +95,49 @@ static GF_MPD_Fractional *gf_mpd_parse_frac(char *attr)
 
 static u64 gf_mpd_parse_date(char *attr)
 {
-       fprintf(stdout, "error: mpd parse date not implemented\n");
+#ifdef _WIN32_WCE
+       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] Parsing MPD date (%s) is not supported on Windows CE\n", attr));
+       return 0;
+#else
+       Bool ok = 0;
+       Bool neg_time_zone = 0;
+       u32 year, month, day, h, m;
+       s32 oh, om;
+       Float s;
+
+       h = m = 0;
+       s = 0;
+       oh = om = 0;
+       if (sscanf(attr, "%d-%d-%dT%d:%d:%gZ", &year, &month, &day, &h, &m, &s) == 6) 
+               ok = 1;
+       else if (sscanf(attr, "%d-%d-%dT%d:%d:%g-%d:%d", &year, &month, &day, &h, &m, &s, &oh, &om) == 8) {
+               neg_time_zone = 1;
+               ok = 1;
+       } else if (sscanf(attr, "%d-%d-%dT%d:%d:%g+%d:%d", &year, &month, &day, &h, &m, &s, &oh, &om) == 8) {
+               ok = 1;
+       }
+
+       if (ok) {
+               u64 res;
+               struct tm _t;
+               _t.tm_year = (year > 1900) ? year - 1900 : 0;
+               _t.tm_mon = month ? month - 1 : 0;
+               _t.tm_mday = day;
+               _t.tm_hour = h;
+               _t.tm_min = m;
+               _t.tm_sec = (u32) s;
+               res = mktime(&_t);
+               if (om || oh) {
+                       s32 diff = (60*oh + om)*60;
+                       if (neg_time_zone) diff = -diff;
+                       res = res + diff;
+               }
+               return res;
+       } else {
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MPD] Failed to parse MPD date %s - format not supported\n", attr));
+       }
        return 0;
+#endif
 }
 
 static u32 gf_mpd_parse_duration(char *duration) {
@@ -146,7 +207,7 @@ static GF_Err gf_mpd_parse_location(GF_MPD *mpd, GF_XMLNode *child)
 
 static GF_Err gf_mpd_parse_metrics(GF_MPD *mpd, GF_XMLNode *child)
 {
-       fprintf(stdout, "mpd metrics not implemented yet\n");
+       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] Metrics not implemented yet\n"));
        return GF_OK;
 }
 
@@ -238,7 +299,7 @@ static GF_MPD_URL *gf_mpd_parse_url(GF_XMLNode *root)
        return url;
 }
 
-static void gf_mpd_parse_segment_base_generic(GF_MPD_SegmentBase *seg, GF_XMLNode *root)
+static void gf_mpd_parse_segment_base_generic(GF_MPD *mpd, GF_MPD_SegmentBase *seg, GF_XMLNode *root)
 {
        GF_XMLAttribute *att;
        GF_XMLNode *child;
@@ -249,20 +310,20 @@ static void gf_mpd_parse_segment_base_generic(GF_MPD_SegmentBase *seg, GF_XMLNod
 
        while ( (att = gf_list_enum(root->attributes, &i)) ) {
                if (!strcmp(att->name, "timescale")) seg->timescale = gf_mpd_parse_int(att->value);
-               else if (!strcmp(att->name, "presentationTimeOffset")) seg->presentation_time_offset = gf_mpd_parse_int(att->value);
+               else if (!strcmp(att->name, "presentationTimeOffset")) seg->presentation_time_offset = gf_mpd_parse_long_int(att->value);
                else if (!strcmp(att->name, "indexRange")) seg->index_range = gf_mpd_parse_int(att->value);
                else if (!strcmp(att->name, "indexRangeExact")) seg->index_range_exact = gf_mpd_parse_bool(att->value);
        }
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "Initialization")) seg->initialization_segment = gf_mpd_parse_url(child);
                else if (!strcmp(child->name, "RepresentationIndex")) seg->representation_index = gf_mpd_parse_url(child);
        }
 }
 
-static GF_MPD_SegmentTimeline *gf_mpd_parse_segment_timeline(GF_XMLNode *root)
+static GF_MPD_SegmentTimeline *gf_mpd_parse_segment_timeline(GF_MPD *mpd, GF_XMLNode *root)
 {
        u32 i, j;
        GF_XMLAttribute *att;
@@ -274,7 +335,7 @@ static GF_MPD_SegmentTimeline *gf_mpd_parse_segment_timeline(GF_XMLNode *root)
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "S")) {
                        GF_MPD_SegmentTimelineEntry *segent;
                        GF_SAFEALLOC(segent, GF_MPD_SegmentTimelineEntry);
@@ -282,31 +343,34 @@ static GF_MPD_SegmentTimeline *gf_mpd_parse_segment_timeline(GF_XMLNode *root)
 
                        j = 0;
                        while ( (att = gf_list_enum(child->attributes, &j)) ) {
-                               if (!strcmp(att->name, "t")) segent->start_time = gf_mpd_parse_int(att->value);
-                               else if (!strcmp(att->name, "d")) segent->duration = gf_mpd_parse_int(att->value);
-                               else if (!strcmp(att->name, "r")) segent->repeat_count = gf_mpd_parse_int(att->value);
+                               if (!strcmp(att->name, "t")) 
+                                       segent->start_time = gf_mpd_parse_long_int(att->value);
+                               else if (!strcmp(att->name, "d")) 
+                                       segent->duration = gf_mpd_parse_int(att->value);
+                               else if (!strcmp(att->name, "r")) 
+                                       segent->repeat_count = gf_mpd_parse_int(att->value);
                        }
                }
        }
        return seg;
 }
 
-static GF_MPD_SegmentBase *gf_mpd_parse_segment_base(GF_XMLNode *root)
+static GF_MPD_SegmentBase *gf_mpd_parse_segment_base(GF_MPD *mpd, GF_XMLNode *root)
 {
        GF_MPD_SegmentBase *seg;
        GF_SAFEALLOC(seg, GF_MPD_SegmentBase);
        if (!seg) return NULL;
-       gf_mpd_parse_segment_base_generic(seg, root);
+       gf_mpd_parse_segment_base_generic(mpd, seg, root);
        return seg;
 }
 
-void gf_mpd_parse_multiple_segment_base(GF_MPD_MultipleSegmentBase *seg, GF_XMLNode *root)
+void gf_mpd_parse_multiple_segment_base(GF_MPD *mpd, GF_MPD_MultipleSegmentBase *seg, GF_XMLNode *root)
 {
        u32 i;
        GF_XMLAttribute *att;
        GF_XMLNode *child;
 
-       gf_mpd_parse_segment_base_generic((GF_MPD_SegmentBase*)seg, root);
+       gf_mpd_parse_segment_base_generic(mpd, (GF_MPD_SegmentBase*)seg, root);
        seg->start_number = (u32) -1;
 
        i = 0;
@@ -317,8 +381,8 @@ void gf_mpd_parse_multiple_segment_base(GF_MPD_MultipleSegmentBase *seg, GF_XMLN
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
-               if (!strcmp(child->name, "SegmentTimeline")) seg->segment_timeline = gf_mpd_parse_segment_timeline(child);
+               if (!gf_mpd_valid_child(mpd, child)) continue;
+               if (!strcmp(child->name, "SegmentTimeline")) seg->segment_timeline = gf_mpd_parse_segment_timeline(mpd, child);
                else if (!strcmp(child->name, "BitstreamSwitching")) seg->bitstream_switching_url = gf_mpd_parse_url(child);
        }
 }
@@ -342,7 +406,7 @@ static void gf_mpd_parse_segment_url(GF_List *container, GF_XMLNode *root)
        }
 }
 
-static GF_MPD_SegmentList *gf_mpd_parse_segment_list(GF_XMLNode *root)
+static GF_MPD_SegmentList *gf_mpd_parse_segment_list(GF_MPD *mpd, GF_XMLNode *root)
 {
        u32 i;
        GF_MPD_SegmentList *seg;
@@ -355,14 +419,14 @@ static GF_MPD_SegmentList *gf_mpd_parse_segment_list(GF_XMLNode *root)
 
        i = 0;
        while ( (att = gf_list_enum(root->attributes, &i)) ) {
-               if (strstr(att->name, "href") || strstr(att->name, "actuate")) {
-               } 
+               if (strstr(att->name, "href")) seg->xlink_href = gf_mpd_parse_string(att->value);
+               else if (strstr(att->name, "actuate")) seg->xlink_actuate_on_load = !strcmp(att->value, "onLoad") ? 1 : 0;
        }
-       gf_mpd_parse_multiple_segment_base((GF_MPD_MultipleSegmentBase *)seg, root);
+       gf_mpd_parse_multiple_segment_base(mpd, (GF_MPD_MultipleSegmentBase *)seg, root);
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "SegmentURL")) gf_mpd_parse_segment_url(seg->segment_URLs, child);
        }
        if (!gf_list_count(seg->segment_URLs)) {
@@ -372,7 +436,7 @@ static GF_MPD_SegmentList *gf_mpd_parse_segment_list(GF_XMLNode *root)
        return seg;
 }
 
-static GF_MPD_SegmentTemplate *gf_mpd_parse_segment_template(GF_XMLNode *root)
+static GF_MPD_SegmentTemplate *gf_mpd_parse_segment_template(GF_MPD *mpd, GF_XMLNode *root)
 {
        u32 i;
        GF_MPD_SegmentTemplate *seg;
@@ -386,10 +450,13 @@ static GF_MPD_SegmentTemplate *gf_mpd_parse_segment_template(GF_XMLNode *root)
                if (!strcmp(att->name, "media")) seg->media = gf_mpd_parse_string(att->value);
                else if (!strcmp(att->name, "index")) seg->index = gf_mpd_parse_string(att->value);
                else if (!strcmp(att->name, "initialization") ) seg->initialization = gf_mpd_parse_string(att->value);
-               else if (!strcmp(att->name, "initialisation") ) seg->initialization = gf_mpd_parse_string(att->value);
+               else if (!stricmp(att->name, "initialisation") || !stricmp(att->name, "initialization") ) {
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] Wrong spelling: got %s but expected \"initialization\" \n", att->name ));
+                       seg->initialization = gf_mpd_parse_string(att->value);
+               }
                else if (!strcmp(att->name, "bitstreamSwitching")) seg->bitstream_switching = gf_mpd_parse_string(att->value);
        }
-       gf_mpd_parse_multiple_segment_base((GF_MPD_MultipleSegmentBase *)seg, root);
+       gf_mpd_parse_multiple_segment_base(mpd, (GF_MPD_MultipleSegmentBase *)seg, root);
        return seg;
 }
 
@@ -403,7 +470,7 @@ static GF_Err gf_mpd_parse_descriptor(GF_List *container, GF_XMLNode *root)
        return GF_OK;
 }
 
-static void gf_mpd_parse_common_representation(GF_MPD_CommonAttributes *com, GF_XMLNode *root)
+static void gf_mpd_parse_common_representation(GF_MPD *mpd, GF_MPD_CommonAttributes *com, GF_XMLNode *root)
 {
        GF_XMLAttribute *att;
        GF_XMLNode *child;
@@ -437,7 +504,7 @@ static void gf_mpd_parse_common_representation(GF_MPD_CommonAttributes *com, GF_
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "FramePacking")) {
                        gf_mpd_parse_content_component(com->frame_packing, child);
                }
@@ -456,7 +523,7 @@ static void gf_mpd_init_common_attributes(GF_MPD_CommonAttributes *com)
        com->content_protection = gf_list_new();
        com->frame_packing = gf_list_new();
 }
-static GF_Err gf_mpd_parse_representation(GF_List *container, GF_XMLNode *root)
+static GF_Err gf_mpd_parse_representation(GF_MPD *mpd, GF_List *container, GF_XMLNode *root)
 {
        u32 i;
        GF_MPD_Representation *rep;
@@ -480,23 +547,23 @@ static GF_Err gf_mpd_parse_representation(GF_List *container, GF_XMLNode *root)
                else if (!strcmp(att->name, "dependencyId")) rep->dependency_id = gf_mpd_parse_string(att->value);
                else if (!strcmp(att->name, "mediaStreamStructureId")) rep->media_stream_structure_id = gf_mpd_parse_string(att->value);
        }
-       gf_mpd_parse_common_representation((GF_MPD_CommonAttributes*)rep, root);
+       gf_mpd_parse_common_representation(mpd, (GF_MPD_CommonAttributes*)rep, root);
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "BaseURL")) {
                        e = gf_mpd_parse_base_url(rep->base_URLs, child);
                        if (e) return e;
                }
                else if (!strcmp(child->name, "SegmentBase")) {
-                       rep->segment_base = gf_mpd_parse_segment_base(child);
+                       rep->segment_base = gf_mpd_parse_segment_base(mpd, child);
                }
                else if (!strcmp(child->name, "SegmentList")) {
-                       rep->segment_list = gf_mpd_parse_segment_list(child);
+                       rep->segment_list = gf_mpd_parse_segment_list(mpd, child);
                }
                else if (!strcmp(child->name, "SegmentTemplate")) {
-                       rep->segment_template = gf_mpd_parse_segment_template(child);
+                       rep->segment_template = gf_mpd_parse_segment_template(mpd, child);
                }
                else if (!strcmp(child->name, "SubRepresentation")) {
 /*TODO
@@ -508,7 +575,7 @@ static GF_Err gf_mpd_parse_representation(GF_List *container, GF_XMLNode *root)
        return GF_OK;
 }
 
-static GF_Err gf_mpd_parse_adaptation_set(GF_List *container, GF_XMLNode *root)
+static GF_Err gf_mpd_parse_adaptation_set(GF_MPD *mpd, GF_List *container, GF_XMLNode *root)
 {
        u32 i;
        GF_MPD_AdaptationSet *set;
@@ -534,8 +601,8 @@ static GF_Err gf_mpd_parse_adaptation_set(GF_List *container, GF_XMLNode *root)
 
        i = 0;
        while ( (att = gf_list_enum(root->attributes, &i)) ) {
-               if (strstr(att->name, "href") || strstr(att->name, "actuate")) {
-               } 
+               if (strstr(att->name, "href")) set->xlink_href = gf_mpd_parse_string(att->value);
+               else if (strstr(att->name, "actuate")) set->xlink_actuate_on_load = !strcmp(att->value, "onLoad") ? 1 : 0;
                else if (!strcmp(att->name, "id")) set->id = gf_mpd_parse_int(att->value);
                else if (!strcmp(att->name, "group")) set->group = gf_mpd_parse_int(att->value);
                else if (!strcmp(att->name, "lang")) set->lang = gf_mpd_parse_string(att->value);
@@ -557,11 +624,11 @@ static GF_Err gf_mpd_parse_adaptation_set(GF_List *container, GF_XMLNode *root)
                        else set->subsegment_starts_with_sap = gf_mpd_parse_int(att->value);
                }
        }
-       gf_mpd_parse_common_representation((GF_MPD_CommonAttributes*)set, root);
+       gf_mpd_parse_common_representation(mpd, (GF_MPD_CommonAttributes*)set, root);
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "Accessibility")) {
                        e = gf_mpd_parse_descriptor(set->accessibility, child);
                        if (e) return e;
@@ -587,16 +654,16 @@ static GF_Err gf_mpd_parse_adaptation_set(GF_List *container, GF_XMLNode *root)
                        if (e) return e;
                }
                else if (!strcmp(child->name, "SegmentBase")) {
-                       set->segment_base = gf_mpd_parse_segment_base(child);
+                       set->segment_base = gf_mpd_parse_segment_base(mpd, child);
                }
                else if (!strcmp(child->name, "SegmentList")) {
-                       set->segment_list = gf_mpd_parse_segment_list(child);
+                       set->segment_list = gf_mpd_parse_segment_list(mpd, child);
                }
                else if (!strcmp(child->name, "SegmentTemplate")) {
-                       set->segment_template = gf_mpd_parse_segment_template(child);
+                       set->segment_template = gf_mpd_parse_segment_template(mpd, child);
                }
                else if (!strcmp(child->name, "Representation")) {
-                       e = gf_mpd_parse_representation(set->representations, child);
+                       e = gf_mpd_parse_representation(mpd, set->representations, child);
                        if (e) return e;
                }
        }
@@ -621,8 +688,8 @@ static GF_Err gf_mpd_parse_period(GF_MPD *mpd, GF_XMLNode *root)
 
        i = 0;
        while ( (att = gf_list_enum(root->attributes, &i)) ) {
-               if (strstr(att->name, "href") || strstr(att->name, "actuate")) {
-               } 
+               if (strstr(att->name, "href")) period->xlink_href = gf_mpd_parse_string(att->value);
+               else if (strstr(att->name, "actuate")) period->xlink_actuate_on_load = !strcmp(att->value, "onLoad") ? 1 : 0;
                else if (!strcmp(att->name, "id")) period->ID = gf_mpd_parse_string(att->value);
                else if (!strcmp(att->name, "start")) period->start = gf_mpd_parse_duration(att->value);
                else if (!strcmp(att->name, "duration")) period->duration = gf_mpd_parse_duration(att->value);
@@ -631,22 +698,22 @@ static GF_Err gf_mpd_parse_period(GF_MPD *mpd, GF_XMLNode *root)
 
        i = 0;
        while ( (child = gf_list_enum(root->content, &i))) {
-               if (child->type != GF_XML_NODE_TYPE) continue;
+               if (!gf_mpd_valid_child(mpd, child)) continue;
                if (!strcmp(child->name, "BaseURL")) {
                        e = gf_mpd_parse_base_url(period->base_URLs, child);
                        if (e) return e;
                }
                else if (!strcmp(child->name, "SegmentBase")) {
-                       period->segment_base = gf_mpd_parse_segment_base(child);
+                       period->segment_base = gf_mpd_parse_segment_base(mpd, child);
                }
                else if (!strcmp(child->name, "SegmentList")) {
-                       period->segment_list = gf_mpd_parse_segment_list(child);
+                       period->segment_list = gf_mpd_parse_segment_list(mpd, child);
                }
                else if (!strcmp(child->name, "SegmentTemplate")) {
-                       period->segment_template = gf_mpd_parse_segment_template(child);
+                       period->segment_template = gf_mpd_parse_segment_template(mpd, child);
                }
                else if (!strcmp(child->name, "AdaptationSet")) {
-                       e = gf_mpd_parse_adaptation_set(period->adaptation_sets, child);
+                       e = gf_mpd_parse_adaptation_set(mpd, period->adaptation_sets, child);
                        if (e) return e;
                }
                else if (!strcmp(child->name, "SubSet")) {
@@ -703,9 +770,9 @@ void gf_mpd_prog_info_free(void *_item)
        if (ptr->more_info_url) gf_free(ptr->more_info_url);
        gf_free(ptr);
 }
-void gf_mpd_segment_url_free(void *_item)
+void gf_mpd_segment_url_free(void *_ptr)
 {
-       GF_MPD_SegmentURL *ptr = (GF_MPD_SegmentURL*)_item;
+       GF_MPD_SegmentURL *ptr = (GF_MPD_SegmentURL *)_ptr;
        if (ptr->index) gf_free(ptr->index);
        if (ptr->index_range) gf_free(ptr->index_range);
        if (ptr->media) gf_free(ptr->media);
@@ -734,6 +801,7 @@ void gf_mpd_segment_timeline_free(void *_item)
 void gf_mpd_segment_list_free(void *_item)
 {
        GF_MPD_SegmentList *ptr = (GF_MPD_SegmentList *)_item;
+       if (ptr->xlink_href) gf_free(ptr->xlink_href);
        if (ptr->initialization_segment) gf_mpd_url_free(ptr->initialization_segment);
        if (ptr->bitstream_switching_url) gf_mpd_url_free(ptr->bitstream_switching_url);
        if (ptr->representation_index) gf_mpd_url_free(ptr->representation_index);
@@ -756,13 +824,13 @@ void gf_mpd_segment_template_free(void *_item)
 }
 void gf_mpd_descriptor_free(void *item)
 {
-       fprintf(stdout, "error: descriptor not implemented\n");
+       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] descriptor not implemented\n"));
        gf_free(item);
 }
 
 void gf_mpd_content_component_free(void *item)
 {
-       fprintf(stdout, "error: content component not implemented\n");
+       GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] content component not implemented\n"));
        gf_free(item);
 }
 
@@ -787,6 +855,8 @@ void gf_mpd_representation_free(void *_item)
        if (ptr->dependency_id) gf_free(ptr->dependency_id);
        if (ptr->media_stream_structure_id) gf_free(ptr->media_stream_structure_id);
 
+       if (ptr->playback.cached_init_segment_url) gf_free(ptr->playback.cached_init_segment_url);
+
        gf_mpd_del_list(ptr->base_URLs, gf_mpd_base_url_free, 0);
        gf_mpd_del_list(ptr->sub_representations, NULL/*TODO*/, 0);
        if (ptr->segment_base) gf_mpd_segment_base_free(ptr->segment_base);
@@ -802,6 +872,7 @@ void gf_mpd_adaptation_set_free(void *_item)
        if (ptr->lang) gf_free(ptr->lang);
        if (ptr->content_type) gf_free(ptr->content_type);
        if (ptr->par) gf_free(ptr->par);
+       if (ptr->xlink_href) gf_free(ptr->xlink_href);
        gf_mpd_del_list(ptr->accessibility, gf_mpd_descriptor_free, 0);
        gf_mpd_del_list(ptr->role, gf_mpd_descriptor_free, 0);
        gf_mpd_del_list(ptr->rating, gf_mpd_descriptor_free, 0);
@@ -818,6 +889,7 @@ void gf_mpd_period_free(void *_item)
 {
        GF_MPD_Period *ptr = (GF_MPD_Period *)_item;
        if (ptr->ID) gf_free(ptr->ID);
+       if (ptr->xlink_href) gf_free(ptr->xlink_href);
        if (ptr->segment_base) gf_mpd_segment_base_free(ptr->segment_base);
        if (ptr->segment_list) gf_mpd_segment_list_free(ptr->segment_list);
        if (ptr->segment_template) gf_mpd_segment_template_free(ptr->segment_template);
@@ -845,6 +917,7 @@ GF_EXPORT
 GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd, const char *default_base_url)
 {
        GF_Err e;
+       Bool ns_ok = 0;
        u32 att_index, child_index;
        GF_XMLAttribute *att;
        GF_XMLNode *child;
@@ -859,9 +932,35 @@ GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd, const char *default_b
        mpd->metrics = gf_list_new();
        /*setup some defaults*/
        mpd->type = GF_MPD_TYPE_STATIC;
+       /*infinite by default*/
+       mpd->time_shift_buffer_depth = (u32) -1;
 
+       mpd->xml_namespace = NULL;
        att_index = 0;
        child_index = gf_list_count(root->attributes);
+       for (att_index = 0 ; att_index < child_index; att_index++) {
+               att = gf_list_get(root->attributes, att_index);
+               if (!att) continue;
+               if (!strcmp(att->name, "xmlns")) {
+                       if (!root->ns && (!strcmp(att->value, "urn:mpeg:dash:schema:mpd:2011") || !strcmp(att->value, "urn:mpeg:DASH:schema:MPD:2011")) ) {
+                               ns_ok = 1;
+                               break;
+                       }
+               }
+               else if (!strncmp(att->name, "xmlns:", 6)) {
+                       if (root->ns && !strcmp(att->name+6, root->ns) && (!strcmp(att->value, "urn:mpeg:dash:schema:mpd:2011") || !strcmp(att->value, "urn:mpeg:DASH:schema:MPD:2011")) ) {
+                               ns_ok = 1;
+                               mpd->xml_namespace = root->ns;
+                               break;
+                       }
+               }
+       }
+
+       if (!ns_ok) {
+               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] Wrong namespace found for DASH MPD - cannot parse\n"));
+       }
+
+       att_index = 0;
        for (att_index = 0 ; att_index < child_index; att_index++) {
                att = gf_list_get(root->attributes, att_index);
                if (!att) {
@@ -895,15 +994,15 @@ GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd, const char *default_b
                        mpd->max_subsegment_duration = gf_mpd_parse_duration(att->value);
                }
        }
-       if (mpd->type == GF_MPD_TYPE_STATIC)
-               mpd->minimum_update_period = 0;
+       if (mpd->type == GF_MPD_TYPE_STATIC) 
+               mpd->minimum_update_period = mpd->time_shift_buffer_depth = 0;
 
        child_index = 0;
        while (1) {
                child = gf_list_get(root->content, child_index);
                if (!child) {
                        break;
-               } else if (child->type == GF_XML_NODE_TYPE) {
+               } else if (gf_mpd_valid_child(mpd, child) ) {
                        if (!strcmp(child->name, "ProgramInformation")) {
                                e = gf_mpd_parse_program_info(mpd, child);
                                if (e) return e;
@@ -945,7 +1044,7 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
 
        e = parse_root_playlist(m3u8_file, &pl, base_url);
        if (e) {
-               GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M3U8] Failed to parse root playlist '%s', error = %s\n", m3u8_file, gf_error_to_string(e)));
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[M3U8] Failed to parse root playlist '%s', error = %s\n", m3u8_file, gf_error_to_string(e)));
                if (pl) variant_playlist_del(pl);
                pl = NULL;
                return e;
@@ -967,7 +1066,7 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                        u32 k;
                        char *suburl;
 
-                       if (!pe->url || !strstr(pe->url, ".m3u8")
+                       if (!pe->url ) 
                                continue;
 
                        /*filter out duplicated entries (seen on M6 m3u8)*/
@@ -982,12 +1081,17 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
 
                        the_pe = pe;
                        suburl = NULL;
+
+                       /*not HLS*/
+                       if ( !strstr(pe->url, ".m3u8")) 
+                               continue;
+
                        if (strcmp(base_url, pe->url))
                                suburl = gf_url_concatenate(base_url, pe->url);
 
                        if (!suburl || !strcmp(base_url, suburl)) {
                                if (suburl) gf_free(suburl);
-                               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] Not downloading, programs are identical for %s...\n", pe->url));
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD Generator] Not downloading, programs are identical for %s...\n", pe->url));
                                continue;
                        }
                        if (getter && getter->new_session && getter->del_session && getter->get_cache_name) {
@@ -1015,8 +1119,8 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
 #endif
                                gf_free(suburl);
                        } else { /* for use in MP4Box */
-                               if (strstr(suburl, "://") && !strstr(suburl, "://") ) {
-                                       e = gf_dm_wget(suburl, "tmp.m3u8");
+                               if (strstr(suburl, "://") ) {
+                                       e = gf_dm_wget(suburl, "tmp.m3u8", 0, 0);
                                        if (e==GF_OK) {
                                                e = parse_sub_playlist("tmp.m3u8", &pl, suburl, prog, pe);
                                        }
@@ -1051,15 +1155,15 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
        }
        if (is_end || ((the_pe->elementType == TYPE_PLAYLIST) && the_pe->element.playlist.is_ended)) {
                update_interval = 0;
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] NO NEED to refresh playlist !\n"));
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD Generator] NO NEED to refresh playlist !\n"));
        } else {
-               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] Playlist will be refreshed every %g seconds, len=%d\n", update_interval, the_pe->durationInfo));
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD Generator] Playlist will be refreshed every %g seconds, len=%d\n", update_interval, the_pe->durationInfo));
        }
 
        assert( mpd_file );
        fmpd = gf_f64_open(mpd_file, "wt");
        if (!fmpd){
-               GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD Generator] Cannot write to temp file %s!\n", mpd_file));
+               GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MPD Generator] Cannot write to temp file %s!\n", mpd_file));
                variant_playlist_del(pl);
                return GF_IO_ERR;
        }
@@ -1166,7 +1270,7 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                }
        }
 
-       fprintf(fmpd, "  <AdaptationSet>\n");
+       fprintf(fmpd, "  <AdaptationSet segmentAlignment=\"true\">\n");
 
        /*if we use templates, put the SegmentTemplate element at the adaptationSet level*/
        if (use_template) {
@@ -1196,7 +1300,7 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                        tmp_file = strrchr(elt->url, '/');
                        if (!tmp_file) tmp_file = strrchr(elt->url, '\\');
                        if (tmp_file) {
-                               e = gf_dm_wget(elt->url, tmp_file);
+                               e = gf_dm_wget(elt->url, tmp_file, 0, 0);
                                if (e==GF_OK) {
                                        import.in_name = tmp_file;
                                        e = gf_media_import(&import);
@@ -1239,13 +1343,15 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                count2 = gf_list_count(prog->bitrates);
                for (j = 0; j<count2; j++) {
                        char *base_url;
+                       Bool import_file = do_import;
+                       Bool is_aac = 0;
                        char *byte_range_media_file = NULL;
                        pe = gf_list_get(prog->bitrates, j);
                        
                        if (pe->elementType == TYPE_STREAM) {
-                               fprintf(stdout, "NOT SUPPORTED: M3U8 Stream\n");
+                               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] NOT SUPPORTED: M3U8 Stream\n"));
                        } else if (pe->elementType != TYPE_PLAYLIST) {
-                               fprintf(stdout, "NOT SUPPORTED: M3U8 unknown type\n");
+                               GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD] NOT SUPPORTED: M3U8 unknown type\n"));
                        }
 
                        count3 = gf_list_count(pe->element.playlist.elements);
@@ -1259,10 +1365,23 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                                strncpy(pe->codecs, pe->codecs+1, len-1);
                                pe->codecs[len-2] = 0;
                        }
+                       if (pe->bandwidth && pe->codecs && pe->width && pe->height) {
+                               import_file = 0;
+                       }
+
+                       /*get rid of level 0 aac*/
+                       elt = gf_list_get(pe->element.playlist.elements, 0);
+                       if (elt && strstr(elt->url, ".aac"))
+                               is_aac = 1;
 
-                       width = height = samplerate = num_channels = 0;
+                       if (is_aac) 
+                               fprintf(fmpd, "<!-- \n");
+
+                       width = pe->width;
+                       height = pe->height;
+                       samplerate = num_channels = 0;
 #ifndef GPAC_DISABLE_MEDIA_IMPORT
-                       if (do_import) {
+                       if (import_file) {
                                GF_Err e;
                                GF_MediaImporter import;
                                char *tmp_file = NULL;
@@ -1275,7 +1394,8 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                                        tmp_file = strrchr(elt->url, '/');
                                        if (!tmp_file) tmp_file = strrchr(elt->url, '\\');
                                        if (tmp_file) {
-                                               e = gf_dm_wget(elt->url, tmp_file);
+                                               tmp_file++;
+                                               e = gf_dm_wget(elt->url, tmp_file, elt->byteRangeStart, elt->byteRangeEnd);
                                                if (e==GF_OK) {
                                                        import.in_name = tmp_file;
                                                }
@@ -1354,6 +1474,8 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                                } else
                                        fprintf(fmpd, "/>\n");
 
+                               if (is_aac) 
+                                       fprintf(fmpd, " -->");
                                continue;
                        }
 
@@ -1398,6 +1520,9 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                        fprintf(fmpd, "    </SegmentList>\n");
                        fprintf(fmpd, "   </Representation>\n");
                        gf_free(base_url);
+
+                       if (is_aac) 
+                               fprintf(fmpd, " -->\n");
                }
        }
 
index 686c74a70d5c57a94d8a26ccfb8cd3697c67b1ab..3d2db207f68b45561dd6bcdb72877071db762490 100644 (file)
@@ -497,7 +497,7 @@ static void copy_bytes_to_pes_buffer (mpeg2ps_stream_t *sptr,
            to_move);
     sptr->pes_buffer_size = to_move;
     sptr->pes_buffer_on = 0;
-    //printf("moving %d bytes\n", to_move);
+    //fprintf(stderr, "moving %d bytes\n", to_move);
     if (to_move + pes_len > sptr->pes_buffer_size_max) {
       sptr->pes_buffer = (u8 *)gf_realloc(sptr->pes_buffer, 
                                            to_move + pes_len + 2048);
@@ -507,7 +507,7 @@ static void copy_bytes_to_pes_buffer (mpeg2ps_stream_t *sptr,
   file_read_bytes(sptr->m_fd, sptr->pes_buffer + sptr->pes_buffer_size, pes_len);
   sptr->pes_buffer_size += pes_len;
 #if 0
-  printf("copying %u bytes - on %u size %u\n",
+  fprintf(stderr, "copying %u bytes - on %u size %u\n",
         pes_len, sptr->pes_buffer_on, sptr->pes_buffer_size);
 #endif
 }
@@ -556,7 +556,7 @@ static Bool read_to_next_pes_header (FILE *fd,
     *stream_id = hdr & 0xff;
     *pes_len = convert16(local + 4);
 #if 0
-    printf("loc: "X64" %x len %u\n", file_location(fd) - 6,
+    fprintf(stderr, "loc: "X64" %x len %u\n", file_location(fd) - 6,
           local[3],
           *pes_len);
 #endif
@@ -613,7 +613,7 @@ static Bool read_pes_header_data (FILE *fd,
     }
     ts->have_pts = 1;
     ts->pts = ts->dts = read_pts(local);
-    //printf("mpeg1 pts "U64"\n", ts->pts);
+    //fprintf(stderr, "mpeg1 pts "U64"\n", ts->pts);
     *have_ts = 1;
     pes_len -= 4;
   } else if ((*local & 0xf0) == 0x30) {
@@ -798,7 +798,7 @@ mpeg2ps_stream_find_mpeg_video_frame (mpeg2ps_stream_t *sptr)
     sptr->next_pes_ts.have_pts = sptr->next_pes_ts.have_dts = 0;
   }
 #if 0
-  printf("header %x at %d\n", scode, sptr->pes_buffer_on);
+  fprintf(stderr, "header %x at %d\n", scode, sptr->pes_buffer_on);
 #endif
 
   if (scode == MPEG12_PICTURE_START_CODE) {
@@ -823,7 +823,7 @@ mpeg2ps_stream_find_mpeg_video_frame (mpeg2ps_stream_t *sptr)
       sptr->pict_header_offset += sptr->pes_buffer_on;
     } else {
 #if 0
-      printf("2header %x at %d\n", scode, start);
+      fprintf(stderr, "2header %x at %d\n", scode, start);
 #endif
 
       start += offset;
@@ -884,7 +884,7 @@ static Bool mpeg2ps_stream_find_ac3_frame (mpeg2ps_stream_t *sptr)
   }
   while (sptr->pes_buffer_size - sptr->pes_buffer_on < sptr->frame_len) {
 #if 0
-    printf("don't have enough - on %u size %u %u %u\n", sptr->pes_buffer_on, 
+    fprintf(stderr, "don't have enough - on %u size %u %u %u\n", sptr->pes_buffer_on, 
           sptr->pes_buffer_size,
           sptr->pes_buffer_size - sptr->pes_buffer_on, 
           sptr->frame_len);
@@ -937,7 +937,7 @@ static Bool mpeg2ps_stream_find_mp3_frame (mpeg2ps_stream_t *sptr)
   }
   while (sptr->pes_buffer_size - sptr->pes_buffer_on < sptr->frame_len) {
 #if 0
-    printf("don't have enough - on %u size %u %u %u\n", sptr->pes_buffer_on, 
+    fprintf(stderr, "don't have enough - on %u size %u %u %u\n", sptr->pes_buffer_on, 
           sptr->pes_buffer_size,
           sptr->pes_buffer_size - sptr->pes_buffer_on, 
           sptr->frame_len);
@@ -1334,7 +1334,7 @@ static void mpeg2ps_scan_file (mpeg2ps_t *ps)
    * Now, we go to close to the end, and try to find the last 
    * dts that we can
    */
-  //  printf("to end "X64"\n", end - orig_check);
+  //  fprintf(stderr, "to end "X64"\n", end - orig_check);
   file_seek_to(ps->fd, ps->end_loc - orig_check);
 
   while (read_to_next_pes_header(ps->fd, &stream_id, &pes_len)) {
@@ -1370,10 +1370,10 @@ static void mpeg2ps_scan_file (mpeg2ps_t *ps)
        sptr->end_dts_loc = loc;
       }
 #if 0
-      printf("loc "X64" stream %x %x", loc, stream_id, substream);
-      if (ts.have_pts) printf(" pts "U64, ts.pts);
-      if (ts.have_dts) printf(" dts "U64, ts.dts);
-      printf("\n");
+      fprintf(stderr, "loc "X64" stream %x %x", loc, stream_id, substream);
+      if (ts.have_pts) fprintf(stderr, " pts "U64, ts.pts);
+      if (ts.have_dts) fprintf(stderr, " dts "U64, ts.dts);
+      fprintf(stderr, "\n");
 #endif
       file_skip_bytes(ps->fd, pes_left);
     }
index 9cc877b2438f0739cfafe30ff5e62a332327e4fa..2a7b2c27b4193bdeef159041b578988bd34034d9 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Walid B.H - Jean Le Feuvre
- *    Copyright (c)2006-200X ENST - All rights reserved
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *
  *  This file is part of GPAC / MPEG2-TS sub-project
  *
 
 #ifndef GPAC_DISABLE_MPEG2TS
 
+#include <string.h>
 #include <gpac/constants.h>
 #include <gpac/internal/media_dev.h>
-#include <gpac/math.h>
-#include <string.h>
 #include <gpac/download.h>
 
 #ifdef GPAC_CONFIG_LINUX
 
 //#define FORCE_DISABLE_MPEG4SL_OVER_MPEG2TS
 
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
 #include <gpac/dvb_mpe.h>
 #endif
 
-#ifndef GPAC_DISABLE_DSMCC
+#ifdef GPAC_ENABLE_DSMCC
 #include <gpac/ait.h>
 #endif
 
@@ -113,6 +112,7 @@ static u32 gf_m2ts_reframe_reset(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, Bool sam
 static u32 gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, Bool same_pts, unsigned char *data, u32 data_len)
 {
        Bool au_start_in_pes=0;
+       Bool prev_is_au_delim=0;
        Bool force_new_au=0;
        Bool start_code_found = 0;
        Bool short_start_code = 0;
@@ -205,20 +205,29 @@ static u32 gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, Bool
 #endif
                        /*check AU start type*/
                        if (nal_type==GF_AVC_NALU_ACCESS_UNIT) {
-                               if (au_start_in_pes) {
-                                       /*FIXME - we should check the AVC framerate to update the timing ...*/
-                                       pck.DTS += 3000;
-                                       pck.PTS += 3000;
-//                                     GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID%d: Two AVC AUs start in this PES packet - cannot recompute non-first AU timing\n", pes->pid));
+                               if (!prev_is_au_delim) {
+                                       if (au_start_in_pes) {
+                                               /*FIXME - we should check the AVC framerate to update the timing ...*/
+                                               pck.DTS += 3000;
+                                               pck.PTS += 3000;
+//                                             GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID%d: Two AVC AUs start in this PES packet - cannot recompute non-first AU timing\n", pes->pid));
+                                       }
+                                       pck.flags = GF_M2TS_PES_PCK_AU_START;
+                                       force_new_au = 0;
+                                       au_start_in_pes = 1;
+                                       ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck);
+                                       prev_is_au_delim=1;
                                }
-                               pck.flags = GF_M2TS_PES_PCK_AU_START;
-                               force_new_au = 0;
-                               au_start_in_pes = 1;
                        } else if (nal_type==GF_AVC_NALU_IDR_SLICE) {
                                pck.flags = GF_M2TS_PES_PCK_RAP;
+                               ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck);
+                               prev_is_au_delim=0;
                        } 
-                       else pck.flags = 0;
-                       ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck);
+                       else {
+                               pck.flags = 0;
+                               ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck);
+                               prev_is_au_delim=0;
+                       }
 
                        data += sc_pos;
                        data_len -= sc_pos;
@@ -793,9 +802,12 @@ static void gf_m2ts_reset_sections(GF_List *sections)
        }
 }
 
-static void gf_m2ts_section_filter_del(GF_M2TS_SectionFilter *sf)
+static void gf_m2ts_section_filter_reset(GF_M2TS_SectionFilter *sf)
 {
-       if (sf->section) gf_free(sf->section);
+       if (sf->section) {
+               gf_free(sf->section);
+               sf->section = NULL;
+       }
        while (sf->table) {
                GF_M2TS_Table *t = sf->table;
                sf->table = t->next;
@@ -803,6 +815,12 @@ static void gf_m2ts_section_filter_del(GF_M2TS_SectionFilter *sf)
                gf_list_del(t->sections);
                gf_free(t);
        }
+       sf->cc = -1;
+       sf->length = sf->received = 0;
+}
+static void gf_m2ts_section_filter_del(GF_M2TS_SectionFilter *sf)
+{
+       gf_m2ts_section_filter_reset(sf);
        gf_free(sf);
 }
 
@@ -814,7 +832,7 @@ void gf_m2ts_es_del(GF_M2TS_ES *es)
                GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
                if (ses->sec) gf_m2ts_section_filter_del(ses->sec);
 
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
                if (es->flags & GF_M2TS_ES_IS_MPE)
                        gf_dvb_mpe_section_del(es);
 #endif
@@ -844,7 +862,7 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter
 {
        if (!sec->process_section) {
                if ((ts->on_event && (sec->section[0]==GF_M2TS_TABLE_ID_AIT)) ) {                               
-#ifndef GPAC_DISABLE_DSMCC
+#ifdef GPAC_ENABLE_DSMCC
                        GF_M2TS_SL_PCK pck;
                        pck.data_len = sec->length;
                        pck.data = sec->section;
@@ -855,7 +873,7 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter
                } else if ((ts->on_event && (sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA || sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE ||
                        sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_DOWNLOAD_DATA_MESSAGE || sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_STREAM_DESCRIPTION || sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_PRIVATE)) ) {                         
 
-#ifndef GPAC_DISABLE_DSMCC
+#ifdef GPAC_ENABLE_DSMCC
                        GF_M2TS_SL_PCK pck;
                        pck.data_len = sec->length;
                        pck.data = sec->section;
@@ -864,7 +882,7 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter
                        //ts->on_event(ts, GF_M2TS_EVT_DSMCC_FOUND, &pck);
 #endif
                }
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
                else if (ts->on_mpe_event && ((ses && (ses->flags & GF_M2TS_EVT_DVB_MPE)) || (sec->section[0]==GF_M2TS_TABLE_ID_INT)) ) {
                        GF_M2TS_SL_PCK pck;
                        pck.data_len = sec->length;
@@ -1520,11 +1538,13 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF
                case GF_M2TS_SUBTITLE_DVB:
                        GF_SAFEALLOC(pes, GF_M2TS_PES);
                        pes->cc = -1;
+                       pes->flags = GF_M2TS_ES_IS_PES;
                        es = (GF_M2TS_ES *)pes;
                        break;
                case GF_M2TS_PRIVATE_DATA:
                        GF_SAFEALLOC(pes, GF_M2TS_PES);
                        pes->cc = -1;
+                       pes->flags = GF_M2TS_ES_IS_PES;
                        es = (GF_M2TS_ES *)pes;
                        break;
                /* Sections */
@@ -1567,7 +1587,7 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF
 
                case GF_M2TS_MPE_SECTIONS:
                        GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("stream type MPE found : pid = %d \n", pid));
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
                        es = gf_dvb_mpe_section_new();
                        if (es->flags & GF_M2TS_ES_IS_SECTION) {
                                /* NULL means: trigger the call to on_event with DVB_GENERAL type and the raw section as payload */
@@ -1837,7 +1857,7 @@ static void gf_m2ts_process_cat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF
        if (ts->on_event) ts->on_event(ts, evt_type, NULL);
 }
 
-static GFINLINE u64 gf_m2ts_get_pts(unsigned char *data)
+u64 gf_m2ts_get_pts(unsigned char *data)
 {
     u64 pts;
     u32 val;
@@ -1849,7 +1869,7 @@ static GFINLINE u64 gf_m2ts_get_pts(unsigned char *data)
     return pts;
 }
 
-static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_size, GF_M2TS_PESHeader *pesh)
+void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_size, GF_M2TS_PESHeader *pesh)
 {
        u32 has_pts, has_dts;
        u32 len_check;
@@ -1892,6 +1912,8 @@ static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_s
                pesh->DTS = gf_m2ts_get_pts(data);
                data+=5;
                len_check += 5;
+       } else {
+               pesh->DTS = pesh->PTS;
        }
        if (len_check < pesh->hdr_data_len) {
                GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Skipping %d bytes in pes header\n", pes->pid, pesh->hdr_data_len - len_check));
@@ -1900,7 +1922,7 @@ static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_s
        }
 }
 
-static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Header *hdr)
+static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes)
 {
        GF_M2TS_PESHeader pesh;
 
@@ -1920,7 +1942,7 @@ static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Hea
                        gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh);
                        
                        /*send PES timing*/
-                       {
+                       if (ts->notify_pes_timing) {
                                GF_M2TS_PES_PCK pck;
                                memset(&pck, 0, sizeof(GF_M2TS_PES_PCK));
                                pck.PTS = pesh.PTS;
@@ -1947,13 +1969,13 @@ static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Hea
 #endif
 
                                pes->PTS = pesh.PTS;
-                               if (!pesh.DTS) pesh.DTS = pesh.PTS;
-
 #ifndef GPAC_DISABLE_LOG
-                               if (pesh.DTS==pes->DTS) {
-                                       GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - same DTS "LLU" for two consecutive PES packets \n", pes->pid, pes->DTS) );
-                               } if (pesh.DTS<pes->DTS) {
-                                       GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - DTS "LLU" less than previous DTS "LLU"\n", pes->pid, pesh.DTS, pes->DTS) );
+                               {
+                                       if (pes->DTS && (pesh.DTS==pes->DTS)) {
+                                               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - same DTS "LLU" for two consecutive PES packets \n", pes->pid, pes->DTS) );
+                                       } if (pesh.DTS<pes->DTS) {
+                                               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - DTS "LLU" less than previous DTS "LLU"\n", pes->pid, pesh.DTS, pes->DTS) );
+                                       }
                                }
 #endif
                                pes->DTS = pesh.DTS;
@@ -2004,10 +2026,10 @@ static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Hea
                                }
                        }
                } else {
-                       GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: unknown stream ID %08X\n", pes->pid, stream_id));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: unknown stream ID %08X\n", pes->pid, stream_id));
                }
-       } else {
-               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Bad PES Header, discarding packet (maybe stream is encrypted ?)\n", hdr->pid));
+       } else if (pes->data) {
+               GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Bad PES Header, discarding packet (maybe stream is encrypted ?)\n", pes->pid));
        }
        if (pes->data) gf_free(pes->data);
        pes->data = NULL;
@@ -2019,14 +2041,17 @@ static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Hea
 static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Header *hdr, unsigned char *data, u32 data_size, GF_M2TS_AdaptationField *paf)
 {
        u8 expect_cc;
-       Bool disc;
+       Bool disc=0;
        Bool flush_pes = 0;
 
-       /*duplicated packet, NOT A DISCONTINUITY, discard the packet*/
-       if (hdr->continuity_counter==pes->cc) return;
-
-       expect_cc = (pes->cc<0) ? hdr->continuity_counter : (pes->cc + 1) & 0xf;
-       disc = (expect_cc == hdr->continuity_counter) ? 0 : 1;
+       /*duplicated packet, NOT A DISCONTINUITY, we should discard the packet - however we may encounter this configuration in DASH at segment boundaries. 
+       If payload start is set, ignore duplication*/
+       if (hdr->continuity_counter==pes->cc) {
+               if (!hdr->payload_start || (hdr->adaptation_field!=3) ) return;
+       } else {
+               expect_cc = (pes->cc<0) ? hdr->continuity_counter : (pes->cc + 1) & 0xf;
+               if (expect_cc != hdr->continuity_counter) disc = 1;
+       }
        pes->cc = hdr->continuity_counter;
 
        if (disc) {
@@ -2035,15 +2060,21 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H
                        disc = 0;
                }
                if (disc) {
-                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Packet discontinuity (%d expected - got %d- - trashing PES packet\n", pes->pid, expect_cc, hdr->continuity_counter));
-                       if (pes->data) {
-                               gf_free(pes->data);
-                               pes->data = NULL;
+                       if (hdr->payload_start) {
+                               if (pes->data) {
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Packet discontinuity (%d expected - got %d) - may have lost end of previous PES\n", pes->pid, expect_cc, hdr->continuity_counter));
+                               }
+                       } else {
+                               if (pes->data) {
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Packet discontinuity (%d expected - got %d) - trashing PES packet\n", pes->pid, expect_cc, hdr->continuity_counter));
+                                       gf_free(pes->data);
+                                       pes->data = NULL;
+                               }
+                               pes->data_len = 0;
+                               pes->pes_len = 0;
+                               pes->cc = -1;
+                               return;
                        }
-                       pes->data_len = 0;
-                       pes->pes_len = 0;
-                       pes->cc = -1;
-                       return;
                }
        }
 
@@ -2056,7 +2087,7 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H
                pes->before_last_pcr_value_pck_number = pes->program->before_last_pcr_value_pck_number;
                pes->last_pcr_value = pes->program->last_pcr_value;
                pes->last_pcr_value_pck_number = pes->program->last_pcr_value_pck_number;
-       } else if (pes->pes_len && (pes->data_len + data_size  == pes->pes_len + 6)) {
+       } else if (pes->pes_len && (pes->data_len + data_size == pes->pes_len + 6)) {
                /* 6 = startcode+stream_id+length*/
                /*reassemble pes*/
                if (pes->data) pes->data = (char*)gf_realloc(pes->data, pes->data_len+data_size);
@@ -2070,7 +2101,7 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H
 
        /*PES first fragment: flush previous packet*/
        if (flush_pes && pes->data) {
-               gf_m2ts_flush_pes(ts, pes, hdr);
+               gf_m2ts_flush_pes(ts, pes);
                if (!data_size) return;
        }
        /*we need to wait for first packet of PES*/
@@ -2081,7 +2112,7 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H
        /*reassemble*/
        if (pes->data){
                pes->data = (char*)gf_realloc(pes->data, pes->data_len+data_size);
-               //printf("[MPEG-2 TS] REALLOC \n");
+               //fprintf(stderr, "[MPEG-2 TS] REALLOC \n");
        }else{
                pes->data = (char*)gf_malloc(data_size);
        }
@@ -2094,7 +2125,7 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H
                GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Got PES packet len %d\n", pes->pid, pes->pes_len));
 
                if (pes->pes_len + 6 == pes->data_len) {
-                       gf_m2ts_flush_pes(ts, pes, hdr);
+                       gf_m2ts_flush_pes(ts, pes);
                }
        }
 }
@@ -2157,7 +2188,7 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data)
 //#if DEBUG_TS_PACKET
        GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Packet PID %d\n", hdr.pid));
 //#endif
-       //printf("[MPEG-2 TS] Packet PID %d\n", hdr.pid);
+
        paf = NULL;
        payload_size = 184;
        pos = 4;
@@ -2245,6 +2276,7 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data)
                es->program->before_last_pcr_value_pck_number = es->program->last_pcr_value_pck_number;
                es->program->last_pcr_value_pck_number = ts->pck_number;
                es->program->last_pcr_value = paf->PCR_base * 300 + paf->PCR_ext;
+               if (!es->program->last_pcr_value) es->program->last_pcr_value =  1;
                pck.PTS = es->program->last_pcr_value;
                pck.stream = (GF_M2TS_PES *)es;
                if (paf->discontinuity_indicator) pck.flags = GF_M2TS_PES_PCK_DISCONTINUITY;
@@ -2362,18 +2394,7 @@ void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts)
 
                if (es->flags & GF_M2TS_ES_IS_SECTION) {
                        GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
-                       ses->sec->cc = -1;
-                       ses->sec->length = 0;
-                       ses->sec->received = 0;
-                       gf_free(ses->sec->section);
-                       ses->sec->section = NULL;
-                       while (ses->sec->table) {
-                               GF_M2TS_Table *t = ses->sec->table;
-                               ses->sec->table = t->next;
-                               gf_m2ts_reset_sections(t->sections);
-                               gf_list_del(t->sections);
-                               gf_free(t);
-                       }
+                       gf_m2ts_section_filter_reset(ses->sec);
                } else {
                        GF_M2TS_PES *pes = (GF_M2TS_PES *)es;
                        if (!pes || (pes->pid==pes->program->pmt_pid)) continue;
@@ -2390,24 +2411,24 @@ void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts)
                        if (pes->buf) gf_free(pes->buf);
                        pes->buf = NULL;
                        pes->buf_len = 0;
+                       pes->before_last_pcr_value = pes->before_last_pcr_value_pck_number = 0;
+                       pes->last_pcr_value = pes->last_pcr_value_pck_number = 0;
+                       if (pes->program->pcr_pid==pes->pid) {
+                               pes->program->last_pcr_value = pes->program->last_pcr_value_pck_number = 0;
+                               pes->program->before_last_pcr_value = pes->program->before_last_pcr_value_pck_number = 0;
+                       }
                }
 //             gf_free(es);
 //             ts->ess[i] = NULL;
        }
-/*
-       if (ts->pat) {
-               ts->pat->cc = -1;
-               ts->pat->length = 0;
-               ts->pat->received = 0;
-               gf_free(ts->pat->section);
-               while (ts->pat->table) {
-                       GF_M2TS_Table *t = ts->pat->table;
-                       ts->pat->table = t->next;
-                       if (t->data) gf_free(t->data);
-                       gf_free(t);
-               }
-       }
-*/
+
+       gf_m2ts_section_filter_reset(ts->cat);
+       gf_m2ts_section_filter_reset(ts->pat);
+       gf_m2ts_section_filter_reset(ts->sdt);
+       gf_m2ts_section_filter_reset(ts->nit);
+       gf_m2ts_section_filter_reset(ts->eit);
+       gf_m2ts_section_filter_reset(ts->tdt_tot);
+
 }
 
 static void gf_m2ts_process_section_discard(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
@@ -2492,7 +2513,7 @@ GF_M2TS_Demuxer *gf_m2ts_demux_new()
        ts->eit = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_eit*/, 1);
        ts->tdt_tot = gf_m2ts_section_filter_new(gf_m2ts_process_tdt_tot, 1);
 
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
        gf_dvb_mpe_init(ts);
 #endif
 
@@ -2564,12 +2585,12 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts)
        if (ts->tdt_tot)
        gf_list_del(ts->SDTs);
 
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
        gf_dvb_mpe_shutdown(ts);
 #endif
 
        if(gf_list_count(ts->dsmcc_controler)){
-#ifndef GPAC_DISABLE_DSMCC
+#ifdef GPAC_ENABLE_DSMCC
                GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord = (GF_M2TS_DSMCC_OVERLORD*)gf_list_get(ts->dsmcc_controler,0);   
                gf_cleanup_dir(dsmcc_overlord->root_dir);
                gf_rmdir(dsmcc_overlord->root_dir);     
@@ -2581,7 +2602,7 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts)
        }
 
        while(gf_list_count(ts->ChannelAppList)){
-#ifndef GPAC_DISABLE_DSMCC
+#ifdef GPAC_ENABLE_DSMCC
                GF_M2TS_CHANNEL_APPLICATION_INFO* ChanAppInfo = (GF_M2TS_CHANNEL_APPLICATION_INFO*)gf_list_get(ts->ChannelAppList,0);
                gf_m2ts_delete_channel_application_info(ChanAppInfo);
                gf_list_rem(ts->ChannelAppList,0);
@@ -2589,12 +2610,22 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts)
        }
        gf_list_del(ts->ChannelAppList);
 
+       if (ts->requested_progs) {
+               assert(!gf_list_count(ts->requested_progs));
+               gf_list_del(ts->requested_progs);
+       }
+
+       if (ts->requested_pids) {
+               assert(!gf_list_count(ts->requested_pids));
+               gf_list_del(ts->requested_pids);
+       }
+
        gf_free(ts);
 }
 
 void gf_m2ts_print_info(GF_M2TS_Demuxer *ts)
 {
-#ifndef GPAC_DISABLE_MPE
+#ifdef GPAC_ENABLE_MPE
        gf_m2ts_print_mpe_info(ts);
 #endif
 }
@@ -2712,7 +2743,18 @@ restart_file:
                                gf_sleep(3000);
             }
                }
-               if (feof(ts->file)) GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TSDemux] EOS reached\n"));
+               if (feof(ts->file)) {
+                       u32 i;
+                       for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {
+                               if (ts->ess[i]) {
+                                       if (ts->ess[i]->flags & GF_M2TS_ES_IS_PES) {
+                                               gf_m2ts_flush_pes(ts, (GF_M2TS_PES *) ts->ess[i]);
+                                               ts->on_event(ts, GF_M2TS_EVT_EOS, (GF_M2TS_PES *) ts->ess[i]);
+                                       } 
+                               }
+                       }
+                       GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TSDemux] EOS reached\n"));
+               }
 
 next_segment_setup:
                if (ts->run_state && ts->query_next) {
@@ -3109,6 +3151,134 @@ GF_Err TSDemux_DemuxPlay(GF_M2TS_Demuxer *ts){
 }
 
 
+Bool gf_m2ts_probe_file(const char *fileName)
+{
+       char buf[188];
+       u32 count = 10;
+       FILE *t = gf_f64_open(fileName, "rb");
+       while (t && count) {
+               u32 read = fread(buf, 1, 188, t);
+               if (!read) {
+                       count = 0;
+                       break;
+               }
+               if (buf[0] != 0x47)
+                       break;
+               if (read<188) 
+                       count = 0;
+               else count--;
+       }
+       if (t) fclose(t);
+       return count ? 0 : 1;
+}
+
+static void rewrite_pts_dts(unsigned char *ptr, u64 TS)
+{
+       ptr[0] &= 0xf1;
+       ptr[0] |= (unsigned char)((TS&0x1c0000000)>>29);
+       ptr[1]  = (unsigned char)((TS&0x03fc00000)>>22);
+       ptr[2] &= 0x1;
+       ptr[2] |= (unsigned char)((TS&0x0003f8000)>>14);
+       ptr[3]  = (unsigned char)((TS&0x000007f80)>>7);
+       ptr[4] &= 0x1;
+       ptr[4] |= (unsigned char)((TS&0x00000007f)<<1);
+
+       assert(((u64)(ptr[0]&0xe)<<29) + ((u64)ptr[1]<<22) + ((u64)(ptr[2]&0xfe)<<14) + ((u64)ptr[3]<<7) + ((ptr[4]&0xfe)>>1) == TS);
+}
+
+#define ADJUST_TIMESTAMP(_TS) \
+       if (_TS < (u64) -ts_shift) _TS = pcr_mod + _TS + ts_shift; \
+       else _TS = _TS + ts_shift; \
+       while (_TS > pcr_mod) _TS -= pcr_mod; \
+
+
+GF_Err gf_m2ts_restamp(char *buffer, u32 size, s64 ts_shift, u8 *is_pes)
+{
+       u32 done = 0;
+       u64 pcr_mod;
+//     if (!ts_shift) return GF_OK;
+
+       pcr_mod = 0x80000000;
+       pcr_mod*=4;
+       while (done + 188 <= size) {
+               char *pesh;
+               u8 *pck;
+               u64 pcr_base=0, pcr_ext=0;
+               u16 pid;
+               u8 adaptation_field, adaptation_field_length;
+
+               pck = buffer+done;
+               if (pck[0]!=0x47) {
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS Restamp] Invalid sync byte %X\n", pck[0]));
+                       return GF_NON_COMPLIANT_BITSTREAM;
+               }
+               pid = ((pck[1] & 0x1f) <<8 ) + pck[2];
+
+               adaptation_field_length = 0;
+               adaptation_field = (pck[3] >> 4) & 0x3;
+               if ((adaptation_field==2) || (adaptation_field==3)) {
+                       adaptation_field_length = pck[4];
+                       if ( pck[5]&0x10 /*PCR_flag*/) {
+                               pcr_base = (((u64)pck[6])<<25) + (pck[7]<<17) + (pck[8]<<9) + (pck[9]<<1) + (pck[10]>>7);
+                               pcr_ext  = ((pck[10]&1)<<8) + pck[11];
+
+                               ADJUST_TIMESTAMP(pcr_base);
+
+                               pck[6]  = (unsigned char)(0xff&(pcr_base>>25));
+                               pck[7]  = (unsigned char)(0xff&(pcr_base>>17));
+                               pck[8]  = (unsigned char)(0xff&(pcr_base>>9));
+                               pck[9]  = (unsigned char)(0xff&(pcr_base>>1));
+                               pck[10] = (unsigned char)(((0x1&pcr_base)<<7) | 0x7e | ((0x100&pcr_ext)>>8));
+                               if (pcr_ext != ((pck[10]&1)<<8) + pck[11]) {
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS Restamp] Sanity check failed for PCR restamping\n"));
+                                       return GF_IO_ERR;
+                               }
+                               pck[11] = (unsigned char)(0xff&pcr_ext);
+                       }
+               }
+               if (!is_pes[pid] || !(pck[1]&0x40)) {
+                       done+=188;
+                       continue;
+               }
+               if (adaptation_field_length)
+                       adaptation_field_length++; /*add adaptation_field_length field*/
+
+               pesh = &pck[4+adaptation_field_length];
+
+               if ((pesh[0]==0x00) && (pesh[1]==0x00) && (pesh[2]==0x01)) {
+                       Bool has_pts, has_dts;
+                       if ((pesh[6]&0xc0)!=0x80) {
+                               done+=188;
+                               continue;
+                       }
+                       has_pts = (pesh[7]&0x80);
+                       has_dts = has_pts ? (pesh[7]&0x40) : 0;
+
+                       if (has_pts) {
+                               u64 PTS;
+                               if (((pesh[9]&0xe0)>>4)!=0x2) {
+                                       GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS Restamp] PID %4d: Wrong PES header, PTS decoding: '0010' expected\n", pid));
+                                       done+=188;
+                                       continue;
+                               }
+
+                               PTS = gf_m2ts_get_pts(pesh + 9);
+                               ADJUST_TIMESTAMP(PTS);
+                               rewrite_pts_dts(pesh+9, PTS);
+                       }
+
+                       if (has_dts) {
+                               u64 DTS = gf_m2ts_get_pts(pesh + 14);
+                               ADJUST_TIMESTAMP(DTS);
+                               rewrite_pts_dts(pesh+14, DTS);
+                       }
+               } else {
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS Restamp] PID %4d: Wrong PES not beginning with start code\n", pid));
+               }
+               done+=188;      
+       }
+       return GF_OK;
+}
 
 #endif /*GPAC_DISABLE_MPEG2TS*/
 
index c0b9c6be88777a7355e301dcad79b3de4c80ea0b..d6f3f5f25f6a8b276b51f1334e1ad52aa1944e5d 100644 (file)
@@ -16,6 +16,9 @@
 #include <gpac/tools.h>
 #include <gpac/internal/reedsolomon.h>
 
+#ifdef GPAC_ENABLE_MPE
+
+
 /* This is one of 14 irreducible polynomials
  * of degree 8 and cycle length 255. (Ch 5, pp. 275, Magnetic Recording)
  * The high order 1 bit is implicit */
@@ -438,10 +441,10 @@ correct_errors_erasures (unsigned char codeword[],
  print_parity (void)  
  {   
    int i;  
-   printf("Parity Bytes: ");  
+   fprintf(stderr, "Parity Bytes: ");  
    for (i = 0; i < NPAR; i++)   
-     printf("[%d]:%x, ",i,pBytes[i]);  
-   printf("\n");  
+     fprintf(stderr, "[%d]:%x, ",i,pBytes[i]);  
+   fprintf(stderr, "\n");  
  }  
    
    
@@ -449,10 +452,10 @@ correct_errors_erasures (unsigned char codeword[],
  print_syndrome (void)  
  {   
    int i;  
-   printf("Syndrome Bytes: ");  
+   fprintf(stderr, "Syndrome Bytes: ");  
    for (i = 0; i < NPAR; i++)   
-     printf("[%d]:%x, ",i,synBytes[i]);  
-   printf("\n");  
+     fprintf(stderr, "[%d]:%x, ",i,synBytes[i]);  
+   fprintf(stderr, "\n");  
  }  
    
  /* Append the parity bytes onto the end of the message */  
@@ -507,7 +510,7 @@ correct_errors_erasures (unsigned char codeword[],
    int i;  
        
    for (i = 0; i < 3; i++) {  
-     printf(" inv log S[%d]/S[%d] = %d\n", i, i+1,   
+     fprintf(stderr, " inv log S[%d]/S[%d] = %d\n", i, i+1,   
         glog[gmult(synBytes[i], ginv(synBytes[i+1]))]);  
    }  
  }  
@@ -567,3 +570,5 @@ correct_errors_erasures (unsigned char codeword[],
        
    build_codeword(msg, nbytes, dst);  
  }
+
+ #endif //GPAC_ENABLE_MPE
index 79e777aba9376e47bcbfa97b89be03cdcb742bf1..2f7024c5a7067a9d407e5f6915cb6285c8a9144b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / LASeR codec sub-project
index 4abc7e80e19118c6c52408c68889e2a2d2300030..8b4e181f44343a177678d890da00914948d0238b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media Tools sub-project
@@ -40,6 +41,7 @@ enum
        GF_TEXT_IMPORT_SUB,
        GF_TEXT_IMPORT_TTXT,
        GF_TEXT_IMPORT_TEXML,
+    GF_TEXT_IMPORT_WEBVTT,
 };
 
 #define REM_TRAIL_MARKS(__str, __sep) while (1) {      \
@@ -117,8 +119,10 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt)
                if (strstr(szLine, "x-quicktime-tx3g") || strstr(szLine, "text3GTrack")) *fmt = GF_TEXT_IMPORT_TEXML;
                else if (strstr(szLine, "TextStream")) *fmt = GF_TEXT_IMPORT_TTXT;
        }
+       else if (strstr(szLine, "WEBVTT") )
+        *fmt = GF_TEXT_IMPORT_WEBVTT;
        else if (strstr(szLine, " --> ") ) 
-               *fmt = GF_TEXT_IMPORT_SRT;
+               *fmt = GF_TEXT_IMPORT_SRT; /* might want to change the default to WebVTT */
 
        fclose(test);
        return GF_OK;
@@ -129,9 +133,16 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt)
 #define TTXT_DEFAULT_HEIGHT    60
 #define TTXT_DEFAULT_FONT_SIZE 18
 
-static void gf_text_get_video_size(GF_ISOFile *dest, u32 *width, u32 *height)
+static void gf_text_get_video_size(GF_MediaImporter *import, u32 *width, u32 *height)
 {
        u32 w, h, f_w, f_h, i;
+       GF_ISOFile *dest = import->dest;
+
+       if (import->text_track_width && import->text_track_height) {
+               (*width) = import->text_track_width;
+               (*height) = import->text_track_height;
+               return;
+       }
 
        f_w = f_h = 0;
        for (i=0; i<gf_isom_get_track_count(dest); i++) {
@@ -333,7 +344,7 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
        } else {
                u32 w, h;
                GF_TextSampleDescriptor *sd;
-               gf_text_get_video_size(import->dest, &w, &h);
+               gf_text_get_video_size(import, &w, &h);
 
                /*have to work with default - use max size (if only one video, this means the text region is the
                entire display, and with bottom alignment things should be fine...*/
@@ -355,9 +366,10 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
                        sd->default_pos.top = sd->default_pos.left = sd->default_pos.right = sd->default_pos.bottom = 0;
                } else {
                        if ((sd->default_pos.bottom==sd->default_pos.top) || (sd->default_pos.right==sd->default_pos.left)) {
-                               sd->default_pos.top = sd->default_pos.left = 0;
-                               sd->default_pos.right = import->twidth ? import->twidth : w;
-                               sd->default_pos.bottom = import->theight ? import->theight : h;
+                               sd->default_pos.left = import->text_x;
+                               sd->default_pos.top = import->text_y;
+                               sd->default_pos.right = (import->text_width ? import->text_width : w) + sd->default_pos.left;
+                               sd->default_pos.bottom = (import->text_height ? import->text_height : h) + sd->default_pos.top;
                        }
                }
 
@@ -388,7 +400,6 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
 
                if (sOK) REM_TRAIL_MARKS(szLine, "\r\n\t ")
                if (!sOK || !strlen(szLine)) {
-                       state = 0;
                        rec.style_flags = 0;
                        rec.startCharOffset = rec.endCharOffset = 0;
                        if (txt_line) {
@@ -396,20 +407,24 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
                                        GF_TextSample * empty_samp = gf_isom_new_text_sample();
                                        s = gf_isom_text_to_sample(empty_samp);
                                        gf_isom_delete_text_sample(empty_samp);
-                                       s->DTS = (u64) ((timescale*prev_end)/1000);
+                                       if (state<=2) {
+                                               s->DTS = (u64) ((timescale*prev_end)/1000);
+                                               s->IsRAP = 1;
+                                               gf_isom_add_sample(import->dest, track, 1, s);
+                                               nb_samp++;
+                                       }
+                                       gf_isom_sample_del(&s);
+                               }
+
+                               s = gf_isom_text_to_sample(samp);
+                               if (state<=2) {
+                                       s->DTS = (u64) ((timescale*start)/1000);
                                        s->IsRAP = 1;
                                        gf_isom_add_sample(import->dest, track, 1, s);
                                        gf_isom_sample_del(&s);
                                        nb_samp++;
+                                       prev_end = end;
                                }
-
-                               s = gf_isom_text_to_sample(samp);
-                               s->DTS = (u64) ((timescale*start)/1000);
-                               s->IsRAP = 1;
-                               gf_isom_add_sample(import->dest, track, 1, s);
-                               gf_isom_sample_del(&s);
-                               nb_samp++;
-                               prev_end = end;
                                txt_line = 0;
                                char_len = 0;
                                set_start_char = set_end_char = 0;
@@ -420,6 +435,7 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
                                gf_set_progress("Importing SRT", gf_f64_tell(srt_in), file_size);
                                if (duration && (end >= duration)) break;
                        }
+                       state = 0;
                        if (!sOK) break;
                        continue;
                }
@@ -436,12 +452,15 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
                        break;
                case 1:
                        if (sscanf(szLine, "%u:%u:%u,%u --> %u:%u:%u,%u", &sh, &sm, &ss, &sms, &eh, &em, &es, &ems) != 8) {
-                               e = gf_import_message(import, GF_CORRUPTED_DATA, "Error scanning SRT frame %d timing", curLine);
-                               goto exit;
+                               sh = eh = 0;
+                               if (sscanf(szLine, "%u:%u,%u --> %u:%u,%u", &sm, &ss, &sms, &em, &es, &ems) != 6) {
+                                       e = gf_import_message(import, GF_CORRUPTED_DATA, "Error scanning SRT frame %d timing", curLine);
+                                       goto exit;
+                               }
                        }
                        start = (3600*sh + 60*sm + ss)*1000 + sms;
                        if (start<end) {
-                               gf_import_message(import, GF_OK, "WARNING: corrupted SRT frame %d - starts (at %d ms) before end of previous one (%d ms) - adjusting time stamps", curLine, start, end);
+                               gf_import_message(import, GF_OK, "WARNING: overlapping SRT frame %d - starts "LLD" ms is before end of previous one "LLD" ms - adjusting time stamps", curLine, start, end);
                                start = end;
                        }
 
@@ -456,6 +475,11 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import)
                        }
                        rec.style_flags = 0;
                        state = 2;                      
+                       if (end<=prev_end) {
+                               gf_import_message(import, GF_OK, "WARNING: overlapping SRT frame %d end "LLD" is at or before previous end "LLD" - removing", curLine, end, prev_end);
+                               start = end;
+                               state = 3;                      
+                       }
                        break;
 
                default:
@@ -587,6 +611,249 @@ exit:
 }
 
 
+static GF_Err gf_text_import_webvtt(GF_MediaImporter *import)
+{
+    FILE                        *vtt_in;
+    u32                         track;
+    u32                         timescale;
+    u32                         i;
+    u32                         count;
+    GF_GenericSubtitleConfig    *cfg;
+    GF_Err                      e;
+    GF_GenericSubtitleSample    *samp;
+    GF_ISOSample                *s;
+    u32                         sh;
+    u32                         sm;
+    u32                         ss;
+    u32                         sms;
+    u32                         eh;
+    u32                         em;
+    u32                         es;
+    u32                         ems;
+    u32                         txt_line;
+    u32                         nb_samp;
+    u32                         duration;
+    Bool                        first_samp;
+    u64                         start;
+    u64                         end;
+    u64                         prev_end;
+    u64                         file_size;
+    u32                         state;
+    u32                         len;
+    u32                         ID;
+    u32                         OCR_ES_ID;
+    s32                         unicode_type;
+    char                        szLine[2048];
+    char                        szSettings[2048];
+    char                        *ptr;
+    unsigned short              uniLine[5000];
+    char                        *sOK;
+    u32                         curCue;
+    char                        *content_encoding = NULL;
+    char                        *xml_schema_loc = NULL;
+    char                        *mime_ns = "text/vtt";
+    Bool                        is_xml = 0;
+
+       vtt_in = gf_f64_open(import->in_name, "rt");
+       gf_f64_seek(vtt_in, 0, SEEK_END);
+       file_size = gf_f64_tell(vtt_in);
+       gf_f64_seek(vtt_in, 0, SEEK_SET);
+
+       unicode_type = gf_text_get_utf_type(vtt_in);
+       if (unicode_type<0) {
+               fclose(vtt_in);
+               return gf_import_message(import, GF_NOT_SUPPORTED, "Unsupported WebVTT UTF encoding");
+       }
+
+       cfg = NULL;
+       if (import->esd) {
+               if (!import->esd->slConfig) {
+                       import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
+                       import->esd->slConfig->predefined = 2;
+                       import->esd->slConfig->timestampResolution = 1000;
+               }
+               timescale = import->esd->slConfig->timestampResolution;
+               if (!timescale) timescale = 1000;
+
+               /*explicit text config*/
+               if (import->esd->decoderConfig && import->esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_GEN_SUB_CFG_TAG) {
+                       cfg = (GF_GenericSubtitleConfig *) import->esd->decoderConfig->decoderSpecificInfo;
+                       import->esd->decoderConfig->decoderSpecificInfo = NULL;
+               }
+               ID = import->esd->ESID;
+               OCR_ES_ID = import->esd->OCRESID;
+       } else {
+               timescale = 1000;
+               OCR_ES_ID = ID = 0;
+       }
+       
+       if (cfg && cfg->timescale) timescale = cfg->timescale;
+       track = gf_isom_new_track(import->dest, ID, GF_ISOM_MEDIA_SUBM, timescale);
+       if (!track) {
+               fclose(vtt_in);
+               return gf_import_message(import, gf_isom_last_error(import->dest), "Error creating WebVTT track");
+       }
+       gf_isom_set_track_enabled(import->dest, track, 1);
+       if (import->esd && !import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track);
+
+       if (OCR_ES_ID) gf_isom_set_track_reference(import->dest, track, GF_ISOM_REF_OCR, OCR_ES_ID);
+
+       /*setup track*/
+       if (cfg) {
+               /*set track info*/
+               gf_isom_set_track_layout_info(import->dest, track, cfg->text_width<<16, cfg->text_height<<16, 0, 0, cfg->layer);
+
+               /*and set sample descriptions*/
+               count = gf_list_count(cfg->sample_descriptions);
+               for (i=0; i<count; i++) {
+//                     GF_GenericSubtitleSampleDescriptor *sd= (GF_GenericSubtitleSampleDescriptor *)gf_list_get(cfg->sample_descriptions, i);
+                       gf_isom_new_generic_subtitle_description(import->dest, track, content_encoding, xml_schema_loc, mime_ns, is_xml, NULL, NULL, &state);
+               }
+               gf_import_message(import, GF_OK, "WebVTT import - text track %d x %d", cfg->text_width, cfg->text_height);
+               gf_odf_desc_del((GF_Descriptor *)cfg);
+       } else {
+               u32                     w;
+        u32                     h;
+
+        gf_text_get_video_size(import, &w, &h);
+               gf_isom_set_track_layout_info(import->dest, track, w<<16, h<<16, 0, 0, 0);
+
+        gf_isom_new_generic_subtitle_description(import->dest, track, content_encoding, xml_schema_loc, mime_ns, is_xml, NULL, NULL, &state);
+               
+        gf_import_message(import, GF_OK, "WebVTT import");
+       }
+       gf_text_import_set_language(import, track);
+       duration = (u32) (((Double) import->duration)*timescale/1000.0);
+
+       e           = GF_OK;
+       state       = 0;
+       end         = 0;
+    prev_end    = 0;
+       txt_line    = 0;
+       start       = 0;
+       nb_samp     = 0;
+    curCue      = 0;
+       samp        = gf_isom_new_generic_subtitle_sample();
+
+       sOK = gf_text_get_utf8_line(szLine, 2048, vtt_in, unicode_type);
+    len = strlen(szLine);
+       if (len < 6 || strnicmp(szLine, "WEBVTT", 6)) {
+               e = gf_import_message(import, GF_CORRUPTED_DATA, "Bad WebVTT formatting - expecting WEBVTT file signature", szLine);
+               goto exit;
+       } else if (len > 6) {
+        /* ignore additional text on the same line as WEBVTT file signature */
+    }
+       gf_isom_generic_subtitle_sample_add_text(samp, szLine, len);
+       txt_line ++;
+    gf_isom_generic_subtitle_sample_add_text(samp, "\n", 1);
+       txt_line ++;
+
+       first_samp = 1;
+       while (1) {
+               sOK = gf_text_get_utf8_line(szLine, 2048, vtt_in, unicode_type);
+               if (sOK) REM_TRAIL_MARKS(szLine, "\r\n\t ")
+               if (!sOK || !strlen(szLine)) {
+                       state = 0;
+                       if (txt_line) {
+                               if (prev_end && (start > prev_end)) {
+                                       GF_GenericSubtitleSample * empty_samp = gf_isom_new_generic_subtitle_sample();
+                                       s = gf_isom_generic_subtitle_to_sample(empty_samp);
+                                       gf_isom_delete_generic_subtitle_sample(empty_samp);
+                                       s->DTS = (u64) ((timescale*prev_end)/1000);
+                                       s->IsRAP = 1;
+                                       e = gf_isom_add_sample(import->dest, track, 1, s);
+                                       gf_isom_sample_del(&s);
+                                       nb_samp++;
+                               }
+
+                               s = gf_isom_generic_subtitle_to_sample(samp);
+                               s->DTS = (u64) ((timescale*start)/1000);
+                               s->IsRAP = 1;
+                               e = gf_isom_add_sample(import->dest, track, 1, s);
+                               gf_isom_sample_del(&s);
+                               nb_samp++;
+                               txt_line = 0;
+                               prev_end = end;
+                               gf_isom_generic_subtitle_reset(samp);
+
+                               //gf_import_progress(import, nb_samp, nb_samp+1);
+                               gf_set_progress("Importing WebVTT", gf_f64_tell(vtt_in), file_size);
+                               if (duration && (end >= duration)) break;
+                       }
+                       if (!sOK) break;
+                       continue;
+               }
+
+               switch (state) {
+               case 0:
+            if (!strstr(szLine, "-->")) {
+                /*cue id = szLine */
+                state = 1;
+                           gf_isom_generic_subtitle_sample_add_text(samp, szLine, strlen(szLine));
+                           txt_line ++;
+                gf_isom_generic_subtitle_sample_add_text(samp, "\n", 1);
+                           txt_line ++;
+                break;
+            }
+
+        case 1:
+            /* TODO: fix the parsing of time stamps to be compliant */
+                       if (sscanf(szLine, "%u:%u:%u.%u --> %u:%u:%u.%u %s", &sh, &sm, &ss, &sms, &eh, &em, &es, &ems, szSettings) < 8) {
+                               e = gf_import_message(import, GF_CORRUPTED_DATA, "Error scanning WebVTT cue timing for cue %d", curCue);
+                               goto exit;
+                       } else {
+                /* ignore cue settings */
+            }
+            curCue++;
+                       start = (3600*sh + 60*sm + ss)*1000 + sms;
+                       end = (3600*eh + 60*em + es)*1000 + ems;
+                       /*make stream start at 0 by inserting a fake AU*/
+                       if (first_samp && (start>0)) {
+                               s = gf_isom_generic_subtitle_to_sample(samp);
+                               s->DTS = 0;
+                               gf_isom_add_sample(import->dest, track, 1, s);
+                               gf_isom_sample_del(&s);
+                               nb_samp++;
+                       }
+                       gf_isom_generic_subtitle_sample_add_text(samp, szLine, strlen(szLine));
+                       txt_line ++;
+            gf_isom_generic_subtitle_sample_add_text(samp, "\n", 1);
+                       txt_line ++;
+                       state = 2;
+                       break;
+
+               default: /*state = 2 */
+                       /*reset only when text is present*/
+                       first_samp = 0;
+
+                       ptr = (char *) szLine;
+                       len = gf_utf8_mbstowcs(uniLine, 5000, (const char **) &ptr);
+                       if (len == (u32) -1) {
+                               e = gf_import_message(import, GF_CORRUPTED_DATA, "Invalid UTF data in cue %d", curCue);
+                               goto exit;
+                       }
+                       gf_isom_generic_subtitle_sample_add_text(samp, szLine, len);
+                       txt_line ++;
+            gf_isom_generic_subtitle_sample_add_text(samp, "\n", 1);
+                       txt_line ++;
+                       break;
+               }
+               if (duration && (start >= duration)) break;
+       }
+
+       gf_isom_delete_generic_subtitle_sample(samp);
+       /*do not add any empty sample at the end since it modifies track duration and is not needed - it is the player job
+       to figure out when to stop displaying the last text sample
+       However update the last sample duration*/
+       gf_isom_set_last_sample_duration(import->dest, track, (u32) (end-start) );
+       gf_set_progress("Importing WebVTT", nb_samp, nb_samp);
+
+exit:
+       if (e) gf_isom_remove_track(import->dest, track);
+       fclose(vtt_in);
+       return e;
+}
+
 static GF_Err gf_text_import_sub(GF_MediaImporter *import)
 {
        FILE *sub_in;
@@ -678,7 +945,7 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import)
        } else {
                u32 w, h;
                GF_TextSampleDescriptor *sd;
-               gf_text_get_video_size(import->dest, &w, &h);
+               gf_text_get_video_size(import, &w, &h);
 
                /*have to work with default - use max size (if only one video, this means the text region is the
                entire display, and with bottom alignment things should be fine...*/
@@ -700,9 +967,10 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import)
                        sd->default_pos.top = sd->default_pos.left = sd->default_pos.right = sd->default_pos.bottom = 0;
                } else {
                        if ((sd->default_pos.bottom==sd->default_pos.top) || (sd->default_pos.right==sd->default_pos.left)) {
-                               sd->default_pos.top = sd->default_pos.left = 0;
-                               sd->default_pos.right = import->twidth ? import->twidth : w;
-                               sd->default_pos.bottom = import->theight ? import->theight : h;
+                               sd->default_pos.left = import->text_x;
+                               sd->default_pos.top = import->text_y;
+                               sd->default_pos.right = (import->text_width ? import->text_width : w) + sd->default_pos.left;
+                               sd->default_pos.bottom = (import->text_height ? import->text_height : h) + sd->default_pos.top;
                        }
                }
 
@@ -1702,6 +1970,7 @@ GF_Err gf_import_timed_text(GF_MediaImporter *import)
        case GF_TEXT_IMPORT_SUB: return gf_text_import_sub(import);
        case GF_TEXT_IMPORT_TTXT: return gf_text_import_ttxt(import);
        case GF_TEXT_IMPORT_TEXML: return gf_text_import_texml(import);
+       case GF_TEXT_IMPORT_WEBVTT: return gf_text_import_webvtt(import);
        default: return GF_BAD_PARAM;
        }
 }
index cb3059b88d499adf546c0d17af358b6dbc861aff..df63d5eb403254b6136c24e01746c911028d0f6f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 780aef65c5900453e3e55dce60837ebe26e1eff7..ea42ff4deb4a4daf7e21d4d0d6fdd7cf2645b9c0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
@@ -508,6 +509,16 @@ void gf_odf_avc_cfg_del(GF_AVCConfig *cfg)
                gf_free(sl);
        }
        gf_list_del(cfg->pictureParameterSets);
+
+       if (cfg->sequenceParameterSetExtensions) {
+               while (gf_list_count(cfg->sequenceParameterSetExtensions)) {
+                       GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(cfg->sequenceParameterSetExtensions, 0);
+                       gf_list_rem(cfg->sequenceParameterSetExtensions, 0);
+                       if (sl->data) gf_free(sl->data);
+                       gf_free(sl);
+               }
+               gf_list_del(cfg->pictureParameterSets);
+       }
        gf_free(cfg);
 }
 
@@ -537,7 +548,27 @@ GF_Err gf_odf_avc_cfg_write(GF_AVCConfig *cfg, char **outData, u32 *outSize)
                gf_bs_write_int(bs, sl->size, 16);
                gf_bs_write_data(bs, sl->data, sl->size);
        }
-
+       switch (cfg->AVCProfileIndication) {
+       case 100:
+       case 110:
+       case 122:
+       case 144:
+               gf_bs_write_int(bs, 0xFF, 6);
+               gf_bs_write_int(bs, cfg->chroma_format, 2);
+               gf_bs_write_int(bs, 0xFF, 5);
+               gf_bs_write_int(bs, cfg->luma_bit_depth - 8, 3);
+               gf_bs_write_int(bs, 0xFF, 5);
+               gf_bs_write_int(bs, cfg->chroma_bit_depth - 8, 3);
+
+               count = cfg->sequenceParameterSetExtensions ? gf_list_count(cfg->sequenceParameterSetExtensions) : 0;
+               gf_bs_write_u8(bs, count);
+               for (i=0; i<count; i++) {
+                       GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *) gf_list_get(cfg->sequenceParameterSetExtensions, i);
+                       gf_bs_write_u16(bs, sl->size);
+                       gf_bs_write_data(bs, sl->data, sl->size);
+               }
+               break;
+       }
        *outSize = 0;
        *outData = NULL;
        gf_bs_get_content(bs, outData, outSize);
@@ -574,6 +605,33 @@ GF_AVCConfig *gf_odf_avc_cfg_read(char *dsi, u32 dsi_size)
                gf_bs_read_data(bs, sl->data, sl->size);
                gf_list_add(avcc->pictureParameterSets, sl);
        }
+       switch (avcc->AVCProfileIndication) {
+       case 100:
+       case 110:
+       case 122:
+       case 144:
+               gf_bs_read_int(bs, 6);
+               avcc->chroma_format = gf_bs_read_int(bs, 2);
+               gf_bs_read_int(bs, 5);
+               avcc->luma_bit_depth = 8 + gf_bs_read_int(bs, 3);
+               gf_bs_read_int(bs, 5);
+               avcc->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3);
+
+               count = gf_bs_read_int(bs, 8);
+               if (count) {
+                       avcc->sequenceParameterSetExtensions = gf_list_new();
+                       for (i=0; i<count; i++) {
+                               GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_malloc(sizeof(GF_AVCConfigSlot));
+                               sl->size = gf_bs_read_u16(bs);
+                               sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
+                               gf_bs_read_data(bs, sl->data, sl->size);
+                               gf_list_add(avcc->sequenceParameterSetExtensions, sl);
+                       }
+               }
+               break;
+       }
+
+
        gf_bs_del(bs);
        return avcc;
 }
index 145799b70529208520b8364271c6b12651c44797..db5b13909681cb7965a73f94671672629396f7c3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 3c708fdc9d9f1af678b34f72a27e2a1e588eccb9..8755ba9e478b248a26177f984a63399d0421218d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 9e8e6ce0b29501b16d8c51e12205004a579f10a1..2e4bafe80cbdd7037a7430aa4a757e008712b8c8 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index b84f7a2bae5bff624a98ebbf4f0ddb1867e941a9..5b6cd356e782cf6cacb37588bcd02b09d1d8ed68 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 059079b6540a8b92d4207de5f197d69fc0690873..8707162fa603adfa32b49fe18151d6afb426fc73 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 1fec14e01a57f35a55ca1dd5efb6ec53254b9dd3..cbf816a2c9eb7c2522c5c4c8c06fc71c18b2d268 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index a24d02b123145e7e6481826a1ca00d9d076f8393..2c34bd687edba5d0654580e2a80242e0ff8f7e31 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 12057c61d5640ac51b739486fc49721c0288ddeb..1445b88cb22a37a94b7aae17e29c05bdc5f2c38f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
@@ -53,10 +54,12 @@ GF_Err gf_odf_dump_com(void *p, FILE *trace, u32 indent, Bool XMTDump)
                return gf_odf_dump_esd_update((GF_ESDUpdate *)com, trace, indent, XMTDump);
        case GF_ODF_ESD_REMOVE_TAG:
                return gf_odf_dump_esd_remove((GF_ESDRemove *)com, trace, indent, XMTDump);
+#ifndef GPAC_MINIMAL_ODF
        case GF_ODF_IPMP_UPDATE_TAG:
                return gf_odf_dump_ipmp_update((GF_IPMPUpdate *)com, trace, indent, XMTDump);
        case GF_ODF_IPMP_REMOVE_TAG:
                return gf_odf_dump_ipmp_remove((GF_IPMPRemove *)com, trace, indent, XMTDump);
+#endif
        default:
                return gf_odf_dump_base_command((GF_BaseODCom *) com, trace, indent, XMTDump);
        }
@@ -109,6 +112,17 @@ GF_Err gf_odf_dump_desc(void *ptr, FILE *trace, u32 indent, Bool XMTDump)
                return gf_odf_dump_dcd((GF_DecoderConfig *)desc, trace, indent, XMTDump);
        case GF_ODF_SLC_TAG:
                return gf_odf_dump_slc((GF_SLConfig *)desc, trace, indent, XMTDump);
+       case GF_ODF_ESD_INC_TAG:
+               return gf_odf_dump_esd_inc((GF_ES_ID_Inc *)desc, trace, indent, XMTDump);
+       case GF_ODF_ESD_REF_TAG:
+               return gf_odf_dump_esd_ref((GF_ES_ID_Ref *)desc, trace, indent, XMTDump);
+       case GF_ODF_ISOM_IOD_TAG:
+               return gf_odf_dump_isom_iod((GF_IsomInitialObjectDescriptor *)desc, trace, indent, XMTDump);
+       case GF_ODF_ISOM_OD_TAG:
+               return gf_odf_dump_isom_od((GF_IsomObjectDescriptor *)desc, trace, indent, XMTDump);
+       case GF_ODF_OD_TAG:
+               return gf_odf_dump_od((GF_ObjectDescriptor *)desc, trace, indent, XMTDump);
+#ifndef GPAC_MINIMAL_ODF
        case GF_ODF_CC_TAG:
                return gf_odf_dump_cc((GF_CCDescriptor *)desc, trace, indent, XMTDump);
        case GF_ODF_CC_DATE_TAG:
@@ -117,10 +131,6 @@ GF_Err gf_odf_dump_desc(void *ptr, FILE *trace, u32 indent, Bool XMTDump)
                return gf_odf_dump_cc_name((GF_CC_Name *)desc, trace, indent, XMTDump);
        case GF_ODF_CI_TAG:
                return gf_odf_dump_ci((GF_CIDesc *)desc, trace, indent, XMTDump);
-       case GF_ODF_ESD_INC_TAG:
-               return gf_odf_dump_esd_inc((GF_ES_ID_Inc *)desc, trace, indent, XMTDump);
-       case GF_ODF_ESD_REF_TAG:
-               return gf_odf_dump_esd_ref((GF_ES_ID_Ref *)desc, trace, indent, XMTDump);
        case GF_ODF_TEXT_TAG:
                return gf_odf_dump_exp_text((GF_ExpandedTextual *)desc, trace, indent, XMTDump);
        case GF_ODF_EXT_PL_TAG:
@@ -136,12 +146,6 @@ GF_Err gf_odf_dump_desc(void *ptr, FILE *trace, u32 indent, Bool XMTDump)
                return gf_odf_dump_kw((GF_KeyWord *)desc, trace, indent, XMTDump);
        case GF_ODF_LANG_TAG:
                return gf_odf_dump_lang((GF_Language *)desc, trace, indent, XMTDump);
-       case GF_ODF_ISOM_IOD_TAG:
-               return gf_odf_dump_isom_iod((GF_IsomInitialObjectDescriptor *)desc, trace, indent, XMTDump);
-       case GF_ODF_ISOM_OD_TAG:
-               return gf_odf_dump_isom_od((GF_IsomObjectDescriptor *)desc, trace, indent, XMTDump);
-       case GF_ODF_OD_TAG:
-               return gf_odf_dump_od((GF_ObjectDescriptor *)desc, trace, indent, XMTDump);
        case GF_ODF_OCI_DATE_TAG:
                return gf_odf_dump_oci_date((GF_OCI_Data *)desc, trace, indent, XMTDump);
        case GF_ODF_OCI_NAME_TAG:
@@ -164,6 +168,11 @@ GF_Err gf_odf_dump_desc(void *ptr, FILE *trace, u32 indent, Bool XMTDump)
                return gf_odf_dump_segment((GF_Segment *)desc, trace, indent, XMTDump);
        case GF_ODF_MEDIATIME_TAG:
                return gf_odf_dump_mediatime((GF_MediaTime *)desc, trace, indent, XMTDump);
+       case GF_ODF_IPMP_TL_TAG:
+               return gf_odf_dump_ipmp_tool_list((GF_IPMP_ToolList*)desc, trace, indent, XMTDump);
+       case GF_ODF_IPMP_TOOL_TAG:
+               return gf_odf_dump_ipmp_tool((GF_IPMP_Tool*)desc, trace, indent, XMTDump);
+#endif //GPAC_MINIMAL_ODF
        case GF_ODF_TEXT_CFG_TAG:
                return gf_odf_dump_txtcfg((GF_TextConfig *)desc, trace, indent, XMTDump);
        case GF_ODF_MUXINFO_TAG:
@@ -174,10 +183,6 @@ GF_Err gf_odf_dump_desc(void *ptr, FILE *trace, u32 indent, Bool XMTDump)
                return gf_odf_dump_laser_cfg((GF_LASERConfig *)desc, trace, indent, XMTDump);
        case GF_ODF_UI_CFG_TAG:
                return gf_odf_dump_ui_cfg((GF_UIConfig *)desc, trace, indent, XMTDump);
-       case GF_ODF_IPMP_TL_TAG:
-               return gf_odf_dump_ipmp_tool_list((GF_IPMP_ToolList*)desc, trace, indent, XMTDump);
-       case GF_ODF_IPMP_TOOL_TAG:
-               return gf_odf_dump_ipmp_tool((GF_IPMP_Tool*)desc, trace, indent, XMTDump);
        case GF_ODF_AUX_VIDEO_DATA:
                return gf_odf_dump_aux_vid((GF_AuxVideoDescriptor *)desc, trace, indent, XMTDump);
        default:
@@ -297,6 +302,7 @@ static void DumpIntHex(FILE *trace, const char *attName, u32  val, u32 indent, B
        EndAttribute(trace, indent, XMTDump);
 }
 
+#ifndef GPAC_MINIMAL_ODF
 static void DumpFloat(FILE *trace, const char *attName, Float val, u32 indent, Bool XMTDump)
 {
        StartAttribute(trace, attName, indent, XMTDump);
@@ -310,6 +316,23 @@ static void DumpDouble(FILE *trace, const char *attName, Double val, u32 indent,
        fprintf(trace, "%g", val);
        EndAttribute(trace, indent, XMTDump);
 }
+static void DumpBin128(FILE *trace, const char *name, char *data, u32 indent, Bool XMTDump)
+{
+       u32 i;
+       if (!name ||!data) return;
+       StartAttribute(trace, name, indent, XMTDump);
+       fprintf(trace, "0x");
+       i=0;
+       while (!data[i] && (i<16)) i++;
+       if (i==16) {
+               fprintf(trace, "00");
+       } else {
+               for (; i<16; i++) fprintf(trace, "%02X", (unsigned char) data[i]);
+       }
+       EndAttribute(trace, indent, XMTDump);
+}
+
+#endif
 
 static void DumpBool(FILE *trace, const char *attName, u32  val, u32 indent, Bool XMTDump)
 {
@@ -342,22 +365,6 @@ static void DumpData(FILE *trace, const char *name, char *data, u64 dataLength,
        }
        EndAttribute(trace, indent, XMTDump);
 }
-static void DumpBin128(FILE *trace, const char *name, char *data, u32 indent, Bool XMTDump)
-{
-       u32 i;
-       if (!name ||!data) return;
-       StartAttribute(trace, name, indent, XMTDump);
-       fprintf(trace, "0x");
-       i=0;
-       while (!data[i] && (i<16)) i++;
-       if (i==16) {
-               fprintf(trace, "00");
-       } else {
-               for (; i<16; i++) fprintf(trace, "%02X", (unsigned char) data[i]);
-       }
-       EndAttribute(trace, indent, XMTDump);
-}
-
 
 GF_Err DumpDescList(GF_List *list, FILE *trace, u32 indent, const char *ListName, Bool XMTDump, Bool no_skip_empty)
 {
@@ -1027,6 +1034,58 @@ GF_Err gf_odf_dump_slc(GF_SLConfig *sl, FILE *trace, u32 indent, Bool XMTDump)
        return GF_OK;
 }
 
+GF_Err gf_odf_dump_default(GF_DefaultDescriptor *dd, FILE *trace, u32 indent, Bool XMTDump)
+{
+       if (dd->tag == GF_ODF_DSI_TAG) {
+               StartDescDump(trace, "DecoderSpecificInfo", indent, XMTDump);
+               indent++;
+               if (XMTDump) {
+                       DumpString(trace, "type", "auto", indent, XMTDump);
+                       DumpData(trace, "src", dd->data, dd->dataLength, indent, XMTDump);
+               } else {
+                       DumpData(trace, "info", dd->data, dd->dataLength, indent, XMTDump);
+               }
+               indent--;
+               if (XMTDump) {
+                       EndSubElement(trace, indent, 1);
+               } else {
+                       EndDescDump(trace, "", indent, 0);
+               }
+       } else {
+               StartDescDump(trace, "DefaultDescriptor", indent, XMTDump);
+               indent++;
+               DumpData(trace, "data", dd->data, dd->dataLength, indent, XMTDump);
+               indent--;
+               EndSubElement(trace, indent, XMTDump);
+       }
+       return GF_OK;
+}
+
+GF_Err gf_odf_dump_esd_inc(GF_ES_ID_Inc *esd_inc, FILE *trace, u32 indent, Bool XMTDump)
+{
+       StartDescDump(trace, "ES_ID_Inc", indent, XMTDump);
+       indent++;
+       DumpInt(trace, "trackID", esd_inc->trackID, indent, XMTDump);
+       indent--;
+       EndAttributes(trace, indent, XMTDump);
+       EndDescDump(trace, "ES_ID_Inc", indent, XMTDump);
+       return GF_OK;
+}
+
+GF_Err gf_odf_dump_esd_ref(GF_ES_ID_Ref *esd_ref, FILE *trace, u32 indent, Bool XMTDump)
+{
+       StartDescDump(trace, "ES_ID_Ref", indent, XMTDump);
+       indent++;
+       DumpInt(trace, "trackRef", esd_ref->trackRef, indent, XMTDump);
+       indent--;
+       EndAttributes(trace, indent, XMTDump);
+       EndDescDump(trace, "ES_ID_Ref", indent, XMTDump);
+       return GF_OK;
+}
+
+
+#ifndef GPAC_MINIMAL_ODF
+
 GF_Err gf_odf_dump_cc(GF_CCDescriptor *ccd, FILE *trace, u32 indent, Bool XMTDump)
 {
        StartDescDump(trace, "ContentClassificationDescriptor", indent, XMTDump);
@@ -1091,54 +1150,6 @@ GF_Err gf_odf_dump_ci(GF_CIDesc *cid, FILE *trace, u32 indent, Bool XMTDump)
        return GF_OK;
 }
 
-GF_Err gf_odf_dump_default(GF_DefaultDescriptor *dd, FILE *trace, u32 indent, Bool XMTDump)
-{
-       if (dd->tag == GF_ODF_DSI_TAG) {
-               StartDescDump(trace, "DecoderSpecificInfo", indent, XMTDump);
-               indent++;
-               if (XMTDump) {
-                       DumpString(trace, "type", "auto", indent, XMTDump);
-                       DumpData(trace, "src", dd->data, dd->dataLength, indent, XMTDump);
-               } else {
-                       DumpData(trace, "info", dd->data, dd->dataLength, indent, XMTDump);
-               }
-               indent--;
-               if (XMTDump) {
-                       EndSubElement(trace, indent, 1);
-               } else {
-                       EndDescDump(trace, "", indent, 0);
-               }
-       } else {
-               StartDescDump(trace, "DefaultDescriptor", indent, XMTDump);
-               indent++;
-               DumpData(trace, "data", dd->data, dd->dataLength, indent, XMTDump);
-               indent--;
-               EndSubElement(trace, indent, XMTDump);
-       }
-       return GF_OK;
-}
-
-GF_Err gf_odf_dump_esd_inc(GF_ES_ID_Inc *esd_inc, FILE *trace, u32 indent, Bool XMTDump)
-{
-       StartDescDump(trace, "ES_ID_Inc", indent, XMTDump);
-       indent++;
-       DumpInt(trace, "trackID", esd_inc->trackID, indent, XMTDump);
-       indent--;
-       EndAttributes(trace, indent, XMTDump);
-       EndDescDump(trace, "ES_ID_Inc", indent, XMTDump);
-       return GF_OK;
-}
-
-GF_Err gf_odf_dump_esd_ref(GF_ES_ID_Ref *esd_ref, FILE *trace, u32 indent, Bool XMTDump)
-{
-       StartDescDump(trace, "ES_ID_Ref", indent, XMTDump);
-       indent++;
-       DumpInt(trace, "trackRef", esd_ref->trackRef, indent, XMTDump);
-       indent--;
-       EndAttributes(trace, indent, XMTDump);
-       EndDescDump(trace, "ES_ID_Ref", indent, XMTDump);
-       return GF_OK;
-}
 
 GF_Err gf_odf_dump_exp_text(GF_ExpandedTextual *etd, FILE *trace, u32 indent, Bool XMTDump)
 {
@@ -1288,6 +1299,7 @@ GF_Err gf_odf_dump_lang(GF_Language *ld, FILE *trace, u32 indent, Bool XMTDump)
        if (!XMTDump) EndDescDump(trace, "LanguageDescriptor", indent, XMTDump);
        return GF_OK;
 }
+#endif// GPAC_MINIMAL_ODF
 
 GF_Err gf_odf_dump_aux_vid(GF_AuxVideoDescriptor *ld, FILE *trace, u32 indent, Bool XMTDump)
 {
@@ -1464,6 +1476,7 @@ GF_Err gf_odf_dump_isom_od(GF_IsomObjectDescriptor *od, FILE *trace, u32 indent,
        return GF_OK;
 }
 
+#ifndef GPAC_MINIMAL_ODF
 GF_Err gf_odf_dump_oci_date(GF_OCI_Data *ocd, FILE *trace, u32 indent, Bool XMTDump)
 {
        StartDescDump(trace, "OCICreationDateDescriptor", indent, XMTDump);
@@ -1668,6 +1681,7 @@ GF_Err gf_odf_dump_mediatime(GF_MediaTime *mt, FILE *trace, u32 indent, Bool XMT
        return GF_OK;
 }
 
+#endif //GPAC_MINIMAL_ODF
 
 GF_Err gf_odf_dump_muxinfo(GF_MuxInfo *mi, FILE *trace, u32 indent, Bool XMTDump)
 {
@@ -1719,6 +1733,7 @@ GF_Err gf_odf_dump_muxinfo(GF_MuxInfo *mi, FILE *trace, u32 indent, Bool XMTDump
        return GF_OK;
 }
 
+#ifndef GPAC_MINIMAL_ODF
 GF_Err gf_odf_dump_ipmp_tool_list(GF_IPMP_ToolList *tl, FILE *trace, u32 indent, Bool XMTDump)
 {
        StartDescDump(trace, "IPMP_ToolListDescriptor", indent, XMTDump);
@@ -1748,6 +1763,7 @@ GF_Err gf_odf_dump_ipmp_tool(GF_IPMP_Tool*t, FILE *trace, u32 indent, Bool XMTDu
        EndDescDump(trace, "IPMP_Tool", indent, XMTDump);
        return GF_OK;
 }
+#endif //GPAC_MINIMAL_ODF
 
 
 GF_Err gf_odf_dump_od_update(GF_ODUpdate *com, FILE *trace, u32 indent, Bool XMTDump)
@@ -1846,6 +1862,7 @@ GF_Err gf_odf_dump_esd_remove(GF_ESDRemove *com, FILE *trace, u32 indent, Bool X
        return GF_OK;
 }
 
+#ifndef GPAC_MINIMAL_ODF
 GF_Err gf_odf_dump_ipmp_update(GF_IPMPUpdate *com, FILE *trace, u32 indent, Bool XMTDump)
 {
        if (XMTDump) {
@@ -1878,6 +1895,7 @@ GF_Err gf_odf_dump_ipmp_remove(GF_IPMPRemove *com, FILE *trace, u32 indent, Bool
        EndSubElement(trace, indent, XMTDump);
        return GF_OK;
 }
+#endif //GPAC_MINIMAL_ODF
 
 GF_Err gf_odf_dump_base_command(GF_BaseODCom *com, FILE *trace, u32 indent, Bool XMTDump)
 {
index ab93f3ec3bbb7ff72f7a9a2d68f8e1cfadaeb2bf..3fa81e3e0303d9ec0f384edbd2ab9df3595f53f7 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index f20702aa449856a0694477472518d9c34d459cf1..a7a8fd769f7004e5b9339046caf9c4b357e18f86 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index b0bd1e63be65c438c7ce71f5c07e608b643177fe..462df9001fa74163488c9cac93abe3de663edd0b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
index 021b4e582a2669466308c4da7d3a4fdea6873a4b..6b37b2a51565d2a1c9fa987efbf6957ac1b1476c 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
@@ -268,6 +269,10 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD
        e = gf_media_import(&import);
        if (e) return e;
 
+       if (src->OCRESID) {
+               gf_isom_set_track_reference(mp4, gf_isom_get_track_by_id(mp4, import.final_trackID), GF_ISOM_REF_OCR, src->OCRESID);
+       }
+
        i=0;
        while ((d = gf_list_enum(src->extensionDescriptors, &i))) {
                if (d->tag == GF_ODF_AUX_VIDEO_DATA) {
index 78b908c242f4c58e78cea50f17dafcca7243aa7a..5ceeb21c9ce4907700beca63691d40ab9c3b15e3 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
 #include <gpac/nodes_x3d.h>
 /*for key codes...*/
 #include <gpac/user.h>
-#include <gpac/base_coding.h>
-#include <gpac/network.h>
-
-
-void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName)
-{
-       u32 data_size = 0;
-       char *data = NULL;
-       char *buffer; 
-       M_BitWrapper *bw = (M_BitWrapper *)node;
-
-       if (!bw->buffer.buffer) return;
-       buffer = bw->buffer.buffer;
-       if (!strnicmp(buffer, "file://", 7)) {
-               char *url = gf_url_concatenate(fileName, buffer+7);
-               if (url) {
-                       FILE *f = fopen(url, "rb");
-                       if (f) {
-                               fseek(f, 0, SEEK_END);
-                               data_size = ftell(f);
-                               fseek(f, 0, SEEK_SET);
-                               data = gf_malloc(sizeof(char)*data_size);
-                               if (data) {
-                                       size_t s = fread(data, 1, data_size, f);
-                                       assert(s == data_size);
-                               }
-                               fclose(f);
-                       }
-                       gf_free(url);
-               }
-       } else {
-               Bool base_64 = 0;
-               if (!strnicmp(buffer, "data:application/octet-string", 29)) {
-                       char *sep = strchr(bw->buffer.buffer, ',');
-                       base_64 = strstr(bw->buffer.buffer, ";base64") ? 1 : 0;
-                       if (sep) buffer = sep+1;
-               }
-                       
-               if (base_64) {
-                       data_size = 2*strlen(buffer);
-                       data = (char*)gf_malloc(sizeof(char)*data_size);
-                       if (data) 
-                               data_size = gf_base64_decode(buffer, strlen(buffer), data, data_size);
-               } else {
-                       u32 i, c;
-                       char s[3];
-                       data_size = strlen(buffer) / 3;
-                       data = (char*)gf_malloc(sizeof(char) * data_size);
-                       if (data) {
-                               s[2] = 0;
-                               for (i=0; i<data_size; i++) {
-                                       s[0] = buffer[3*i+1];
-                                       s[1] = buffer[3*i+2];
-                                       sscanf(s, "%02X", &c);
-                                       data[i] = (unsigned char) c;
-                               }
-                       }
-               }
-       }
-       gf_free(bw->buffer.buffer);
-       bw->buffer.buffer = NULL;
-       bw->buffer_len = 0;
-       if (data) {
-               bw->buffer.buffer = data;
-               bw->buffer_len = data_size;
-       }
-
-}
 
 
 #ifndef GPAC_DISABLE_LOADER_BT
@@ -108,6 +41,7 @@ void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName)
 /*since 0.2.2, we use zlib for bt reading to handle wrl.gz files*/
 #include <zlib.h>
 
+void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName);
 
 void load_bt_done(GF_SceneLoader *load);
 
index 20eee00e57b9b3e4c780901da8d7258c13c694b7..5a11a5b93ef56857254dddbc3fc132898821bd15 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index b84ac02b06a2bf30793bd447b76423dd5e841c7e..15270ff732c76b9d845909437c1b4ef17cc3c61f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index cedbab8ac26ab63abd43f54368561dbf4a02531a..872deca41dd19f3472092af2a2fe45c07fea9780 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre, Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index 86c336bcf6b093a81c7cf37d4e793c997d97c059..a617c8307e6bf7a2a7456aa9d1fc4e5cb791e42d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
 #include <gpac/internal/scenegraph_dev.h>
 #include <gpac/nodes_x3d.h>
 
-void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName);
-
 #ifndef GPAC_DISABLE_LOADER_XMT
 
+void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName);
 
 /*for QP types*/
 #include "../bifs/quant.h"
index b60a27ae24eafac50c4ec985f1455e12490a8094..f82800720bb1a4c6936ab5a65c35e33f84584462 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index 02210336311d0ddc4d9ac446475bfe799e7b7150..e2254fb51c7d90de98a229b44ba135f5b2bb6de9 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre, Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / ISO Media File Format sub-project
index 9cc2752e0a4e61dd09c65c9334f0af174b375272..819f045f160ccaebc3469d1e62b2e8b304f880c2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
@@ -28,6 +29,7 @@
 #include <gpac/bifs.h>
 #include <gpac/xml.h>
 #include <gpac/internal/scenegraph_dev.h>
+#include <gpac/network.h>
 
 
 GF_EXPORT
@@ -731,3 +733,73 @@ GF_Err gf_sm_load_suspend(GF_SceneLoader *load, Bool suspend)
        if (load->suspend) return load->suspend(load, suspend);
        return GF_OK;
 }
+
+#if !defined(GPAC_DISABLE_LOADER_BT) || !defined(GPAC_DISABLE_LOADER_XMT)
+#include <gpac/base_coding.h>
+void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName)
+{
+       u32 data_size = 0;
+       char *data = NULL;
+       char *buffer; 
+       M_BitWrapper *bw = (M_BitWrapper *)node;
+
+       if (!bw->buffer.buffer) return;
+       buffer = bw->buffer.buffer;
+       if (!strnicmp(buffer, "file://", 7)) {
+               char *url = gf_url_concatenate(fileName, buffer+7);
+               if (url) {
+                       FILE *f = fopen(url, "rb");
+                       if (f) {
+                               fseek(f, 0, SEEK_END);
+                               data_size = ftell(f);
+                               fseek(f, 0, SEEK_SET);
+                               data = gf_malloc(sizeof(char)*data_size);
+                               if (data) {
+                                       size_t s = fread(data, 1, data_size, f);
+                                       assert(s == data_size);
+                               }
+                               fclose(f);
+                       }
+                       gf_free(url);
+               }
+       } else {
+               Bool base_64 = 0;
+               if (!strnicmp(buffer, "data:application/octet-string", 29)) {
+                       char *sep = strchr(bw->buffer.buffer, ',');
+                       base_64 = strstr(bw->buffer.buffer, ";base64") ? 1 : 0;
+                       if (sep) buffer = sep+1;
+               }
+                       
+               if (base_64) {
+                       data_size = 2*strlen(buffer);
+                       data = (char*)gf_malloc(sizeof(char)*data_size);
+                       if (data) 
+                               data_size = gf_base64_decode(buffer, strlen(buffer), data, data_size);
+               } else {
+                       u32 i, c;
+                       char s[3];
+                       data_size = strlen(buffer) / 3;
+                       data = (char*)gf_malloc(sizeof(char) * data_size);
+                       if (data) {
+                               s[2] = 0;
+                               for (i=0; i<data_size; i++) {
+                                       s[0] = buffer[3*i+1];
+                                       s[1] = buffer[3*i+2];
+                                       sscanf(s, "%02X", &c);
+                                       data[i] = (unsigned char) c;
+                               }
+                       }
+               }
+       }
+       gf_free(bw->buffer.buffer);
+       bw->buffer.buffer = NULL;
+       bw->buffer_len = 0;
+       if (data) {
+               bw->buffer.buffer = data;
+               bw->buffer_len = data_size;
+       }
+
+}
+#endif //!defined(GPAC_DISABLE_LOADER_BT) || !defined(GPAC_DISABLE_LOADER_XMT)
+
+
index cb73599c4545c1ea3a6d73e0ecb30f57dc99096a..a36ae003da5bb1e16114fc09c9f0e2b343906315 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index da983b8148fd6d0f9d334e967471878c42dec1cd..38e2874eeaa80563ef8a1f0601abbf9b1c0fc4e4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index 8bebbb7232fe7eae0472ec079fea4c03460b3677..1b5b39bb23210412ae49856c1aa85f68b3a16774 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
 #ifndef GPAC_DISABLE_SWF_IMPORT
 
 
-/*display list item (one per layer only)*/
-typedef struct
-{
-       GF_Matrix2D mat;
-       GF_ColorMatrix cmat;
-       u32 depth;
-       u32 char_id;
-} DispShape;
-
 enum
 {
        SWF_END = 0,
@@ -2090,6 +2082,7 @@ static GF_Err swf_def_bits_jpeg(SWFReader *read, u32 version)
                fclose(file);
 
        if (version==3) {
+#ifndef GPAC_DISABLE_AV_PARSERS
                char *dst, *raw;
                u8 oti;
                u32 osize, w, h, j, pf;
@@ -2135,6 +2128,7 @@ static GF_Err swf_def_bits_jpeg(SWFReader *read, u32 version)
                fclose(file);
                
                gf_free(raw);
+#endif //GPAC_DISABLE_AV_PARSERS
        }
        gf_free(buf);
 
@@ -2482,7 +2476,11 @@ GF_Err gf_sm_load_init_swf(GF_SceneLoader *load)
                read->no_as = 1;
        }
 
-       e = swf_to_bifs_init(read);
+    if (!(load->swf_import_flags & GF_SM_SWF_USE_SVG)) {
+        e = swf_to_bifs_init(read);
+    } else {
+        e = swf_to_svg_init(read);
+    }
        if (e) goto exit;
 
        /*parse all tags*/
diff --git a/src/scene_manager/swf_svg.c b/src/scene_manager/swf_svg.c
new file mode 100644 (file)
index 0000000..1001a4e
--- /dev/null
@@ -0,0 +1,1182 @@
+/*\r
+ *          GPAC - Multimedia Framework C SDK\r
+ *\r
+ *          Authors: Cyril Concolato\r
+ *          Copyright (c) Telecom ParisTech 2000-2012\r
+ *                  All rights reserved\r
+ *\r
+ *  This file is part of GPAC / Scene Management sub-project\r
+ *\r
+ *  GPAC is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU Lesser General Public License as published by\r
+ *  the Free Software Foundation; either version 2, or (at your option)\r
+ *  any later version.\r
+ *   \r
+ *  GPAC is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU Lesser General Public License for more details.\r
+ *   \r
+ *  You should have received a copy of the GNU Lesser General Public\r
+ *  License along with this library; see the file COPYING.  If not, write to\r
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+#include <gpac/utf.h>\r
+#include <gpac/xml.h>\r
+#include <gpac/internal/swf_dev.h>\r
+#include <gpac/internal/scenegraph_dev.h>\r
+\r
+#ifndef GPAC_DISABLE_VRML\r
+\r
+#ifndef GPAC_DISABLE_SWF_IMPORT\r
+\r
+#define SWF_TEXT_SCALE              (1/1024.0f)\r
+\r
+typedef struct\r
+{\r
+    u32 btn_id;\r
+    u32 sprite_up_id;\r
+} s2sBtnRec;\r
+\r
+static void swf_svg_print_color(SWFReader *read, u32 ARGB)\r
+{\r
+    SFColor val;\r
+    val.red = INT2FIX((ARGB>>16)&0xFF) / 255*100;\r
+    val.green = INT2FIX((ARGB>>8)&0xFF) / 255*100;\r
+    val.blue = INT2FIX((ARGB)&0xFF) / 255*100;\r
+    fprintf(read->svg_output, "rgb(%f%%,%f%%,%f%%)", FIX2FLT(val.red), FIX2FLT(val.green), FIX2FLT(val.blue));\r
+}\r
+\r
+static void swf_svg_print_alpha(SWFReader *read, u32 ARGB)\r
+{\r
+    Fixed alpha;\r
+    alpha = INT2FIX((ARGB>>24)&0xFF)/255;\r
+    fprintf(read->svg_output, "%f", FIX2FLT(alpha));\r
+}\r
+\r
+static void swg_svg_print_shape_record_to_fill_stroke(SWFReader *read, SWFShapeRec *srec, Bool is_fill)\r
+{\r
+       /*get regular appearance reuse*/\r
+       if (is_fill) {\r
+               switch (srec->type) {\r
+               /*solid/alpha fill*/\r
+               case 0x00:\r
+            fprintf(read->svg_output, "fill=\"");\r
+            swf_svg_print_color(read, srec->solid_col);\r
+            fprintf(read->svg_output, "\" ");\r
+            fprintf(read->svg_output, "fill-opacity=\"");\r
+            swf_svg_print_alpha(read, srec->solid_col);\r
+            fprintf(read->svg_output, "\" ");\r
+                       break;\r
+               case 0x10:\r
+               case 0x12:\r
+                       //if (read->flags & GF_SM_SWF_NO_GRADIENT) {\r
+                       //      u32 col = srec->grad_col[srec->nbGrad/2];\r
+                       //      col |= 0xFF000000;\r
+                       //      n->appearance = s2b_get_appearance(read, (GF_Node *) n, col, 0, 0);\r
+                       //} else {\r
+                       //      n->appearance = s2b_get_gradient(read, (GF_Node *) n, shape, srec);\r
+                       //}\r
+                       //break;\r
+               case 0x40:\r
+               case 0x41:\r
+               case 0x42:\r
+               case 0x43:\r
+                       //n->appearance = s2b_get_bitmap(read, (GF_Node *) n, shape, srec);\r
+                       //break;\r
+               default:\r
+                       swf_report(read, GF_NOT_SUPPORTED, "fill_style %x not supported", srec->type);\r
+                       break;\r
+               }\r
+       } else {\r
+        fprintf(read->svg_output, "fill=\"none\" ");\r
+        fprintf(read->svg_output, "stroke=\"");\r
+        swf_svg_print_color(read, srec->solid_col);\r
+        fprintf(read->svg_output, "\" ");\r
+        fprintf(read->svg_output, "stroke-opacity=\"");\r
+        swf_svg_print_alpha(read, srec->solid_col);\r
+        fprintf(read->svg_output, "\" ");\r
+        fprintf(read->svg_output, "stroke-width=\"%f\" ", FIX2FLT(srec->width));\r
+       }\r
+}\r
+\r
+static void swf_svg_print_shape_record_to_path_d(SWFReader *read, SWFShapeRec *srec) \r
+{\r
+    u32     pt_idx;\r
+    u32     i;\r
+\r
+    pt_idx = 0;\r
+    for (i=0; i<srec->path->nbType; i++) {\r
+        switch (srec->path->types[i]) {\r
+        /*moveTo*/\r
+        case 0:\r
+            fprintf(read->svg_output, "M%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));\r
+            pt_idx++;\r
+            break;\r
+        /*lineTo*/\r
+        case 1:\r
+            fprintf(read->svg_output, "L%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));\r
+            pt_idx++;\r
+            break;\r
+        /*curveTo*/\r
+        case 2:\r
+            fprintf(read->svg_output, "Q%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));\r
+            pt_idx++;\r
+            fprintf(read->svg_output, ",%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));\r
+            pt_idx++;\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+static void swf_svg_print_matrix(SWFReader *read, GF_Matrix2D *mat)\r
+{\r
+    if (!gf_mx2d_is_identity(*mat))\r
+    {\r
+        GF_Point2D  scale;\r
+        GF_Point2D  translate;\r
+        Fixed       rotate;\r
+        if( gf_mx2d_decompose(mat, &scale, &rotate, &translate)) \r
+        {\r
+            fprintf(read->svg_output, "transform=\"");\r
+            if (translate.x != 0 || translate.y != 0)\r
+            {\r
+                fprintf(read->svg_output, "translate(%f, %f) ", translate.x, translate.y);\r
+            }\r
+            if (rotate != 0)\r
+            {\r
+                fprintf(read->svg_output, "rotate(%f) ", rotate);\r
+            }\r
+            if (scale.x != FIX_ONE || scale.y != FIX_ONE)\r
+            {\r
+                fprintf(read->svg_output, "scale(%f, %f) ", scale.x, scale.y);\r
+            }\r
+            fprintf(read->svg_output, "\" ");\r
+        } \r
+        else \r
+        {\r
+            fprintf(read->svg_output, "transform=\"matrix(%f,%f,%f,%f,%f,%f)\" ", mat->m[0], mat->m[3], mat->m[1], mat->m[4], mat->m[2], mat->m[5]);\r
+        }\r
+    }\r
+}\r
+\r
+/*translates Flash to SVG shapes*/\r
+static GF_Err swf_svg_define_shape(SWFReader *read, SWFShape *shape, SWFFont *parent_font, Bool last_sub_shape)\r
+{\r
+    u32 i;\r
+    SWFShapeRec *srec;\r
+\r
+    if (parent_font && (read->flags & GF_SM_SWF_NO_FONT)) \r
+    {\r
+        return GF_OK;\r
+    }\r
+\r
+    if (!read->cur_shape) \r
+    {\r
+        fprintf(read->svg_output, "<defs>\n");\r
+        if (!parent_font)\r
+        {\r
+            fprintf(read->svg_output, "<g id=\"S%d\" >\n", shape->ID);\r
+        }\r
+        else\r
+        {\r
+            char    szGlyphId[256];\r
+            sprintf(szGlyphId, "Font%d_Glyph%d", parent_font->fontID, gf_list_count(parent_font->glyphs));\r
+            fprintf(read->svg_output, "<g id=\"%s\" >\n", szGlyphId);\r
+            gf_list_add(parent_font->glyphs, szGlyphId);\r
+        }\r
+    }\r
+    read->cur_shape = (GF_Node *)"shape";\r
+\r
+    i=0;\r
+    while ((srec = (SWFShapeRec*)gf_list_enum(shape->fill_left, &i))) {\r
+        fprintf(read->svg_output, "<path d=\"");\r
+        swf_svg_print_shape_record_to_path_d(read, srec);\r
+        fprintf(read->svg_output, "\" ");\r
+        swg_svg_print_shape_record_to_fill_stroke(read, srec, 1);\r
+        fprintf(read->svg_output, "/>\n");\r
+    }\r
+    i=0;\r
+    while ((srec = (SWFShapeRec*)gf_list_enum(shape->lines, &i))) {\r
+        fprintf(read->svg_output, "<path d=\"");\r
+        swf_svg_print_shape_record_to_path_d(read, srec);\r
+        fprintf(read->svg_output, "\" ");\r
+        swg_svg_print_shape_record_to_fill_stroke(read, srec, 0);\r
+        fprintf(read->svg_output, "/>\n");\r
+    }\r
+\r
+    if (last_sub_shape) \r
+    {\r
+        read->cur_shape = NULL;\r
+        fprintf(read->svg_output, "</g>\n");\r
+        fprintf(read->svg_output, "</defs>\n");\r
+    }\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_define_text(SWFReader *read, SWFText *text)\r
+{\r
+    Bool            use_text;\r
+    u32             i;\r
+    u32             j;\r
+    SWFGlyphRec     *gr;\r
+    SWFFont         *ft;\r
+\r
+    use_text = (read->flags & GF_SM_SWF_NO_FONT) ? 1 : 0;\r
+\r
+    fprintf(read->svg_output, "<defs>\n");\r
+    fprintf(read->svg_output, "<g id=\"S%d\" ", text->ID);\r
+    swf_svg_print_matrix(read, &text->mat);\r
+    fprintf(read->svg_output, ">\n");\r
+\r
+    i=0;\r
+    while ((gr = (SWFGlyphRec*)gf_list_enum(text->text, &i))) \r
+    {\r
+        ft = NULL;\r
+        if (use_text) {\r
+            ft = swf_find_font(read, gr->fontID);\r
+            if (!ft->glyph_codes) {\r
+                use_text = 0;\r
+                swf_report(read, GF_BAD_PARAM, "Font glyphs are not defined, cannot reference extern font - Forcing glyph embedding");\r
+            }\r
+        }\r
+        if (use_text) {\r
+            /*restore back the font height in pixels (it's currently in SWF glyph design units)*/\r
+            fprintf(read->svg_output, "<text ");\r
+            fprintf(read->svg_output, "x=\"%f \" ", FIX2FLT(gr->orig_x));\r
+            fprintf(read->svg_output, "y=\"%f \" ", FIX2FLT(gr->orig_y));\r
+            fprintf(read->svg_output, "font-size=\"%d\" ", (u32)(gr->fontSize * SWF_TWIP_SCALE));\r
+            if (ft->fontName)\r
+            {\r
+                fprintf(read->svg_output, "font-family=\"%s\" ", ft->fontName);\r
+            }\r
+            if (ft->is_italic) \r
+            {\r
+                fprintf(read->svg_output, "font-style=\"italic\" ");\r
+            }\r
+            if (ft->is_bold) \r
+            {\r
+                fprintf(read->svg_output, "font-weight=\"bold\" ");\r
+            }\r
+            fprintf(read->svg_output, ">");\r
+            /*convert to UTF-8*/\r
+            {\r
+                u16     *str_w;\r
+                u16     *widestr;\r
+                char    *str;\r
+\r
+                str_w = (u16*)gf_malloc(sizeof(u16) * (gr->nbGlyphs+1));\r
+                for (j=0; j<gr->nbGlyphs; j++) \r
+                {\r
+                    str_w[j] = ft->glyph_codes[gr->indexes[j]];\r
+                }\r
+                str_w[j] = 0;\r
+                str = (char*)gf_malloc(sizeof(char) * (gr->nbGlyphs+2));\r
+                widestr = str_w;\r
+                j = gf_utf8_wcstombs(str, sizeof(u8) * (gr->nbGlyphs+1), (const unsigned short **) &widestr);\r
+                if (j != (u32) -1) {\r
+                    str[j] = 0;\r
+                    fprintf(read->svg_output, "%s", str);\r
+                }\r
+            }\r
+            fprintf(read->svg_output, "</text>\n");\r
+        }\r
+        else\r
+        {\r
+            /*convert glyphs*/\r
+            Fixed       dx;\r
+            fprintf(read->svg_output, "<g tranform=\"scale(1,-1) ");\r
+            fprintf(read->svg_output, "translate(%f, %f)\" >\n", FIX2FLT(gr->orig_x), FIX2FLT(gr->orig_y));\r
+\r
+            dx = 0;\r
+            for (j=0; j<gr->nbGlyphs; j++) \r
+            {\r
+                fprintf(read->svg_output, "<use xlink:href=\"#Font%d_Glyph%d\" transform=\"translate(%f)\" />\n", gr->fontID, gr->indexes[j], FLT2FIX(gf_divfix(dx, FLT2FIX(gr->fontSize * SWF_TEXT_SCALE))));\r
+                dx += gr->dx[j];\r
+            }\r
+            fprintf(read->svg_output, "</g>\n");\r
+        }\r
+    }\r
+    fprintf(read->svg_output, "</g>\n");\r
+    fprintf(read->svg_output, "</defs>\n");\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_define_edit_text(SWFReader *read, SWFEditText *text)\r
+{\r
+    //char styles[1024];\r
+    //char *ptr;\r
+    //Bool use_layout;\r
+    //M_Layout *layout = NULL;\r
+    //M_Shape *txt;\r
+    //M_Text *t;\r
+    //M_FontStyle *f;\r
+    //M_Transform2D *tr;\r
+\r
+    //tr = (M_Transform2D *) s2s_new_node(read, TAG_MPEG4_Transform2D);\r
+    //tr->scale.y = -FIX_ONE;\r
+\r
+    //use_layout = 0;\r
+    //if (text->align==3) use_layout = 1;\r
+    //else if (text->multiline) use_layout = 1;\r
+\r
+    //if (use_layout) {\r
+    //  layout = (M_Layout *) s2s_new_node(read, TAG_MPEG4_Layout);\r
+    //  tr->translation.x = read->width/2;\r
+    //  tr->translation.y = read->height/2;\r
+    //}\r
+\r
+    //t = (M_Text *) s2s_new_node(read, TAG_MPEG4_Text);\r
+    //f = (M_FontStyle *) s2s_new_node(read, TAG_MPEG4_FontStyle);\r
+    //t->fontStyle = (GF_Node *) f;\r
+    //gf_node_register(t->fontStyle, (GF_Node *) t);\r
+\r
+    ///*restore back the font height in pixels (it's currently in SWF glyph design units)*/\r
+    //f->size = text->font_height;\r
+    //f->spacing = text->font_height + text->leading;\r
+\r
+    //gf_sg_vrml_mf_reset(&f->justify, GF_SG_VRML_MFSTRING);\r
+    //gf_sg_vrml_mf_append(&f->justify, GF_SG_VRML_MFSTRING, (void**)&ptr);\r
+    //switch (text->align) {\r
+    //case 0:\r
+    //  ((SFString*)ptr)->buffer = gf_strdup("BEGIN"); \r
+    //  break;\r
+    //case 1:\r
+    //  ((SFString*)ptr)->buffer = gf_strdup("END"); \r
+    //  break;\r
+    //case 3:\r
+    //  ((SFString*)ptr)->buffer = gf_strdup("JUSTIFY"); \r
+    //  break;\r
+    //default:\r
+    //  ((SFString*)ptr)->buffer = gf_strdup("MIDDLE"); \r
+    //  break;\r
+    //}\r
+\r
+    //strcpy(styles, "");\r
+    //if (!text->read_only) strcat(styles, "EDITABLE");\r
+    //if (text->password) strcat(styles, "PASSWORD");\r
+    //\r
+    //if (f->style.buffer) gf_free(f->style.buffer);\r
+    //f->style.buffer = gf_strdup(styles);\r
+\r
+    //if (text->init_value) {\r
+    //  gf_sg_vrml_mf_reset(&t->string, GF_SG_VRML_MFSTRING);\r
+    //  gf_sg_vrml_mf_append(&t->string, GF_SG_VRML_MFSTRING, (void**)&ptr);\r
+\r
+    //  if (text->html) {\r
+    //      GF_SAXParser *xml;\r
+    //      SWFFlatText flat;\r
+    //      flat.final = 0;\r
+    //      flat.len = 0;\r
+    //      xml = gf_xml_sax_new(swf_nstart, swf_nend, swf_ntext, &flat);\r
+    //      gf_xml_sax_init(xml, NULL);\r
+    //      gf_xml_sax_parse(xml, text->init_value);\r
+    //      gf_xml_sax_del(xml);\r
+\r
+    //      if (flat.final) {\r
+    //          ((SFString*)ptr)->buffer = gf_strdup(flat.final);\r
+    //          gf_free(flat.final);\r
+    //      }\r
+    //  } else {\r
+    //      ((SFString*)ptr)->buffer = gf_strdup(text->init_value);\r
+    //  }\r
+    //}\r
+\r
+\r
+    //txt = (M_Shape *) s2s_new_node(read, TAG_MPEG4_Shape);\r
+    //txt->appearance = s2s_get_appearance(read, (GF_Node *) txt, text->color, 0, 0);               \r
+    //txt->geometry = (GF_Node *) t;\r
+    //gf_node_register(txt->geometry, (GF_Node *) txt);\r
+\r
+    //if (layout) {     \r
+    //  gf_sg_vrml_mf_reset(&layout->justify, GF_SG_VRML_MFSTRING);\r
+    //  gf_sg_vrml_mf_append(&layout->justify, GF_SG_VRML_MFSTRING, NULL);\r
+    //  switch (text->align) {\r
+    //  case 0:\r
+    //      layout->justify.vals[0] = gf_strdup("BEGIN"); \r
+    //      break;\r
+    //  case 1:\r
+    //      layout->justify.vals[0] = gf_strdup("END"); \r
+    //      break;\r
+    //  case 3:\r
+    //      layout->justify.vals[0] = gf_strdup("JUSTIFY"); \r
+    //      break;\r
+    //  default:\r
+    //      layout->justify.vals[0] = gf_strdup("MIDDLE"); \r
+    //      break;\r
+    //  }\r
+    //  if (text->multiline || text->word_wrap) layout->wrap = 1;\r
+\r
+    //  gf_node_insert_child((GF_Node *) layout, (GF_Node *)txt, -1);\r
+    //  gf_node_register((GF_Node *) txt, (GF_Node *) layout);\r
+\r
+    //  gf_node_insert_child((GF_Node *) tr, (GF_Node *)layout, -1);\r
+    //  gf_node_register((GF_Node *) layout, (GF_Node *) tr);\r
+    //} else {\r
+    //  gf_node_insert_child((GF_Node *) tr, (GF_Node *)txt, -1);\r
+    //  gf_node_register((GF_Node *) txt, (GF_Node *) tr);\r
+    //} \r
+    //if (tr) {\r
+    //  char szDEF[1024];\r
+    //  u32 ID;\r
+    //  sprintf(szDEF, "Text%d", text->ID);\r
+    //  read->load->ctx->max_node_id++;\r
+    //  ID = read->load->ctx->max_node_id;\r
+    //  gf_node_set_id((GF_Node*)tr, ID, szDEF);\r
+    //  s2s_insert_symbol(read, (GF_Node*)tr);\r
+    //}\r
+    return GF_OK;\r
+}\r
+\r
+#if 0\r
+/*called upon end of sprite or clip*/\r
+static void swf_svg_end_of_clip(SWFReader *read)\r
+{\r
+    //char szDEF[1024];\r
+    //u32 i;\r
+    //GF_AUContext *au;\r
+    //GF_Command *com;\r
+    //GF_CommandField *f;\r
+    //GF_Node *empty;\r
+    //\r
+    //return;\r
+\r
+    //empty = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");\r
+\r
+    //au = gf_list_get(read->bifs_es->AUs, 0);\r
+    //for (i=0; i<read->max_depth; i++) {\r
+    //  /*and write command*/\r
+    //  com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_REPLACE);\r
+    //  sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);\r
+    //  com->node = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);\r
+\r
+    //  gf_node_register(com->node, NULL);\r
+    //  f = gf_sg_command_field_new(com);\r
+    //  f->field_ptr = &f->new_node;\r
+    //  f->fieldType = GF_SG_VRML_SFNODE;\r
+    //  f->pos = i;\r
+    //  f->fieldIndex = 2;  /*children index*/\r
+    //  f->new_node = empty;\r
+    //  gf_node_register(f->new_node, com->node);\r
+\r
+    //  gf_list_insert(au->commands, com, i);\r
+    //}\r
+}\r
+#endif\r
+\r
+static Bool swf_svg_allocate_depth(SWFReader *read, u32 depth)\r
+{\r
+    //char szDEF[100];\r
+    //GF_Node *disp, *empty;\r
+    //if (read->max_depth > depth) return 1;\r
+\r
+    //sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);\r
+    //disp = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);\r
+\r
+    //empty = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");\r
+    //while (read->max_depth<=depth) {\r
+    //  gf_node_insert_child(disp, empty, -1);\r
+    //  gf_node_register(empty, disp);\r
+    //  read->max_depth++;\r
+    //}\r
+    return 0;\r
+}\r
+\r
+static GF_Err swf_svg_define_sprite(SWFReader *read, u32 nb_frames)\r
+{\r
+    //GF_Err e;\r
+    //GF_ObjectDescriptor *od;\r
+    //GF_ESD *esd;\r
+    //u32 ID;\r
+    //GF_Node *n, *par;\r
+    //GF_FieldInfo info;\r
+    //char szDEF[100];\r
+    //GF_StreamContext *prev_sc;\r
+    //GF_AUContext *prev_au;\r
+\r
+    ///*init OD*/\r
+    //e = swf_init_od(read, 0);\r
+    //if (e) return e;\r
+\r
+    ///*create animationStream object*/\r
+    //od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);\r
+    //if (!od) return GF_OUT_OF_MEM;\r
+\r
+    //od->objectDescriptorID = swf_get_od_id(read);\r
+    //esd = (GF_ESD *) gf_odf_desc_esd_new(0);\r
+    //if (!esd) return GF_OUT_OF_MEM;\r
+    //esd->ESID = swf_get_es_id(read);\r
+    ///*sprite runs on its own timeline*/\r
+    //esd->OCRESID = esd->ESID;\r
+    ///*always depends on main scene*/\r
+    //esd->dependsOnESID = 1;\r
+    //esd->decoderConfig->streamType = GF_STREAM_SCENE;\r
+    //esd->decoderConfig->objectTypeIndication = 1;\r
+    //esd->slConfig->timestampResolution = read->bifs_es->timeScale;\r
+    //gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo);\r
+    //esd->decoderConfig->decoderSpecificInfo = NULL;\r
+    //gf_list_add(od->ESDescriptors, esd);\r
+\r
+    ///*by default insert OD at begining*/\r
+    //e = swf_insert_od(read, 0, od);\r
+    //if (e) {\r
+    //  gf_odf_desc_del((GF_Descriptor *) od);\r
+    //  return e;\r
+    //}\r
+\r
+    ///*create AS for sprite - all AS are created in initial scene replace*/\r
+    //n = s2s_new_node(read, TAG_MPEG4_AnimationStream);\r
+    //gf_node_insert_child(read->root, n, 0);\r
+    //gf_node_register(n, read->root);\r
+    ///*assign URL*/\r
+    //gf_node_get_field_by_name(n, "url", &info);\r
+    //gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);\r
+    //((MFURL*)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;\r
+    //((M_AnimationStream *)n)->startTime = 0;\r
+\r
+    //n = s2s_new_node(read, TAG_MPEG4_MediaControl);\r
+    //sprintf(szDEF, "CLIP%d_CTRL", read->current_sprite_id);\r
+    //read->load->ctx->max_node_id++;\r
+    //ID = read->load->ctx->max_node_id;\r
+    //gf_node_set_id(n, ID, szDEF);\r
+\r
+    //gf_node_insert_child(read->root, n, 0);\r
+    //gf_node_register(n, read->root);\r
+    ///*assign URL*/\r
+    //gf_node_get_field_by_name(n, "url", &info);\r
+    //gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);\r
+    //((MFURL*)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;\r
+    ///*inactive by default (until inserted)*/\r
+    //((M_MediaControl *)n)->mediaSpeed = 0;\r
+    //((M_MediaControl *)n)->loop = 1;\r
+\r
+    ///*create sprite grouping node*/\r
+    //n = s2s_new_node(read, TAG_MPEG4_Group);\r
+    //sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);\r
+\r
+    //read->load->ctx->max_node_id++;\r
+    //ID = read->load->ctx->max_node_id;\r
+    //gf_node_set_id(n, ID, szDEF);\r
+    //par = gf_sg_find_node_by_name(read->load->scene_graph, "DICTIONARY");\r
+    //assert(par);\r
+    //gf_node_list_add_child(&((M_Switch *)par)->choice, n);\r
+    //gf_node_register(n, par);\r
+    //par = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");\r
+    //gf_node_insert_child(n, par, -1);\r
+    //gf_node_register(par, n);\r
+\r
+    ///*store BIFS context*/\r
+    //prev_sc = read->bifs_es;\r
+    //prev_au = read->bifs_au;\r
+    ///*create new BIFS stream*/\r
+    //read->bifs_es = gf_sm_stream_new(read->load->ctx, esd->ESID, GF_STREAM_SCENE, 1);\r
+    //read->bifs_es->timeScale = prev_sc->timeScale;\r
+    //read->bifs_es->imp_exp_time = prev_sc->imp_exp_time + prev_au->timing;\r
+\r
+    ///*create first AU*/\r
+    //read->bifs_au = gf_sm_stream_au_new(read->bifs_es, 0, 0, 1);\r
+\r
+    //e = swf_parse_sprite(read);\r
+    //if (e) return e;\r
+\r
+    //swf_svg_end_of_clip(read);\r
+\r
+    ///*restore BIFS context*/\r
+    //read->bifs_es = prev_sc;\r
+    //read->bifs_au = prev_au;\r
+\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_setup_sound(SWFReader *read, SWFSound *snd, Bool soundstream_first_block)\r
+{\r
+//  GF_Err e;\r
+//  GF_ObjectDescriptor *od;\r
+//  GF_ESD *esd;\r
+//  GF_MuxInfo *mux;\r
+//  GF_Node *n, *par;\r
+//  GF_FieldInfo info;\r
+//  u32 ID;\r
+//  char szDEF[100];\r
+//\r
+//  /*soundstream header, only declare the associated MediaControl node for later actions*/\r
+//  if (!snd->ID && !soundstream_first_block) {\r
+//      n = s2s_new_node(read, TAG_MPEG4_MediaControl);\r
+//      sprintf(szDEF, "CLIP%d_SND", read->current_sprite_id);\r
+//      read->load->ctx->max_node_id++;\r
+//      ID = read->load->ctx->max_node_id;\r
+//      gf_node_set_id(n, ID, szDEF);\r
+//\r
+//      gf_node_insert_child(read->root, n, 0);\r
+//      gf_node_register(n, read->root);\r
+//      return GF_OK;\r
+//  }\r
+//\r
+//  e = swf_init_od(read, 0);\r
+//  if (e) return e;\r
+//\r
+//  /*create audio object*/\r
+//  od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);\r
+//  if (!od) return GF_OUT_OF_MEM;\r
+//  od->objectDescriptorID = swf_get_od_id(read);\r
+//  esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG);\r
+//  if (!esd) return GF_OUT_OF_MEM;\r
+//  esd->ESID = swf_get_es_id(read);\r
+//  if (snd->ID) {\r
+//      /*sound runs on its own timeline*/\r
+//      esd->OCRESID = esd->ESID;\r
+//  } else {\r
+//      /*soundstream runs on movie/sprite timeline*/\r
+//      esd->OCRESID = read->bifs_es->ESID;\r
+//      esd->OCRESID = esd->ESID;\r
+//  }\r
+//  gf_list_add(od->ESDescriptors, esd);\r
+//\r
+//  /*setup mux info*/\r
+//  mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG);\r
+//  mux->file_name = gf_strdup(snd->szFileName);\r
+////    mux->startTime = snd->frame_delay_ms;\r
+//  mux->startTime = 0;\r
+//  /*MP3 in, destroy file once done*/\r
+//  if (snd->format==2) mux->delete_file = 1;\r
+//  gf_list_add(esd->extensionDescriptors, mux);\r
+//\r
+//\r
+//  /*by default insert OD at begining*/\r
+//  e = swf_insert_od(read, 0, od);\r
+//  if (e) {\r
+//      gf_odf_desc_del((GF_Descriptor *) od);\r
+//      return e;\r
+//  }\r
+//  /*create sound & audio clip*/\r
+//  n = s2s_new_node(read, TAG_MPEG4_Sound2D);\r
+//  gf_node_insert_child(read->root, n, 0);\r
+//  gf_node_register(n, read->root);\r
+//  par = n;\r
+//  n = s2s_new_node(read, TAG_MPEG4_AudioClip);\r
+//  ((M_Sound2D *)par)->source = n;\r
+//  gf_node_register(n, par);\r
+//  /*assign URL*/\r
+//  gf_node_get_field_by_name(n, "url", &info);\r
+//  gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);\r
+//  ((MFURL *)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;\r
+//\r
+//  ((M_AudioClip*)n)->startTime = -1.0;\r
+//\r
+//  /*regular sound: set an ID to do play/stop*/\r
+//  if (snd->ID) {\r
+//      sprintf(szDEF, "Sound%d", snd->ID);\r
+//      read->load->ctx->max_node_id++;\r
+//      ID = read->load->ctx->max_node_id;\r
+//      gf_node_set_id(n, ID, szDEF);\r
+//  }\r
+//  /*soundStream - add a MediaControl*/\r
+//  else {\r
+//      /*if sprite always have the media active but controled by its mediaControl*/\r
+//      if (read->current_sprite_id) {\r
+//          ((M_AudioClip*)n)->startTime = 0;\r
+//      } \r
+//      /*otherwise start the media at the first soundstream block*/\r
+//      else {\r
+//          ((M_AudioClip*)n)->startTime = snd->frame_delay_ms/1000.0;\r
+//          ((M_AudioClip*)n)->startTime = 0;\r
+//      }\r
+//\r
+//      sprintf(szDEF, "CLIP%d_SND", read->current_sprite_id);\r
+//      n = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);\r
+//\r
+//      /*assign URL*/\r
+//      gf_node_get_field_by_name(n, "url", &info);\r
+//      gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);\r
+//      ((MFURL*)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;\r
+//      ((M_MediaControl *)n)->loop = 0;\r
+//\r
+//      /*inactive by default (until inserted)*/\r
+//      if (read->current_sprite_id) {\r
+//          ((M_MediaControl *)n)->mediaSpeed = 0;\r
+//      } else {\r
+//          ((M_MediaControl *)n)->mediaSpeed = FIX_ONE;\r
+//      }\r
+//  }\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_setup_image(SWFReader *read, u32 ID, char *fileName)\r
+{\r
+\r
+    //GF_Err e;\r
+    //GF_ObjectDescriptor *od;\r
+    //GF_ESD *esd;\r
+    //GF_MuxInfo *mux;\r
+    //GF_Node *n, *par;\r
+    //GF_FieldInfo info;\r
+    //char szDEF[100];\r
+    //\r
+    //e = swf_init_od(read, 0);\r
+    //if (e) return e;\r
+\r
+    ///*create visual object*/\r
+    //od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);\r
+    //if (!od) return GF_OUT_OF_MEM;\r
+    //od->objectDescriptorID = swf_get_od_id(read);\r
+    //esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG);\r
+    //if (!esd) return GF_OUT_OF_MEM;\r
+    //esd->ESID = swf_get_es_id(read);\r
+    //esd->OCRESID = esd->ESID;\r
+    //gf_list_add(od->ESDescriptors, esd);\r
+\r
+    ///*setup mux info*/\r
+    //mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG);\r
+\r
+    //mux->file_name = gf_strdup(fileName);\r
+    ///*destroy file once done*/\r
+    ////mux->delete_file = 1;\r
+    //gf_list_add(esd->extensionDescriptors, mux);\r
+\r
+\r
+    ///*by default insert OD at begining*/\r
+    //e = swf_insert_od(read, 0, od);\r
+    //if (e) {\r
+    //  gf_odf_desc_del((GF_Descriptor *) od);\r
+    //  return e;\r
+    //}\r
+    ///*create appearance clip*/\r
+    //par = s2s_new_node(read, TAG_MPEG4_Shape);\r
+    //s2s_insert_symbol(read, par);\r
+    //n = s2s_new_node(read, TAG_MPEG4_Appearance);\r
+    //((M_Shape *)par)->appearance = n;\r
+    //gf_node_register(n, par);\r
+\r
+    //par = n;\r
+    //n = s2s_new_node(read, TAG_MPEG4_ImageTexture);\r
+    //((M_Appearance *)par)->texture = n;\r
+    //gf_node_register(n, par);\r
+\r
+    //sprintf(szDEF, "Bitmap%d", ID);\r
+    //read->load->ctx->max_node_id++;\r
+    //ID = read->load->ctx->max_node_id;\r
+    //gf_node_set_id(n, ID, szDEF);\r
+\r
+    ///*assign URL*/\r
+    //gf_node_get_field_by_name(n, "url", &info);\r
+    //gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);\r
+    //((MFURL *)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;\r
+\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_set_backcol(SWFReader *read, u32 xrgb)\r
+{\r
+    //SFColor rgb;\r
+    //GF_Node *bck = gf_sg_find_node_by_name(read->load->scene_graph, "BACKGROUND");\r
+\r
+    //rgb.red = INT2FIX((xrgb>>16) & 0xFF) / 255;\r
+    //rgb.green = INT2FIX((xrgb>>8) & 0xFF) / 255;\r
+    //rgb.blue = INT2FIX((xrgb) & 0xFF) / 255;\r
+    //s2s_set_field(read, read->bifs_au->commands, bck, "backColor", -1, GF_SG_VRML_SFCOLOR, &rgb, 0);\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_start_sound(SWFReader *read, SWFSound *snd, Bool stop)\r
+{\r
+    //GF_Node *sound2D;\r
+    //SFTime t = 0;\r
+    //char szDEF[100];\r
+\r
+    //sprintf(szDEF, "Sound%d", snd->ID);\r
+    //sound2D = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);\r
+    ///*check flags*/\r
+    //if (sound2D)\r
+    //  s2s_set_field(read, read->bifs_au->commands, sound2D, stop ? "stopTime" : "startTime", -1, GF_SG_VRML_SFTIME, &t, 0);\r
+\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_place_obj(SWFReader *read, u32 depth, u32 ID, u32 prev_id, u32 type, GF_Matrix2D *mat, GF_ColorMatrix *cmat, GF_Matrix2D *prev_mat, GF_ColorMatrix *prev_cmat)\r
+{\r
+    //fprintf(read->svg_output, "<use xlink:href=\"#S%d\" z-index=\"%d\" ", ID, depth);\r
+    //if (mat) {\r
+    //    swf_svg_print_matrix(read, mat);\r
+    //}\r
+    //fprintf(read->svg_output, "/>\n");\r
+\r
+    //GF_Command *com;\r
+    //GF_CommandField *f;\r
+    //GF_Node *obj, *par;\r
+    //char szDEF[100];\r
+    //Bool is_sprite;\r
+\r
+    //obj = s2s_get_node(read, ID);\r
+    //is_sprite = 0;\r
+    //if (!obj) {\r
+    //  sprintf(szDEF, "CLIP%d_DL", ID);\r
+    //  obj = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);\r
+    //  if (obj) is_sprite = 1;\r
+    //}\r
+    //if (!obj) return GF_BAD_PARAM;\r
+\r
+    ///*then add cmat/mat and node*/\r
+    //par = s2s_wrap_node(read, obj, mat, cmat);\r
+\r
+    ///*and write command*/\r
+    //com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_REPLACE);\r
+    //sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);\r
+    //com->node = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);\r
+    //gf_node_register(com->node, NULL);\r
+    //f = gf_sg_command_field_new(com);\r
+    //f->field_ptr = &f->new_node;\r
+    //f->fieldType = GF_SG_VRML_SFNODE;\r
+    //f->pos = depth;\r
+    //f->fieldIndex = 2;    /*children index*/\r
+    //f->new_node = par;\r
+    //gf_node_register(f->new_node, com->node);\r
+    //gf_list_add(read->bifs_au->commands, com);\r
+\r
+    //if (ID==prev_id) return GF_OK;\r
+\r
+    //strcpy(szDEF, gf_node_get_name(obj));\r
+    ///*when inserting a button, trigger a pause*/\r
+    //if (!strnicmp(szDEF, "Button", 6)) {\r
+    //  u32 i, count;\r
+    //  s2s_control_sprite(read, read->bifs_au->commands, read->current_sprite_id, 1, 0, 0, 1);\r
+\r
+    //  count = gf_list_count(read->buttons);\r
+    //  for (i=0; i<count; i++) {\r
+    //      s2sBtnRec *btnrec = gf_list_get(read->buttons, i);\r
+    //      if (btnrec->btn_id==ID) {\r
+    //          s2s_control_sprite(read, read->bifs_au->commands, btnrec->sprite_up_id, 0, 0, 0, 1);\r
+    //      }\r
+    //  }\r
+    //}\r
+    ///*starts anim*/\r
+    //else if (is_sprite) {\r
+    //  s2s_control_sprite(read, read->bifs_au->commands, ID, 0, 1, 0, 0);\r
+    //  if (prev_id) {\r
+    //      s2s_control_sprite(read, read->bifs_au->commands, prev_id, 1, 0, 0, 0);\r
+    //  }\r
+    //}\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_remove_obj(SWFReader *read, u32 depth, u32 ID)\r
+{\r
+    return GF_OK;\r
+}\r
+\r
+static GF_Err swf_svg_show_frame(SWFReader *read)\r
+{\r
+    u32     i;\r
+    u32     len;\r
+    GF_List *sdl = gf_list_new(); // sorted display list\r
+\r
+    /* sorting the display list */\r
+    while (gf_list_count(read->display_list))\r
+    {\r
+        Bool        inserted = 0;\r
+        DispShape   *s;\r
+\r
+        s = (DispShape *)gf_list_get(read->display_list, 0);\r
+        gf_list_rem(read->display_list, 0);\r
+        \r
+        for (i = 0; i < gf_list_count(sdl); i++)\r
+        {\r
+            DispShape *s2 = (DispShape *)gf_list_get(sdl, i);\r
+            if (s->depth < s2->depth) \r
+            {\r
+                gf_list_insert(sdl, s, i);\r
+                inserted = 1;\r
+                break;\r
+            }\r
+        }\r
+        if (!inserted)\r
+        {\r
+            gf_list_add(sdl, s);\r
+        }\r
+    }\r
+    gf_list_del(read->display_list);\r
+    read->display_list = sdl;\r
+\r
+    /* dumping the display list */\r
+    len = gf_list_count(read->display_list);\r
+    for (i=0; i<len; i++)\r
+    {\r
+        DispShape   *s;\r
+        s = (DispShape *)gf_list_get(read->display_list, i);\r
+        fprintf(read->svg_output, "<use xlink:href=\"#S%d\" z-index=\"%d\" ", s->char_id, s->depth);\r
+        swf_svg_print_matrix(read, &s->mat);\r
+        fprintf(read->svg_output, "/>\n");\r
+    }\r
+    fprintf(read->svg_output, "</g>\n");\r
+\r
+    fprintf(read->svg_output, "<g id=\"frame%d\" display=\"none\">\n",read->current_frame+1);\r
+    fprintf(read->svg_output, "<animate attributeName=\"display\" to=\"inline\" begin=\"%f\" end=\"%f\" fill=\"%s\" restart=\"never\"/>\n", \r
+        1.0*(read->current_frame+1)/read->frame_rate, 1.0*(read->current_frame+2)/read->frame_rate,\r
+        (((read->current_frame+1) <= (read->frame_count-1)) ? "remove" : "freeze"));\r
+    return GF_OK;\r
+}\r
+\r
+static void swf_svg_finalize(SWFReader *read)\r
+{\r
+    //u32 i, count;\r
+\r
+    //swf_svg_end_of_clip(read);    \r
+\r
+    //while (gf_list_count(read->buttons)) {\r
+    //  s2sBtnRec *btnrec = gf_list_get(read->buttons, 0);\r
+    //  gf_list_rem(read->buttons, 0);\r
+    //  gf_free(btnrec);\r
+    //}\r
+\r
+    //count = gf_list_count(read->fonts);\r
+    //for (i=0;i<count; i++) {\r
+    //  SWFFont *ft = (SWFFont *)gf_list_get(read->fonts, i);\r
+    //  while (gf_list_count(ft->glyphs)) {\r
+    //      GF_Node *gl = (GF_Node *)gf_list_get(ft->glyphs, 0);\r
+    //      gf_list_rem(ft->glyphs, 0);\r
+    //      gf_node_unregister(gl, NULL);\r
+    //  }\r
+    //}\r
+    fprintf(read->svg_output, "</g>\n");\r
+    fprintf(read->svg_output, "</svg>\n");\r
+    fclose(read->svg_output);\r
+}\r
+\r
+static GF_Err swf_svg_define_button(SWFReader *read, SWF_Button *btn)\r
+{\r
+    //char szName[1024];\r
+    //M_Switch *button;\r
+    //SWF_ButtonRecord *br;\r
+    //GF_Node *btn_root, *n, *btn_ts;\r
+    //u32 i, ID, pos;\r
+\r
+    //if (!btn) {\r
+    //  read->btn = NULL;\r
+    //  read->btn_over = read->btn_not_over = read->btn_active = read->btn_not_active = NULL;\r
+    //  return GF_OK;\r
+    //}\r
+\r
+    //read->btn = btn;\r
+\r
+    //btn_root = s2s_new_node(read, TAG_MPEG4_Transform2D);\r
+    //sprintf(szName, "Button%d", btn->ID);\r
+    //read->load->ctx->max_node_id++;\r
+    //ID = read->load->ctx->max_node_id;\r
+    //gf_node_set_id((GF_Node *)btn_root, ID, szName);\r
+\r
+    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_ColorTransform, NULL, -1);\r
+    //((M_ColorTransform*)n)->maa = ((M_ColorTransform*)n)->mab = ((M_ColorTransform*)n)->mar = ((M_ColorTransform*)n)->mag = ((M_ColorTransform*)n)->ta = 0; \r
+\r
+    ///*locate hit buttons and add them to the color transform*/\r
+    //for (i=0; i<btn->count; i++) {\r
+    //  GF_Node *character;\r
+    //  br = &btn->buttons[i];\r
+    //  if (!br->hitTest) continue;\r
+    //  character = s2s_get_node(read, br->character_id);\r
+    //  if (!character) {\r
+    //      sprintf(szName, "CLIP%d_DL", br->character_id);\r
+    //      character = gf_sg_find_node_by_name(read->load->scene_graph, szName);\r
+    //  }\r
+    //  if (character) {\r
+    //      gf_node_list_add_child(&((GF_ParentNode*)n)->children, character);\r
+    //      gf_node_register(character, (GF_Node *)n);\r
+    //  }\r
+    //}\r
+    ///*add touch sensor to the color transform*/\r
+    //sprintf(szName, "BTN%d_TS", read->btn->ID);\r
+    //btn_ts = s2s_button_add_child(read, n, TAG_MPEG4_TouchSensor, szName, -1);\r
+\r
+    //s2s_insert_symbol(read, (GF_Node *)btn_root);\r
+\r
+    ///*isActive handler*/\r
+    //sprintf(szName, "BTN%d_CA", read->btn->ID);\r
+    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);\r
+    //read->btn_active = ((M_Conditional*)n)->buffer.commandList;\r
+    //s2s_button_add_route(read, btn_ts, 4, n, 0);\r
+\r
+    ///*!isActive handler*/\r
+    //sprintf(szName, "BTN%d_CNA", read->btn->ID);\r
+    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);\r
+    //read->btn_not_active = ((M_Conditional*)n)->buffer.commandList;\r
+    //s2s_button_add_route(read, btn_ts, 4, n, 1);\r
+\r
+    ///*isOver handler*/\r
+    //sprintf(szName, "BTN%d_CO", read->btn->ID);\r
+    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);\r
+    //read->btn_over = ((M_Conditional*)n)->buffer.commandList;\r
+    //s2s_button_add_route(read, btn_ts, 5, n, 0);\r
+\r
+    ///*!isOver handler*/\r
+    //sprintf(szName, "BTN%d_CNO", read->btn->ID);\r
+    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);\r
+    //read->btn_not_over = ((M_Conditional*)n)->buffer.commandList;\r
+    //s2s_button_add_route(read, btn_ts, 5, n, 1);\r
+\r
+    ///*by default show first character*/\r
+    //pos = 0;\r
+    //for (i=0; i<btn->count; i++) {\r
+    //  GF_Node *sprite_ctrl = NULL;\r
+    //  GF_Node *character;\r
+    //  br = &btn->buttons[i];\r
+    //  if (!br->up && !br->down && !br->over) continue;\r
+\r
+    //  character = s2s_get_node(read, br->character_id);\r
+\r
+    //  if (!character) {\r
+    //      sprintf(szName, "CLIP%d_DL", br->character_id);\r
+    //      character = gf_sg_find_node_by_name(read->load->scene_graph, szName);\r
+    //      if (character) {\r
+    //          sprintf(szName, "CLIP%d_CTRL", br->character_id);\r
+    //          sprite_ctrl = gf_sg_find_node_by_name(read->load->scene_graph, szName);\r
+    //      }\r
+    //  }\r
+    //  if (character) {\r
+    //      SFInt32 choice = 0;\r
+    //      GF_Node *n = s2s_wrap_node(read, character, &br->mx, &br->cmx);\r
+\r
+    //      sprintf(szName, "BTN%d_R%d", btn->ID, i+1);\r
+    //      button = (M_Switch *) s2s_button_add_child(read, btn_root, TAG_MPEG4_Switch, szName, pos);\r
+    //      pos++;\r
+\r
+    //      gf_node_list_add_child(&button->choice, n);\r
+    //      gf_node_register(n, (GF_Node *)button);\r
+    //      /*initial state*/\r
+    //      if (br->up) {\r
+    //          button->whichChoice = 0;\r
+    //          /*register this button for sprite start upon place_obj*/\r
+    //          if (sprite_ctrl) {\r
+    //              s2sBtnRec *btnrec;\r
+    //              if (!read->buttons) read->buttons = gf_list_new();\r
+    //              btnrec = gf_malloc(sizeof(s2sBtnRec));\r
+    //              btnrec->btn_id = btn->ID;\r
+    //              btnrec->sprite_up_id = br->character_id;\r
+    //              gf_list_add(read->buttons, btnrec);\r
+    //          }\r
+\r
+    //      } else {\r
+    //          button->whichChoice = -1;\r
+    //      }\r
+\r
+    //      choice = br->up ? 0 : -1;\r
+    //      s2s_set_field(read, read->btn_not_over, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);\r
+    //      /*start or stop sprite if button is up or not*/\r
+    //      if (sprite_ctrl) {\r
+    //          s2s_control_sprite(read, read->btn_not_over, br->character_id, choice, 1, 0, 0);\r
+    //      }\r
+\r
+    //      choice = br->down ? 0 : -1;\r
+    //      s2s_set_field(read, read->btn_active, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);\r
+    //      if (sprite_ctrl && !br->over) {\r
+    //          s2s_control_sprite(read, read->btn_active, br->character_id, choice, 1, 0, 0);\r
+    //      }\r
+\r
+    //      choice = br->over ? 0 : -1;\r
+    //      s2s_set_field(read, read->btn_not_active, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);\r
+    //      s2s_set_field(read, read->btn_over, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);\r
+    //      if (sprite_ctrl) {\r
+    //          s2s_control_sprite(read, read->btn_over, br->character_id, choice, 1, 0, 0);\r
+    //          if (!br->down)\r
+    //              s2s_control_sprite(read, read->btn_not_active, br->character_id, choice, 1, 0, 0);\r
+    //      }\r
+    //  }\r
+    //}\r
+\r
+    return GF_OK;\r
+}\r
+\r
+Bool swf_svg_action(SWFReader *read, SWFAction *act)\r
+{\r
+//  GF_List *dst;\r
+//  MFURL url;\r
+//  SFURL sfurl;\r
+//  Bool bval;\r
+//  GF_Node *n;\r
+//  Double time;\r
+//\r
+//  dst = read->bifs_au->commands;\r
+//  if (read->btn) {\r
+//      if (act->button_mask & GF_SWF_COND_OVERUP_TO_OVERDOWN) dst = read->btn_active;\r
+//      else if (act->button_mask & GF_SWF_COND_IDLE_TO_OVERUP) dst = read->btn_over;\r
+//      else if (act->button_mask & GF_SWF_COND_OVERUP_TO_IDLE) dst = read->btn_not_over;\r
+//      else dst = read->btn_not_active;\r
+//  }\r
+//\r
+//  switch (act->type) {\r
+//  case GF_SWF_AS3_WAIT_FOR_FRAME:\r
+//      /*while correct, this is not optimal, we set the wait-frame upon GOTO frame*/\r
+////        read->wait_frame = act->frame_number;\r
+//      break;\r
+//  case GF_SWF_AS3_GOTO_FRAME:\r
+//      if (act->frame_number>read->current_frame)\r
+//          read->wait_frame = act->frame_number;\r
+//\r
+//      time = act->frame_number ? act->frame_number +1: 0;\r
+//      time /= read->frame_rate;\r
+//      s2s_control_sprite(read, dst, read->current_sprite_id, 0, 1, time, 0);\r
+//      break;\r
+//  case GF_SWF_AS3_GET_URL:\r
+//      n = gf_sg_find_node_by_name(read->load->scene_graph, "MOVIE_URL");\r
+//      sfurl.OD_ID = 0; sfurl.url = act->url;\r
+//      url.count = 1; url.vals = &sfurl;\r
+//      s2s_set_field(read, dst, n, "url", -1, GF_SG_VRML_MFURL, &url, 0);\r
+//      s2s_set_field(read, dst, n, "parameter", -1, GF_SG_VRML_MFSTRING, &url, 0);\r
+//      bval = 1;\r
+//      s2s_set_field(read, dst, n, "activate", -1, GF_SG_VRML_SFBOOL, &bval, 0);\r
+//      break;\r
+//  case GF_SWF_AS3_PLAY:\r
+//      s2s_control_sprite(read, dst, read->current_sprite_id, 0, 1, -1, 0);\r
+//      break;\r
+//  case GF_SWF_AS3_STOP:\r
+//      s2s_control_sprite(read, dst, read->current_sprite_id, 1, 0, 0, 0);\r
+//      break;\r
+//  default:\r
+//      return 0;\r
+//  }\r
+//\r
+    return 1;\r
+}\r
+\r
+GF_Err swf_to_svg_init(SWFReader *read)\r
+{\r
+    char szFileName[GF_MAX_PATH];\r
+    sprintf(szFileName, "%s.svg", read->load->fileName);\r
+    /*init callbacks*/\r
+    read->svg_output = gf_f64_open(szFileName, "wt");\r
+    fprintf(read->svg_output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");\r
+    fprintf(read->svg_output, "<svg xmlns=\"http://www.w3.org/2000/svg\" ");\r
+    fprintf(read->svg_output, "xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");\r
+    fprintf(read->svg_output, "width=\"100%%\" ");\r
+    fprintf(read->svg_output, "height=\"100%%\" ");\r
+    fprintf(read->svg_output, "viewBox=\"0 0 %d %d\" ", FIX2INT(read->width), FIX2INT(read->height));\r
+    fprintf(read->svg_output, "viewport-fill=\"rgb(255,255,255)\" ");\r
+    fprintf(read->svg_output, ">\n");\r
+    fprintf(read->svg_output, "<g id=\"frame%d\" display=\"none\">\n",read->current_frame);\r
+    fprintf(read->svg_output, "<animate attributeName=\"display\" to=\"inline\" begin=\"%f\" end=\"%f\" fill=\"remove\" restart=\"never\"/>\n",\r
+        1.0*(read->current_frame)/read->frame_rate, 1.0*(read->current_frame+1)/read->frame_rate);\r
+    read->show_frame = swf_svg_show_frame;\r
+    read->allocate_depth = swf_svg_allocate_depth;\r
+    read->place_obj = swf_svg_place_obj;\r
+    read->remove_obj = swf_svg_remove_obj;\r
+    read->define_shape = swf_svg_define_shape;\r
+    read->define_sprite = swf_svg_define_sprite;\r
+    read->set_backcol = swf_svg_set_backcol;\r
+    read->define_button = swf_svg_define_button;\r
+    read->define_text = swf_svg_define_text;\r
+    read->define_edit_text = swf_svg_define_edit_text;\r
+    read->setup_sound = swf_svg_setup_sound;\r
+    read->start_sound = swf_svg_start_sound;\r
+    read->setup_image = swf_svg_setup_image;\r
+    read->action = swf_svg_action;\r
+    read->finalize = swf_svg_finalize;\r
+    return GF_OK;\r
+}\r
+\r
+#endif /*GPAC_DISABLE_SWF_IMPORT*/\r
+\r
+#else\r
+GF_Err swf_to_svg_init(SWFReader *read)\r
+{\r
+    return GF_NOT_SUPPORTED;\r
+}\r
+\r
+#endif /*GPAC_DISABLE_VRML*/\r
index 1e70c4e4edc2648a7597e0166436cea1d1485ddf..6bc75c9e088cf7e0195498769235c7a4677bdb8d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index 05187c4feaaa4e748a4d30d8db48abd0ea72af0f..e93409ff12b154d1f4ad0113c4f80995145ab098 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -291,7 +292,10 @@ void gf_sg_reset(GF_SceneGraph *sg)
 {
        GF_SceneGraph *par;
        GF_List *gc;
-       u32 type, count;
+#ifndef GPAC_DISABLE_SVG
+       u32 type;
+#endif
+       u32 count;
        NodeIDedItem *reg_node;
        if (!sg) return;
 
@@ -390,8 +394,9 @@ restart:
                This will take care of nodes referencing themselves*/
                {
                GF_ParentList *nlist = node->sgprivate->parents;
+#ifndef GPAC_DISABLE_SVG
                type = (node->sgprivate->tag>GF_NODE_RANGE_LAST_VRML) ? 1 : 0;
-
+#endif
                while (nlist) {
                        GF_ParentList *next = nlist->next;
 #if 0
@@ -865,7 +870,9 @@ static void ReplaceIRINode(GF_Node *FromNode, GF_Node *old_node, GF_Node *newNod
 /*get all parents of the node and replace, the instance of the node and finally destroy the node*/
 GF_Err gf_node_replace(GF_Node *node, GF_Node *new_node, Bool updateOrderedGroup)
 {
+#ifndef GPAC_DISABLE_SVG
        u32 type;
+#endif
 #ifndef GPAC_DISABLE_VRML
        Bool replace_proto;
 #endif
@@ -878,8 +885,8 @@ GF_Err gf_node_replace(GF_Node *node, GF_Node *new_node, Bool updateOrderedGroup
        if (node == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene;
 #endif
 
-       type = (node->sgprivate->tag>GF_NODE_RANGE_LAST_VRML) ? 1 : 0;
 #ifndef GPAC_DISABLE_SVG
+       type = (node->sgprivate->tag>GF_NODE_RANGE_LAST_VRML) ? 1 : 0;
        if (type) {
                Replace_IRI(pSG, node, new_node);
        }
index 6d06516ea51de1c62f959e573ad39b074a5047a1..200526873aedcee711ea0930ebf383972d781fdf 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -144,6 +145,7 @@ static void SG_CheckFieldChange(GF_Node *node, GF_FieldInfo *field)
        gf_node_changed(node, field);
 }
 
+#ifndef GPAC_DISABLE_SVG
 static void gf_node_unregister_children_deactivate(GF_Node *container, GF_ChildNodeItem *child)
 {
        GF_ChildNodeItem *cur;
@@ -155,6 +157,7 @@ static void gf_node_unregister_children_deactivate(GF_Node *container, GF_ChildN
                gf_free(cur);
        }
 }
+#endif
 
 
 GF_EXPORT
index 4739de24d6cf70d82b5b4b16175d40972fe8f575..0aa1c35dc28d3d0e3cbde84ec8bee5c18511786f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004
+ *                     Authors: Jean Le Feuvre, Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / DOM 3 Events sub-project
index 878cd6317c97effa31b29d373cf8c1a74a8d47cf..7b1cc04d4d38c26b63c816dceff79c4f7b3973fe 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2007-200X ENST
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -106,23 +106,17 @@ char *js_get_utf8(JSContext *c, jsval val)
 typedef struct
 {
        u32 nb_inst;
-       JSClass domDocumentClass;
-       JSClass domNodeClass;
-       JSClass domElementClass;
-       JSClass domTextClass;
-       JSClass domNodeListClass;
-       JSClass domEventClass;
+       GF_JSClass domDocumentClass;
+       GF_JSClass domNodeClass;
+       GF_JSClass domElementClass;
+       GF_JSClass domTextClass;
+       GF_JSClass domNodeListClass;
+       GF_JSClass domEventClass;
 
-       JSClass xmlHTTPRequestClass;
-       JSClass DCCIClass;
+       GF_JSClass xmlHTTPRequestClass;
+       GF_JSClass DCCIClass;
 
-       JSClass storageClass;
-
-    JSObject *dom_node_proto;
-       JSObject *dom_document_proto;
-       JSObject *dom_element_proto;
-       JSObject *dom_event_proto;
-       JSObject *storage_proto;
+       GF_JSClass storageClass;
 
        void *(*get_element_class)(GF_Node *n);
        void *(*get_document_class)(GF_SceneGraph *n);
@@ -222,7 +216,7 @@ GF_SceneGraph *dom_get_doc(JSContext *c, JSObject *obj)
 
 static jsval dom_document_construct(JSContext *c, GF_SceneGraph *sg)
 {
-       JSClass *jsclass;
+       GF_JSClass *jsclass;
        JSObject *new_obj;
        if (sg->document) return OBJECT_TO_JSVAL(sg->document);
 
@@ -232,17 +226,17 @@ static jsval dom_document_construct(JSContext *c, GF_SceneGraph *sg)
 
        jsclass = NULL;
        if (dom_rt->get_document_class)
-               jsclass = (JSClass *) dom_rt->get_document_class(sg);
+               jsclass = (GF_JSClass *) dom_rt->get_document_class(sg);
 
        if (!jsclass) jsclass = &dom_rt->domDocumentClass;
 
-       new_obj = JS_NewObject(c, jsclass, 0, 0);
+       new_obj = JS_NewObject(c, & jsclass->_class, 0, 0);
        SMJS_SET_PRIVATE(c, new_obj, sg);
        sg->document = new_obj;
        return OBJECT_TO_JSVAL(new_obj);
 }
 
-static jsval dom_base_node_construct(JSContext *c, JSClass *_class, GF_Node *n)
+static jsval dom_base_node_construct(JSContext *c, GF_JSClass *_class, GF_Node *n)
 {
        Bool set_rooted;
        GF_SceneGraph *sg;
@@ -271,7 +265,7 @@ static jsval dom_base_node_construct(JSContext *c, JSClass *_class, GF_Node *n)
                n->sgprivate->scenegraph->reference_count ++;
 
        gf_node_register(n, NULL);
-       new_obj = JS_NewObject(c, _class, 0, 0);
+       new_obj = JS_NewObject(c, & _class->_class, 0, 0);
        SMJS_SET_PRIVATE(c, new_obj, n);
 
        if (!n->sgprivate->interact) GF_SAFEALLOC(n->sgprivate->interact, struct _node_interactive_ext);
@@ -294,13 +288,13 @@ static jsval dom_base_node_construct(JSContext *c, JSClass *_class, GF_Node *n)
 }
 static jsval dom_node_construct(JSContext *c, GF_Node *n)
 {
-       JSClass *__class = NULL;
+       GF_JSClass *__class = NULL;
 
        if (!n) return JSVAL_NULL;
        if (n->sgprivate->scenegraph->dcci_doc)
                __class = &dom_rt->DCCIClass;
        else if (dom_rt->get_element_class)
-               __class = (JSClass *) dom_rt->get_element_class(n);
+               __class = (GF_JSClass *) dom_rt->get_element_class(n);
 
        if (!__class ) __class  = &dom_rt->domElementClass;
 
@@ -310,13 +304,13 @@ static jsval dom_node_construct(JSContext *c, GF_Node *n)
 }
 jsval dom_element_construct(JSContext *c, GF_Node *n)
 {
-       JSClass *__class = NULL;
+       GF_JSClass *__class = NULL;
 
        if (!n) return JSVAL_NULL;
        if (n->sgprivate->scenegraph->dcci_doc)
                __class = &dom_rt->DCCIClass;
        else if (dom_rt->get_element_class)
-               __class = (JSClass *) dom_rt->get_element_class(n);
+               __class = (GF_JSClass *) dom_rt->get_element_class(n);
 
        if (!__class) __class = &dom_rt->domElementClass;
 
@@ -408,15 +402,15 @@ static jsval dom_nodelist_construct(JSContext *c, GF_ParentNode *n)
                n->sgprivate->scenegraph->reference_count++;
 
        gf_node_register((GF_Node*)n, NULL);
-       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass, 0, 0);
+       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, new_obj, nl);
        return OBJECT_TO_JSVAL(new_obj);
 }
 
-static void dom_nodelist_finalize(JSContext *c, JSObject *obj)
-{
+static DECL_FINALIZE(dom_nodelist_finalize)
+
        DOMNodeList *nl;
-       if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) )
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) )
                return;
 
        nl = (DOMNodeList *) SMJS_GET_PRIVATE(c, obj);
@@ -444,7 +438,7 @@ static JSBool SMJS_FUNCTION(dom_nodelist_item)
        DOMNodeList *nl;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) )
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) )
                return JS_TRUE;
        if ((argc!=1) || !JSVAL_IS_INT(argv[0]))
                return JS_TRUE;
@@ -461,10 +455,10 @@ static JSBool SMJS_FUNCTION(dom_nodelist_item)
        return JS_TRUE;
 }
 
-static JSBool dom_nodelist_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( dom_nodelist_getProperty)
+
        DOMNodeList *nl;
-       if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL)
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL)
        )
                return JS_TRUE;
 
@@ -478,8 +472,10 @@ static JSBool dom_nodelist_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GE
        }
        return JS_TRUE;
 }
-static JSBool dom_nodelist_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( dom_nodelist_setProperty)
+
+       /*avoids gcc warning*/
+       if (!obj) obj=NULL;
        if (!SMJS_ID_IS_INT(id)) return JS_TRUE;
        /*no write prop*/
        return JS_TRUE;
@@ -761,8 +757,8 @@ JSBool SMJS_FUNCTION(dom_event_remove_listener)
 }
 
 /*dom3 node*/
-static void dom_node_finalize(JSContext *c, JSObject *obj)
-{
+static DECL_FINALIZE( dom_node_finalize)
+
        GF_Node *n = (GF_Node *) SMJS_GET_PRIVATE(c, obj);
        /*the JS proto of the svgClass or a destroyed object*/
        if (!n) return;
@@ -1103,8 +1099,8 @@ static u32 get_namespace_code_by_prefix(GF_Node *node, char *prefix)
 }
 #endif /*GPAC_UNUSED_FUNC*/
 
-static JSBool dom_node_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( dom_node_getProperty)
+
        u32 tag;
        GF_Node *n;
        GF_SceneGraph *sg = NULL;
@@ -1302,8 +1298,8 @@ void dom_node_set_textContent(GF_Node *n, char *text)
        gf_node_changed(n, &info);
 }
 
-static JSBool dom_node_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( dom_node_setProperty)
+
        u32 tag;
        GF_Node *n;
 
@@ -1349,8 +1345,8 @@ static JSBool dom_node_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER
 
 /*don't attempt to do anything with the scenegraph, it may be destroyed
 fortunately a sg cannot be created like that...*/
-void dom_document_finalize(JSContext *c, JSObject *obj)
-{
+DECL_FINALIZE(dom_document_finalize)
+
        GF_SceneGraph *sg = dom_get_doc(c, obj);
 
        sg = (GF_SceneGraph*) SMJS_GET_PRIVATE(c, obj);
@@ -1369,8 +1365,8 @@ void dom_document_finalize(JSContext *c, JSObject *obj)
        }
 }
 
-static JSBool dom_document_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( dom_document_getProperty )
+
        u32 prop_id;
        GF_SceneGraph *sg = dom_get_doc(c, obj);
        if (!sg) return JS_TRUE;
@@ -1409,8 +1405,8 @@ static JSBool dom_document_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GE
        return JS_TRUE;
 }
 
-static JSBool dom_document_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET(dom_document_setProperty)
+
        u32 prop_id;
        GF_SceneGraph *sg = dom_get_doc(c, obj);
        if (!sg) return JS_TRUE;
@@ -1545,7 +1541,7 @@ static JSBool SMJS_FUNCTION(xml_document_elements_by_tag)
        GF_SAFEALLOC(nl, DOMNodeList);
        if (name && !strcmp(name, "*")) name = NULL;
        xml_doc_gather_nodes((GF_ParentNode*)sg->RootNode, name, nl);
-       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass, 0, 0);
+       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, new_obj, nl);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(new_obj));
        SMJS_FREE(c, name);
@@ -1583,13 +1579,13 @@ static JSBool SMJS_FUNCTION(xml_document_element_by_id)
 }
 
 /*dom3 element*/
-void dom_element_finalize(JSContext *c, JSObject *obj)
-{
+DECL_FINALIZE( dom_element_finalize)
+
        dom_node_finalize(c, obj);
 }
 
-static JSBool dom_element_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( dom_element_getProperty) 
+
        u32 prop_id;
        GF_Node *n = dom_get_node(c, obj);
        if (!n) return JS_TRUE;
@@ -2050,7 +2046,7 @@ static JSBool SMJS_FUNCTION(xml_element_elements_by_tag)
                name = NULL;
        }
        xml_doc_gather_nodes((GF_ParentNode*)n, name, nl);
-       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass, 0, 0);
+       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, new_obj, nl);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(new_obj) );
        
@@ -2098,8 +2094,8 @@ static JSBool SMJS_FUNCTION(xml_element_set_id)
 
 /*dom3 character/text/comment*/
 
-static JSBool dom_text_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( dom_text_getProperty) 
+
        u32 prop_id;
        GF_DOMText *txt = (GF_DOMText*)dom_get_node(c, obj);
        if (!txt || (txt->sgprivate->tag != TAG_DOMText)) return JS_TRUE;
@@ -2124,8 +2120,8 @@ static JSBool dom_text_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER
        }
        return JS_TRUE;
 }
-static JSBool dom_text_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( dom_text_setProperty)
+
        u32 prop_id;
        GF_DOMText *txt = (GF_DOMText*)dom_get_node(c, obj);
        if (!txt || (txt->sgprivate->tag != TAG_DOMText)) return JS_TRUE;
@@ -2172,8 +2168,8 @@ static JSBool SMJS_FUNCTION(event_prevent_default)
        return JS_TRUE;
 }
 
-static JSBool event_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( event_getProperty)
+
        JSString *s;
        GF_DOM_Event *evt = SMJS_GET_PRIVATE(c, obj);
        if (evt==NULL) return JS_TRUE;
@@ -2527,10 +2523,10 @@ static void xml_http_reset(XMLHTTPContext *ctx)
        ctx->html_status = 0;
 }
 
-static void xml_http_finalize(JSContext *c, JSObject *obj)
-{
+static DECL_FINALIZE( xml_http_finalize)
+
        XMLHTTPContext *ctx;
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (ctx) {
                if (ctx->onreadystatechange) gf_js_remove_root(c, &(ctx->onreadystatechange), GF_JSGC_VAL);
@@ -2541,9 +2537,9 @@ static void xml_http_finalize(JSContext *c, JSObject *obj)
 static JSBool SMJS_FUNCTION(xml_http_constructor)
 {
        XMLHTTPContext *p;
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&dom_rt->xmlHTTPRequestClass)
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        GF_SAFEALLOC(p, XMLHTTPContext);
        p->c = c;
        p->_this = obj;
@@ -2587,7 +2583,7 @@ static JSBool SMJS_FUNCTION(xml_http_open)
        SMJS_OBJ
        SMJS_ARGS
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -2656,7 +2652,7 @@ static JSBool SMJS_FUNCTION(xml_http_set_header)
        SMJS_OBJ
        SMJS_ARGS
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -2895,7 +2891,7 @@ static JSBool SMJS_FUNCTION(xml_http_send)
        SMJS_OBJ
        SMJS_ARGS
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -2910,7 +2906,7 @@ static JSBool SMJS_FUNCTION(xml_http_send)
        if (argc) {
                if (JSVAL_IS_NULL(argv[0])) {
                } else  if (JSVAL_IS_OBJECT(argv[0])) {
-//                     if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &documentClass, NULL) ) return JS_TRUE;
+//                     if (!GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &documentClass, NULL) ) return JS_TRUE;
 
                        /*NOT SUPPORTED YET, we must serialize the sg*/
                        return JS_TRUE;
@@ -2999,7 +2995,7 @@ static JSBool SMJS_FUNCTION(xml_http_abort)
        XMLHTTPContext *ctx;
        SMJS_OBJ
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -3018,7 +3014,7 @@ static JSBool SMJS_FUNCTION(xml_http_get_all_headers)
        XMLHTTPContext *ctx;
        SMJS_OBJ
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -3052,7 +3048,7 @@ static JSBool SMJS_FUNCTION(xml_http_get_header)
        XMLHTTPContext *ctx;
        SMJS_OBJ
        SMJS_ARGS
-       if (!argc || !JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!argc || !GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -3081,11 +3077,11 @@ static JSBool SMJS_FUNCTION(xml_http_get_header)
        return JS_TRUE;
 }
 
-static JSBool xml_http_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( xml_http_getProperty)
+
        JSString *s;
        XMLHTTPContext *ctx;
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -3137,14 +3133,13 @@ static JSBool xml_http_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER
                        return JS_TRUE;
                }
        }
-       return JS_PropertyStub(c, obj, id, vp);
-       return JS_TRUE;
+       return SMJS_CALL_PROP_STUB();
 }
 
-static JSBool xml_http_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( xml_http_setProperty)
+
        XMLHTTPContext *ctx;
-       if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_TRUE;
        ctx = (XMLHTTPContext *)SMJS_GET_PRIVATE(c, obj);
        if (!ctx) return JS_TRUE;
 
@@ -3179,14 +3174,14 @@ static JSBool xml_http_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER
 }
 
 
-static JSBool dcci_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(dcci_getProperty)
+
        GF_DOMFullAttribute *att;
        GF_ChildNodeItem *child;
        GF_DOMFullNode *n;
        char *value;
        JSString *s;
-       if (!JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
        n = (GF_DOMFullNode*) dom_get_node(c, obj);
        if (!n) return JS_TRUE;
 
@@ -3265,17 +3260,18 @@ static JSBool dcci_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
                        return JS_TRUE;
                }
        }
-       return JS_PropertyStub(c, obj, id, vp);
+       return SMJS_CALL_PROP_STUB();
 }
 
-static JSBool dcci_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( dcci_setProperty)
+
        GF_ChildNodeItem *child;
        GF_DOMFullNode *n;
+       GF_DOMFullAttribute*att;
        GF_DOM_Event evt;
        char *str;
-       jsval readonly=JSVAL_NULL;
-       if (!JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
+       Bool readonly;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
        n = (GF_DOMFullNode*) dom_get_node(c, obj);
        if (!n) return JS_TRUE;
 
@@ -3286,12 +3282,16 @@ static JSBool dcci_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, js
                switch (SMJS_ID_TO_INT(id)) {
                /*value*/
                case 0:
-#if (JS_VERSION>=185)
-                       dcci_getProperty(c, obj, (jsint) (3), &readonly);
-#else
-                       dcci_getProperty(c, obj, INT_TO_JSVAL(3), &readonly);
-#endif
-                       if (JSVAL_TO_BOOLEAN(readonly) == JS_TRUE) break;
+                       readonly = 0;
+                       att = (GF_DOMFullAttribute*) n->attributes;
+                       while (att) {
+                               if (att->name && !strcmp(att->name, "readOnly") && att->data && !strcmp(att->data, "true")) {
+                                       readonly = 1;
+                                       break;
+                               }
+                               att = (GF_DOMFullAttribute*) att->next;
+                       }
+                       if (readonly) break;
                        child = n->children;
                        while (child) {
                                if (child->node && (child->node->sgprivate->tag==TAG_DOMText)) {
@@ -3362,7 +3362,7 @@ static JSBool SMJS_FUNCTION(dcci_has_property)
        char *ns, *name;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
        n = (GF_DOMFullNode*) dom_get_node(c, obj);
        if (!n) return JS_TRUE;
        if (argc!=3) return JS_TRUE;
@@ -3419,7 +3419,7 @@ static JSBool SMJS_FUNCTION(dcci_search_property)
        SMJS_OBJ
        SMJS_ARGS
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->DCCIClass, NULL) ) return JS_TRUE;
        n = (GF_DOMFullNode*) dom_get_node(c, obj);
        if (!n) return JS_TRUE;
        if (argc!=4) return JS_TRUE;
@@ -3432,7 +3432,7 @@ static JSBool SMJS_FUNCTION(dcci_search_property)
 
        GF_SAFEALLOC(nl, DOMNodeList);
        dcci_prop_collect(nl, n, ns, name, deep, 1);
-       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass, 0, 0);
+       new_obj = JS_NewObject(c, &dom_rt->domNodeListClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, new_obj, nl);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(new_obj) );
        SMJS_FREE(c, ns);
@@ -3440,33 +3440,39 @@ static JSBool SMJS_FUNCTION(dcci_search_property)
        return JS_TRUE;
 }
 
-static JSBool storage_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_GET( storage_getProperty)
+
+       /*avoids gcc warning*/
+       if (!id) id=0;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE;
        return JS_TRUE;
 }
 
-static JSBool storage_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_SET( storage_setProperty)
+
+       /*avoids gcc warning*/
+       if (!id) id=0;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE;
        return JS_TRUE;
 }
 
 static JSBool SMJS_FUNCTION(storage_constructor)
 {
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&dom_rt->storageClass)
 
-       if (!JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE;
        return JS_TRUE;
 }
 
-static void storage_finalize(JSContext *c, JSObject *obj)
-{
+static DECL_FINALIZE( storage_finalize)
+
+       /*avoids GCC warning*/
+       if (!c) c=NULL;
 }
 
 void dom_js_define_storage(JSContext *c, JSObject *parent_obj, const char *name)
 {
-    JS_DefineObject(c, parent_obj, name, &dom_rt->storageClass, 0, 0 );
+    JS_DefineObject(c, parent_obj, name, &dom_rt->storageClass._class, 0, 0 );
 }
 
 void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
@@ -3544,17 +3550,17 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
 
                        {0, 0, 0, 0, 0}
                };
-               dom_rt->dom_node_proto = JS_InitClass(c, global, 0, &dom_rt->domNodeClass, 0, 0, nodeProps, nodeFuncs, 0, 0);
-               if (!dom_rt->dom_node_proto) {
+               GF_JS_InitClass(c, global, 0, &dom_rt->domNodeClass, 0, 0, nodeProps, nodeFuncs, 0, 0);
+               if (!dom_rt->domNodeClass._proto) {
                        GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[DOMCore] Not enough memory to initialize JS node class\n"));
                        return;
                }
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] node class initialized\n"));
 
-               JS_DefineProperty(c, dom_rt->dom_node_proto, "ELEMENT_NODE", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_node_proto, "TEXT_NODE", INT_TO_JSVAL(3), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_node_proto, "CDATA_SECTION_NODE", INT_TO_JSVAL(4), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_node_proto, "DOCUMENT_NODE", INT_TO_JSVAL(9), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domNodeClass._proto, "ELEMENT_NODE", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domNodeClass._proto, "TEXT_NODE", INT_TO_JSVAL(3), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domNodeClass._proto, "CDATA_SECTION_NODE", INT_TO_JSVAL(4), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domNodeClass._proto, "DOCUMENT_NODE", INT_TO_JSVAL(9), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
 
        }
        {
@@ -3597,7 +3603,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                        {0, 0, 0, 0, 0},
                };
 
-               dom_rt->dom_document_proto = JS_InitClass(c, global, dom_rt->dom_node_proto, &dom_rt->domDocumentClass, 0, 0, documentProps, documentFuncs, 0, 0);
+               GF_JS_InitClass(c, global, dom_rt->domNodeClass._proto, &dom_rt->domDocumentClass, 0, 0, documentProps, documentFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] document class initialized\n"));
        }
 
@@ -3631,7 +3637,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                        {"schemaTypeInfo",              2,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0},
                        {0, 0, 0, 0, 0},
                };
-               dom_rt->dom_element_proto = JS_InitClass(c, global, dom_rt->dom_node_proto, &dom_rt->domElementClass, 0, 0, elementProps, elementFuncs, 0, 0);
+               GF_JS_InitClass(c, global, dom_rt->domNodeClass._proto, &dom_rt->domElementClass, 0, 0, elementProps, elementFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] element class initialized\n"));
        }
 
@@ -3657,7 +3663,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                        {"wholeText",                                   4,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0},
                        {0, 0, 0, 0, 0},
                };
-               JS_InitClass(c, global, dom_rt->dom_node_proto, &dom_rt->domTextClass, 0, 0, textProps, textFuncs, 0, 0);
+               GF_JS_InitClass(c, global, dom_rt->domNodeClass._proto, &dom_rt->domTextClass, 0, 0, textProps, textFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] text class initialized\n"));
        }
 
@@ -3728,17 +3734,17 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
 
                        {0, 0, 0, 0, 0},
                };
-               dom_rt->dom_event_proto = JS_InitClass(c, global, 0, &dom_rt->domEventClass, 0, 0, eventProps, eventFuncs, 0, 0);
+               GF_JS_InitClass(c, global, 0, &dom_rt->domEventClass, 0, 0, eventProps, eventFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] Event class initialized\n"));
 
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "CAPTURING_PHASE", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "AT_TARGET", INT_TO_JSVAL(2), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "BUBBLING_PHASE", INT_TO_JSVAL(3), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "CAPTURING_PHASE", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "AT_TARGET", INT_TO_JSVAL(2), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "BUBBLING_PHASE", INT_TO_JSVAL(3), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
 
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "DOM_KEY_LOCATION_STANDARD ", INT_TO_JSVAL(0), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "DOM_KEY_LOCATION_LEFT", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "DOM_KEY_LOCATION_RIGHT", INT_TO_JSVAL(2), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(c, dom_rt->dom_event_proto, "DOM_KEY_LOCATION_NUMPAD", INT_TO_JSVAL(3), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "DOM_KEY_LOCATION_STANDARD ", INT_TO_JSVAL(0), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "DOM_KEY_LOCATION_LEFT", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "DOM_KEY_LOCATION_RIGHT", INT_TO_JSVAL(2), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, dom_rt->domEventClass._proto, "DOM_KEY_LOCATION_NUMPAD", INT_TO_JSVAL(3), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
        }
 
 
@@ -3751,7 +3757,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                        {"length",      0,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(c, global, 0, &dom_rt->domNodeListClass, 0, 0, nodeListProps, nodeListFuncs, 0, 0);
+               GF_JS_InitClass(c, global, 0, &dom_rt->domNodeListClass, 0, 0, nodeListProps, nodeListFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] nodeList class initialized\n"));
        }
 
@@ -3775,7 +3781,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                        /*todo - addEventListener and removeEventListener*/
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
-               JS_InitClass(c, global, 0, &dom_rt->xmlHTTPRequestClass, xml_http_constructor, 0, xmlHTTPRequestClassProps, xmlHTTPRequestClassFuncs, 0, 0);
+               GF_JS_InitClass(c, global, 0, &dom_rt->xmlHTTPRequestClass, xml_http_constructor, 0, xmlHTTPRequestClassProps, xmlHTTPRequestClassFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] XMLHttpRequest class initialized\n"));
        }
 
@@ -3786,7 +3792,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                JSFunctionSpec storageClassFuncs[] = {
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
-               dom_rt->storage_proto = JS_InitClass(c, global, 0, &dom_rt->storageClass, storage_constructor, 0, storageClassProps, storageClassFuncs, 0, 0);
+               GF_JS_InitClass(c, global, 0, &dom_rt->storageClass, storage_constructor, 0, storageClassProps, storageClassFuncs, 0, 0);
                GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] Storage class initialized\n"));
        }
 
@@ -3819,7 +3825,7 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global)
                                SMJS_FUNCTION_SPEC(0, 0, 0)
                        };
 
-                       JS_InitClass(c, global, dom_rt->dom_element_proto, &dom_rt->DCCIClass, 0, 0, DCCIClassProps, DCCIClassFuncs, 0, 0);
+                       GF_JS_InitClass(c, global, dom_rt->domElementClass._proto, &dom_rt->DCCIClass, 0, 0, DCCIClassProps, DCCIClassFuncs, 0, 0);
                        dcci_root = dom_base_node_construct(c, &dom_rt->DCCIClass, dcci->RootNode);
                        JS_DefineProperty(c, global, "DCCIRoot", dcci_root, 0, 0, JSPROP_READONLY | JSPROP_PERMANENT );
 
@@ -3876,7 +3882,11 @@ void dom_js_pre_destroy(JSContext *c, GF_SceneGraph *sg, GF_Node *n)
                }
        }
        if (sg->document) {
+#ifdef USE_FFDEV_15
+               dom_document_finalize(NULL, sg->document);
+#else
                dom_document_finalize(c, sg->document);
+#endif
        }
 }
 
@@ -3893,7 +3903,7 @@ void dom_js_unload()
 
 static void dom_js_define_document_ex(JSContext *c, JSObject *global, GF_SceneGraph *doc, const char *name)
 {
-       JSClass *__class;
+       GF_JSClass *__class;
        JSObject *obj;
        if (!doc || !doc->RootNode) return;
 
@@ -3905,7 +3915,7 @@ static void dom_js_define_document_ex(JSContext *c, JSObject *global, GF_SceneGr
                __class = dom_rt->get_document_class(doc);
        if (!__class) __class = &dom_rt->domDocumentClass;
 
-       obj = JS_DefineObject(c, global, name, __class, 0, 0 );
+       obj = JS_DefineObject(c, global, name, & __class->_class, 0, 0 );
        gf_node_register(doc->RootNode, NULL);
        SMJS_SET_PRIVATE(c, obj, doc);
        doc->document = obj;
@@ -3918,19 +3928,19 @@ void dom_js_define_document(JSContext *c, JSObject *global, GF_SceneGraph *doc)
 
 JSObject *dom_js_define_event(JSContext *c, JSObject *global)
 {
-       JSObject *obj = JS_DefineObject(c, global, "evt", &dom_rt->domEventClass, 0, 0 );
+       JSObject *obj = JS_DefineObject(c, global, "evt", &dom_rt->domEventClass._class, 0, 0 );
        //JS_AliasProperty(c, global, "evt", "event");
        return obj;
 }
 
 JSObject *gf_dom_new_event(JSContext *c)
 {
-       return JS_NewObject(c, &dom_rt->domEventClass, 0, 0);
+       return JS_NewObject(c, &dom_rt->domEventClass._class, 0, 0);
 }
-JSObject *dom_js_get_node_proto(JSContext *c) { return dom_rt->dom_node_proto; }
-JSObject *dom_js_get_element_proto(JSContext *c) { return dom_rt->dom_element_proto; }
-JSObject *dom_js_get_document_proto(JSContext *c) { return dom_rt->dom_document_proto; }
-JSObject *dom_js_get_event_proto(JSContext *c) { return dom_rt->dom_event_proto; }
+JSObject *dom_js_get_node_proto(JSContext *c) { return dom_rt->domNodeClass._proto; }
+JSObject *dom_js_get_element_proto(JSContext *c) { return dom_rt->domElementClass._proto; }
+JSObject *dom_js_get_document_proto(JSContext *c) { return dom_rt->domDocumentClass._proto; }
+JSObject *dom_js_get_event_proto(JSContext *c) { return dom_rt->domEventClass._proto; }
 
 void dom_set_class_selector(JSContext *c, void *(*get_element_class)(GF_Node *n), void *(*get_document_class)(GF_SceneGraph *n) )
 {
index 5e708c3f91471d9e0ea288989db85571fdc15714..20156ac8b0d6c82025cfa4e9e8166370bc2ea625 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index f020ce18c03e0a10a2fcdc589cc6999a5427d12a..3c2d2bcf8f6e55b17f1e87588130d75edb79f4ad 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index 2c9cb6972ef112a42ef083941330f740d7b23b42..dcda43d0bdae0815de18407d5bf8b70f624ee0cc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index c16f05b8e5d9d41645134842be742c303ab3f65e..3a93fa504eb38a42c53718d504327d5175d3ebe2 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Cyril Concolato - Jean Le Feuvre
- *    Copyright (c)2004-200X ENST - All rights reserved
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *
  *  This file is part of GPAC / SVG Scene Graph sub-project
  *
index aa525d9a58b7618c32874da3e7e6f5a21c685daf..d95063d0a161c272132cfe202084bff19c238a49 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Cyril Concolato - Jean Le Feuvre
- *    Copyright (c)2004-200X ENST - All rights reserved
+ *                     Authors: Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *
  *  This file is part of GPAC / SVG Scene Graph sub-project
  *
index e09a0729acc8462dee29c3a69347be491fa24c96..bdc7d09b983b43fade07914ab46bb7c86bb2db07 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                     Authors: Cyril Concolato - Jean le Feuvre - Jean-Claude Moissinac
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Cyril Concolato, Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Loader module
index 56a5f6f7565b2c9f82cdfde33d3d96ce035c9a7a..870359d8aba7c26bc57294192db5a73297d58638 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                                     GPAC Multimedia Framework
  *
- *                     Authors: Cyril Concolato - Jean le Feuvre - Jean-Claude Moissinac
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Cyril Concolato, Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Loader module
index 63ab3a5829851db853cded34a10b1f588d88a1a1..1f3d7c7e4875b16e6273e083000fd59fa04e045b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -46,8 +46,13 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No
 
 
 jsval dom_element_construct(JSContext *c, GF_Node *n);
+#ifdef USE_FFDEV_15
+void dom_element_finalize(JSFreeOp *fop, JSObject *obj);
+void dom_document_finalize(JSFreeOp *fop, JSObject *obj);
+#else
 void dom_element_finalize(JSContext *c, JSObject *obj);
 void dom_document_finalize(JSContext *c, JSObject *obj);
+#endif
 
 GF_Node *dom_get_element(JSContext *c, JSObject *obj);
 GF_SceneGraph *dom_get_doc(JSContext *c, JSObject *obj);
@@ -83,15 +88,15 @@ typedef struct
 {
        u32 nb_inst;
        /*SVG uDOM classes*/
-       JSClass svgElement;
-       JSClass svgDocument;
-       JSClass globalClass;
-       JSClass connectionClass;
-       JSClass rgbClass;
-       JSClass rectClass;
-       JSClass pointClass;
-       JSClass pathClass;
-       JSClass matrixClass;
+       GF_JSClass svgElement;
+       GF_JSClass svgDocument;
+       GF_JSClass globalClass;
+       GF_JSClass connectionClass;
+       GF_JSClass rgbClass;
+       GF_JSClass rectClass;
+       GF_JSClass pointClass;
+       GF_JSClass pathClass;
+       GF_JSClass matrixClass;
 } GF_SVGuDOM;
 static GF_SVGuDOM *svg_rt = NULL;
 
@@ -138,7 +143,7 @@ static JSBool SMJS_FUNCTION(svg_nav_to_location)
        GF_SceneGraph *sg;
        SMJS_OBJ
        SMJS_ARGS
-       if ((argc!=1) || !JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL)) return JS_TRUE;
+       if ((argc!=1) || !GF_JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL)) return JS_TRUE;
        sg = SMJS_GET_PRIVATE(c, obj);
        par.uri.url = SMJS_CHARS(c, argv[0]);
        par.uri.nb_params = 0;
@@ -182,7 +187,7 @@ static JSBool SMJS_FUNCTION(svg_echo)
        GF_SceneGraph *sg;
        SMJS_OBJ
        SMJS_ARGS
-       if ((argc!=1) || !JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL)) return JS_TRUE;
+       if ((argc!=1) || !GF_JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL)) return JS_TRUE;
        sg = SMJS_GET_PRIVATE(c, obj);
        if (!sg) return JS_TRUE;
 
@@ -221,10 +226,10 @@ static void svg_define_udom_exception(JSContext *c, JSObject *global)
        JS_DefineProperty(c, obj, "NAV_UP_LEFT", INT_TO_JSVAL(11), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
 }
 
-static JSBool global_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( global_getProperty)
+
        GF_SceneGraph *sg;
-       if (!JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL) )
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL) )
                return JS_TRUE;
 
        sg = SMJS_GET_PRIVATE(c, obj);
@@ -293,8 +298,8 @@ static GF_Node *get_corresponding_use(GF_Node *n)
        /*otherwise recursively get up the tree*/
        return get_corresponding_use(gf_node_get_parent(n, 0));
 }
-static JSBool svg_doc_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( svg_doc_getProperty)
+
        u32 prop_id;
        GF_SceneGraph *sg = dom_get_doc(c, obj);
        if (!sg) return JS_TRUE;
@@ -309,8 +314,8 @@ static JSBool svg_doc_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER,
        return JS_TRUE;
 }
 
-static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(svg_element_getProperty)
+
        u32 prop_id;
        GF_JSAPIParam par;
        JSString *s;
@@ -348,7 +353,7 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GET
        case 7:/*currentTranslate*/
                if (n->sgprivate->tag!=TAG_SVG_svg) return JS_TRUE;
                if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_TRANSLATE, (GF_Node *)n, &par)) {
-                       JSObject *r = JS_NewObject(c, &svg_rt->pointClass, 0, 0);
+                       JSObject *r = JS_NewObject(c, &svg_rt->pointClass._class, 0, 0);
                        pointCI *rc = gf_malloc(sizeof(pointCI));
                        rc->x = FIX2FLT(par.pt.x);
                        rc->y = FIX2FLT(par.pt.y);
@@ -361,7 +366,7 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GET
        case 8:/*viewport*/
                if (n->sgprivate->tag!=TAG_SVG_svg) return JS_TRUE;
                if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_VIEWPORT, (GF_Node *)n, &par)) {
-                       JSObject *r = JS_NewObject(c, &svg_rt->rectClass, 0, 0);
+                       JSObject *r = JS_NewObject(c, &svg_rt->rectClass._class, 0, 0);
                        rectCI *rc = gf_malloc(sizeof(rectCI));
                        rc->x = FIX2FLT(par.rc.x);
                        rc->y = FIX2FLT(par.rc.y);
@@ -407,8 +412,8 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GET
        return JS_TRUE;
 }
 
-static JSBool svg_element_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( svg_element_setProperty)
+
        GF_JSAPIParam par;
        jsdouble d;
        u32 prop_id;
@@ -837,7 +842,7 @@ JSBool SMJS_FUNCTION(svg_udom_get_matrix_trait)
 
        if (info.fieldType==SVG_Transform_datatype) {
                GF_Matrix2D *mx = gf_malloc(sizeof(GF_Matrix2D));
-               mO = JS_NewObject(c, &svg_rt->matrixClass, 0, 0);
+               mO = JS_NewObject(c, &svg_rt->matrixClass._class, 0, 0);
                gf_mx2d_init(*mx);
                gf_mx2d_copy(*mx, ((SVG_Transform*)info.far_ptr)->mat);
 
@@ -869,7 +874,7 @@ JSBool SMJS_FUNCTION(svg_udom_get_rect_trait)
        if (info.fieldType==SVG_ViewBox_datatype) {
                rectCI *rc;
                SVG_ViewBox *v = (SVG_ViewBox *)info.far_ptr;
-               newObj = JS_NewObject(c, &svg_rt->rectClass, 0, 0);
+               newObj = JS_NewObject(c, &svg_rt->rectClass._class, 0, 0);
                GF_SAFEALLOC(rc, rectCI);
                rc->x = FIX2FLT(v->x);
                rc->y = FIX2FLT(v->y);
@@ -931,7 +936,7 @@ JSBool SMJS_FUNCTION(svg_udom_get_rgb_color_trait)
                SVG_Color *col = (SVG_Color *)info.far_ptr;
                if (col->type == SVG_COLOR_CURRENTCOLOR) return JS_TRUE;
                if (col->type == SVG_COLOR_INHERIT) return JS_TRUE;
-               newObj = JS_NewObject(c, &svg_rt->rgbClass, 0, 0);
+               newObj = JS_NewObject(c, &svg_rt->rgbClass._class, 0, 0);
                GF_SAFEALLOC(rgb, rgbCI);
                rgb->r = (u8) (255*FIX2FLT(col->red)) ;
                rgb->g = (u8) (255*FIX2FLT(col->green)) ;
@@ -945,7 +950,7 @@ JSBool SMJS_FUNCTION(svg_udom_get_rgb_color_trait)
        {
                SVG_Paint *paint = (SVG_Paint *)info.far_ptr;
                if (1 || paint->type==SVG_PAINT_COLOR) {
-                       newObj = JS_NewObject(c, &svg_rt->rgbClass, 0, 0);
+                       newObj = JS_NewObject(c, &svg_rt->rgbClass._class, 0, 0);
                        GF_SAFEALLOC(rgb, rgbCI);
                        rgb->r = (u8) (255*FIX2FLT(paint->color.red) );
                        rgb->g = (u8) (255*FIX2FLT(paint->color.green) );
@@ -1088,7 +1093,7 @@ JSBool SMJS_FUNCTION(svg_udom_set_matrix_trait)
 
        if (JSVAL_IS_NULL(argv[1]) || !JSVAL_IS_OBJECT(argv[1])) return JS_TRUE;
        mO = JSVAL_TO_OBJECT(argv[1]);
-       if (!JS_InstanceOf(c, mO, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, mO, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx = SMJS_GET_PRIVATE(c, mO);
        if (!mx) return JS_TRUE;
 
@@ -1121,7 +1126,7 @@ JSBool SMJS_FUNCTION(svg_udom_set_rect_trait)
 
        if (JSVAL_IS_NULL(argv[1]) || !JSVAL_IS_OBJECT(argv[1])) return JS_TRUE;
        rO = JSVAL_TO_OBJECT(argv[1]);
-       if (!JS_InstanceOf(c, rO, &svg_rt->rectClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, rO, &svg_rt->rectClass, NULL) ) return JS_TRUE;
        rc = SMJS_GET_PRIVATE(c, rO);
        if (!rc) return JS_TRUE;
 
@@ -1157,7 +1162,7 @@ JSBool SMJS_FUNCTION(svg_udom_set_path_trait)
        if (!JSVAL_IS_STRING(argv[0])) return JS_TRUE;
        if (JSVAL_IS_NULL(argv[1]) || !JSVAL_IS_OBJECT(argv[1])) return JS_TRUE;
        pO = JSVAL_TO_OBJECT(argv[1]);
-       if (!JS_InstanceOf(c, pO, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, pO, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        path = SMJS_GET_PRIVATE(c, pO);
        if (!path) return JS_TRUE;
        
@@ -1224,7 +1229,7 @@ JSBool SMJS_FUNCTION(svg_udom_set_rgb_color_trait)
        if (!JSVAL_IS_OBJECT(argv[1])) return JS_TRUE;
        colO = JSVAL_TO_OBJECT(argv[1]);
        if (!colO) return JS_TRUE;
-       if (!JS_InstanceOf(c, colO, &svg_rt->rgbClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, colO, &svg_rt->rgbClass, NULL) ) return JS_TRUE;
        rgb = SMJS_GET_PRIVATE(c, colO);
        if (!rgb) return JS_TRUE;
 
@@ -1270,7 +1275,7 @@ static JSBool SMJS_FUNCTION_EXT(svg_get_bbox, Bool get_screen)
        par.bbox.is_set = 0;
        if (ScriptAction(n->sgprivate->scenegraph, get_screen ? GF_JSAPI_OP_GET_SCREEN_BBOX : GF_JSAPI_OP_GET_LOCAL_BBOX, (GF_Node *)n, &par) ) {
                if (par.bbox.is_set) {
-                       JSObject *rO = JS_NewObject(c, &svg_rt->rectClass, 0, 0);
+                       JSObject *rO = JS_NewObject(c, &svg_rt->rectClass._class, 0, 0);
                        rectCI *rc = gf_malloc(sizeof(rectCI));
                        rc->sg = NULL;
                        rc->x = FIX2FLT(par.bbox.min_edge.x);
@@ -1304,7 +1309,7 @@ JSBool SMJS_FUNCTION(svg_udom_get_screen_ctm)
        if (!n || argc) return JS_TRUE;
 
        if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_TRANSFORM, (GF_Node *)n, &par)) {
-               JSObject *mO = JS_NewObject(c, &svg_rt->matrixClass, 0, 0);
+               JSObject *mO = JS_NewObject(c, &svg_rt->matrixClass._class, 0, 0);
                GF_Matrix2D *mx = gf_malloc(sizeof(GF_Matrix2D));
                gf_mx2d_from_mx(mx, &par.mx);
                SMJS_SET_PRIVATE(c, mO, mx);
@@ -1338,7 +1343,7 @@ JSBool SMJS_FUNCTION(svg_udom_create_matrix_components)
        mx->m[2] = FLT2FIX(v);
        JS_ValueToNumber(c, argv[5], &v);
        mx->m[5] = FLT2FIX(v);
-       mat = JS_NewObject(c, &svg_rt->matrixClass, 0, 0);
+       mat = JS_NewObject(c, &svg_rt->matrixClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, mat, mx);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(mat) );
        return JS_TRUE;
@@ -1352,7 +1357,7 @@ JSBool SMJS_FUNCTION(svg_udom_create_rect)
        if (!n || argc) return JS_TRUE;
 
        GF_SAFEALLOC(rc, rectCI);
-       r = JS_NewObject(c, &svg_rt->rectClass, 0, 0);
+       r = JS_NewObject(c, &svg_rt->rectClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, r, rc);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(r) );
        return JS_TRUE;
@@ -1366,7 +1371,7 @@ JSBool SMJS_FUNCTION(svg_udom_create_point)
        if (!n || argc) return JS_TRUE;
 
        GF_SAFEALLOC(pt, pointCI);
-       r = JS_NewObject(c, &svg_rt->pointClass, 0, 0);
+       r = JS_NewObject(c, &svg_rt->pointClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, r, pt);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(r) );
        return JS_TRUE;
@@ -1380,7 +1385,7 @@ JSBool SMJS_FUNCTION(svg_udom_create_path)
        if (!n || argc) return JS_TRUE;
 
        GF_SAFEALLOC(path, pathCI);
-       p = JS_NewObject(c, &svg_rt->pathClass, 0, 0);
+       p = JS_NewObject(c, &svg_rt->pathClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, p, path);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(p) );
        return JS_TRUE;
@@ -1399,7 +1404,7 @@ JSBool SMJS_FUNCTION(svg_udom_create_color)
        col->r = JSVAL_TO_INT(argv[0]);
        col->g = JSVAL_TO_INT(argv[1]);
        col->b = JSVAL_TO_INT(argv[2]);
-       p = JS_NewObject(c, &svg_rt->rgbClass, 0, 0);
+       p = JS_NewObject(c, &svg_rt->rgbClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, p, col);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(p) );
        return JS_TRUE;
@@ -1536,15 +1541,17 @@ static JSFunctionSpec connectionFuncs[] = {
 };
 #endif /*GPAC_UNUSED_FUNC*/
 
-static void baseCI_finalize(JSContext *c, JSObject *obj)
-{
+static DECL_FINALIZE( baseCI_finalize)
+
+       /*avoids GCC warning*/
        void *data = SMJS_GET_PRIVATE(c, obj);
+       if (!c) c=NULL;
        if (data) gf_free(data);
 }
 
-static JSBool rgb_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->rgbClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_GET(rgb_getProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->rgbClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                rgbCI *col = SMJS_GET_PRIVATE(c, obj);
                if (!col) return JS_TRUE;
@@ -1558,9 +1565,9 @@ static JSBool rgb_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsv
        }
        return JS_TRUE;
 }
-static JSBool rgb_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->rgbClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_SET( rgb_setProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->rgbClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                rgbCI *col = SMJS_GET_PRIVATE(c, obj);
                if (!col) return JS_TRUE;
@@ -1575,9 +1582,9 @@ static JSBool rgb_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsv
 }
 
 
-static JSBool rect_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->rectClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_GET(rect_getProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->rectClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                rectCI *rc = SMJS_GET_PRIVATE(c, obj);
                if (!rc) return JS_TRUE;
@@ -1599,9 +1606,9 @@ static JSBool rect_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
        }
        return JS_TRUE;
 }
-static JSBool rect_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->rectClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_SET( rect_setProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->rectClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                jsdouble d;
                rectCI *rc = SMJS_GET_PRIVATE(c, obj);
@@ -1618,9 +1625,9 @@ static JSBool rect_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, js
        return JS_TRUE;
 }
 
-static JSBool point_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->pointClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_GET( point_getProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pointClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                pointCI *pt = SMJS_GET_PRIVATE(c, obj);
                if (!pt) return JS_TRUE;
@@ -1638,9 +1645,9 @@ static JSBool point_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, j
        }
        return JS_TRUE;
 }
-static JSBool point_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->pointClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_SET( point_setProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pointClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                jsdouble d;
                pointCI *pt = SMJS_GET_PRIVATE(c, obj);
@@ -1683,7 +1690,7 @@ static JSObject *svg_new_path_object(JSContext *c, SVG_PathData *d)
                        p->pts[i].y = FIX2FLT(pt->y);
                }
        }
-       obj = JS_NewObject(c, &svg_rt->pathClass, 0, 0);
+       obj = JS_NewObject(c, &svg_rt->pathClass._class, 0, 0);
        SMJS_SET_PRIVATE(c, obj, p);
        return obj;
 #endif
@@ -1710,9 +1717,9 @@ static void pathCI_finalize(JSContext *c, JSObject *obj)
        }
 }
 
-static JSBool path_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+static SMJS_FUNC_PROP_GET( path_getProperty)
+
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        if (SMJS_ID_IS_INT(id)) {
                pathCI *p = SMJS_GET_PRIVATE(c, obj);
                if (!p) return JS_TRUE;
@@ -1729,7 +1736,7 @@ static JSBool SMJS_FUNCTION(svg_path_get_segment)
        u32 idx;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if ((argc!=1) || !JSVAL_IS_INT(argv[0])) return JS_TRUE;
@@ -1756,7 +1763,7 @@ static JSBool SMJS_FUNCTION(svg_path_get_segment_param)
        SMJS_OBJ
        SMJS_ARGS
        u32 i, idx, param_idx, pt_idx;
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if ((argc!=2) || !JSVAL_IS_INT(argv[0]) || !JSVAL_IS_INT(argv[1])) return JS_TRUE;
@@ -1845,7 +1852,7 @@ static JSBool SMJS_FUNCTION(svg_path_move_to)
        u32 nb_pts;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if ((argc!=2) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1])) return JS_TRUE;
@@ -1866,7 +1873,7 @@ static JSBool SMJS_FUNCTION(svg_path_line_to)
        u32 nb_pts;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if ((argc!=2) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1])) return JS_TRUE;
@@ -1888,7 +1895,7 @@ static JSBool SMJS_FUNCTION(svg_path_quad_to)
        u32 nb_pts;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if ((argc!=4) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1]) || !JSVAL_IS_NUMBER(argv[2]) || !JSVAL_IS_NUMBER(argv[3])) return JS_TRUE;
@@ -1911,7 +1918,7 @@ static JSBool SMJS_FUNCTION(svg_path_curve_to)
        u32 nb_pts;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if ((argc!=6) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1]) || !JSVAL_IS_NUMBER(argv[2]) || !JSVAL_IS_NUMBER(argv[3]) || !JSVAL_IS_NUMBER(argv[4]) || !JSVAL_IS_NUMBER(argv[5])) return JS_TRUE;
@@ -1934,7 +1941,7 @@ static JSBool SMJS_FUNCTION(svg_path_close)
 {
        pathCI *p;
        SMJS_OBJ
-       if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_TRUE;
        p = SMJS_GET_PRIVATE(c, obj);
        if (!p) return JS_TRUE;
        if (argc) return JS_TRUE;
@@ -1944,10 +1951,10 @@ static JSBool SMJS_FUNCTION(svg_path_close)
        return JS_TRUE;
 }
 
-static JSBool matrix_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( matrix_getProperty)
+
        GF_Matrix2D *mx;
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx = SMJS_GET_PRIVATE(c, obj);
        if (!SMJS_ID_IS_INT(id)) return JS_TRUE;
 
@@ -1963,11 +1970,11 @@ static JSBool matrix_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER,
        }
        return JS_TRUE;
 }
-static JSBool matrix_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( matrix_setProperty)
+
        jsdouble d;
        GF_Matrix2D *mx;
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx = SMJS_GET_PRIVATE(c, obj);
        if (!SMJS_ID_IS_INT(id)) return JS_TRUE;
 
@@ -1988,7 +1995,7 @@ static JSBool SMJS_FUNCTION(svg_mx2d_get_component)
        GF_Matrix2D *mx;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx = SMJS_GET_PRIVATE(c, obj);
        if (!mx || (argc!=1)) return JS_TRUE;
        if (!JSVAL_IS_INT(argv[0])) return JS_TRUE;
@@ -2009,12 +2016,12 @@ static JSBool SMJS_FUNCTION(svg_mx2d_multiply)
        GF_Matrix2D *mx1, *mx2;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx1 = SMJS_GET_PRIVATE(c, obj);
        if (!mx1 || (argc!=1)) return JS_TRUE;
        if (!JSVAL_IS_OBJECT(argv[0])) return JS_TRUE;
        mat = JSVAL_TO_OBJECT(argv[0]);
-       if (!JS_InstanceOf(c, mat, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, mat, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx2 = SMJS_GET_PRIVATE(c, mat);
        if (!mx2) return JS_TRUE;
        gf_mx2d_add_matrix(mx1, mx2);
@@ -2026,7 +2033,7 @@ static JSBool SMJS_FUNCTION(svg_mx2d_inverse)
 {
        GF_Matrix2D *mx1;
        SMJS_OBJ
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx1 = SMJS_GET_PRIVATE(c, obj);
        if (!mx1) return JS_TRUE;
        gf_mx2d_inverse(mx1);
@@ -2040,7 +2047,7 @@ static JSBool SMJS_FUNCTION(svg_mx2d_translate)
        GF_Matrix2D *mx1, mx2;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx1 = SMJS_GET_PRIVATE(c, obj);
        if (!mx1 || (argc!=2)) return JS_TRUE;
        JS_ValueToNumber(c, argv[0], &x);
@@ -2060,7 +2067,7 @@ static JSBool SMJS_FUNCTION(svg_mx2d_scale)
        GF_Matrix2D *mx1, mx2;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx1 = SMJS_GET_PRIVATE(c, obj);
        if (!mx1 || (argc!=1)) return JS_TRUE;
        JS_ValueToNumber(c, argv[0], &scale);
@@ -2077,7 +2084,7 @@ static JSBool SMJS_FUNCTION(svg_mx2d_rotate)
        GF_Matrix2D *mx1, mx2;
        SMJS_OBJ
        SMJS_ARGS
-       if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
+       if (!GF_JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_TRUE;
        mx1 = SMJS_GET_PRIVATE(c, obj);
        if (!mx1 || (argc!=1)) return JS_TRUE;
        JS_ValueToNumber(c, argv[0], &angle);
@@ -2090,7 +2097,7 @@ static JSBool SMJS_FUNCTION(svg_mx2d_rotate)
 
 jsval svg_udom_new_rect(JSContext *c, Fixed x, Fixed y, Fixed width, Fixed height)
 {
-       JSObject *r = JS_NewObject(c, &svg_rt->rectClass, 0, 0);
+       JSObject *r = JS_NewObject(c, &svg_rt->rectClass._class, 0, 0);
        rectCI *rc = gf_malloc(sizeof(rectCI));
        rc->x = FIX2FLT(x);
        rc->y = FIX2FLT(y);
@@ -2103,7 +2110,7 @@ jsval svg_udom_new_rect(JSContext *c, Fixed x, Fixed y, Fixed width, Fixed heigh
 
 jsval svg_udom_new_point(JSContext *c, Fixed x, Fixed y)
 {
-       JSObject *p = JS_NewObject(c, &svg_rt->pointClass, 0, 0);
+       JSObject *p = JS_NewObject(c, &svg_rt->pointClass._class, 0, 0);
        pointCI *pt = gf_malloc(sizeof(pointCI));
        pt->x = FIX2FLT(x);
        pt->y = FIX2FLT(y);
@@ -2131,7 +2138,6 @@ void *svg_get_document_class(GF_SceneGraph *sg)
 
 static void svg_init_js_api(GF_SceneGraph *scene)
 {
-       JSObject *proto;
        JS_SetContextPrivate(scene->svg_js->js_ctx, scene);
        JS_SetErrorReporter(scene->svg_js->js_ctx, svg_script_error);
 
@@ -2179,7 +2185,7 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {0, 0, 0, 0, 0}
                };
                JSObject *doc_proto = dom_js_get_document_proto(scene->svg_js->js_ctx);
-               JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, doc_proto, &svg_rt->svgDocument, 0, 0, svgDocumentProps, 0, 0, 0);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, doc_proto, &svg_rt->svgDocument, 0, 0, svgDocumentProps, 0, 0, 0);
        }
 
        /*SVGElement class*/
@@ -2259,7 +2265,7 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {0, 0, 0, 0, 0}
                };
                JSObject *elt_proto = dom_js_get_element_proto(scene->svg_js->js_ctx);
-               JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, elt_proto, &svg_rt->svgElement, 0, 0, svgElementProps, svgElementFuncs, 0, 0);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, elt_proto, &svg_rt->svgElement, 0, 0, svgElementProps, svgElementFuncs, 0, 0);
 
        }
 
@@ -2271,7 +2277,7 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {"blue",        2,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->rgbClass, 0, 0, rgbClassProps, 0, 0, 0);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->rgbClass, 0, 0, rgbClassProps, 0, 0, 0);
        }
        /*SVGRect class*/
        {
@@ -2282,7 +2288,7 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {"height",      3,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->rectClass, 0, 0, rectClassProps, 0, 0, 0);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->rectClass, 0, 0, rectClassProps, 0, 0, 0);
        }
        /*SVGPoint class*/
        {
@@ -2291,7 +2297,7 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {"y",   1,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->pointClass, 0, 0, pointClassProps, 0, 0, 0);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->pointClass, 0, 0, pointClassProps, 0, 0, 0);
        }
        /*SVGMatrix class*/
        {
@@ -2313,7 +2319,7 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {"f",   5,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->matrixClass, 0, 0, matrixClassProps, matrixClassFuncs, 0, 0);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->matrixClass, 0, 0, matrixClassProps, matrixClassFuncs, 0, 0);
        }
        /*SVGPath class*/
        {
@@ -2331,12 +2337,12 @@ static void svg_init_js_api(GF_SceneGraph *scene)
                        {"numberOfSegments",    0,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               proto = JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->pathClass, 0, 0, pathClassProps, pathClassFuncs, 0, 0);
-               JS_DefineProperty(scene->svg_js->js_ctx, proto, "MOVE_TO", INT_TO_JSVAL(77), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(scene->svg_js->js_ctx, proto, "LINE_TO", INT_TO_JSVAL(76), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(scene->svg_js->js_ctx, proto, "CURVE_TO", INT_TO_JSVAL(67), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(scene->svg_js->js_ctx, proto, "QUAD_TO", INT_TO_JSVAL(81), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
-               JS_DefineProperty(scene->svg_js->js_ctx, proto, "CLOSE", INT_TO_JSVAL(90), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               GF_JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->pathClass, 0, 0, pathClassProps, pathClassFuncs, 0, 0);
+               JS_DefineProperty(scene->svg_js->js_ctx, svg_rt->pathClass._proto, "MOVE_TO", INT_TO_JSVAL(77), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(scene->svg_js->js_ctx, svg_rt->pathClass._proto, "LINE_TO", INT_TO_JSVAL(76), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(scene->svg_js->js_ctx, svg_rt->pathClass._proto, "CURVE_TO", INT_TO_JSVAL(67), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(scene->svg_js->js_ctx, svg_rt->pathClass._proto, "QUAD_TO", INT_TO_JSVAL(81), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(scene->svg_js->js_ctx, svg_rt->pathClass._proto, "CLOSE", INT_TO_JSVAL(90), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
 
        }
        /*we have our own constructors*/
@@ -2620,7 +2626,7 @@ void JSScript_LoadSVG(GF_Node *node)
 #ifdef DUMP_DEF_AND_ROOT
 void dump_root(const char *name, void *rp, void *data)
 {
-       if (name[0]=='_') fprintf(stdout, "\t%s\n", name);
+       if (name[0]=='_') fprintf(stderr, "\t%s\n", name);
 }
 #endif
 
@@ -2739,14 +2745,14 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No
 #ifdef DUMP_DEF_AND_ROOT
        if ((event->type==GF_EVENT_CLICK) || (event->type==GF_EVENT_MOUSEOVER)) {
                NodeIDedItem *reg_node;
-               fprintf(stdout, "Node registry\n");
+               fprintf(stderr, "Node registry\n");
                reg_node = node->sgprivate->scenegraph->id_node;
                while (reg_node) {
-                       fprintf(stdout, "\t%s\n", reg_node->NodeName);
+                       fprintf(stderr, "\t%s\n", reg_node->NodeName);
                        reg_node = reg_node->next;
                }
 
-               fprintf(stdout, "\n\nNamed roots:\n");
+               fprintf(stderr, "\n\nNamed roots:\n");
                JS_DumpNamedRoots(JS_GetRuntime(svg_js->js_ctx), dump_root, NULL);
        }
 #endif
index 556a2685dabc0b07a9197c6b745a1e6336d793b4..bfdcbdfef7a6cb0d8414af52529d6ecd827f6cdd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2004
+ *                     Authors: Cyril Concolato, Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2004-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph sub-project
index 6bea733e3d94be0a19a27324cc39534a0089e588..e39ad3f45e80018e00e62586ef4b646d007637f5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index c8eabaf9417f9a91fae7c68933e86667230b770e..355c84266d5efce7740faae9036b28b97c710076 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -352,7 +353,9 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon
        GF_Node *node, *child;
        GF_ChildNodeItem *list, *last;
        GF_Route *r1, *r2;
+#ifndef GPAC_DISABLE_BIFS
        void BIFS_SetupConditionalClone(GF_Node *node, GF_Node *orig);
+#endif
        GF_ProtoInstance *proto;
        GF_Proto *proto_node;
        GF_FieldInfo field_orig, field;
@@ -457,9 +460,13 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon
                }
        }
 
+#ifndef GPAC_DISABLE_BIFS
        /*init node before creating ISed routes so the eventIn handler are in place*/
-       if (node->sgprivate->tag == TAG_MPEG4_Conditional) BIFS_SetupConditionalClone(node, orig);
-       else if (node->sgprivate->tag != TAG_ProtoNode) gf_node_init(node);
+       if (node->sgprivate->tag == TAG_MPEG4_Conditional)
+               BIFS_SetupConditionalClone(node, orig);
+       else 
+#endif
+               if (node->sgprivate->tag != TAG_ProtoNode) gf_node_init(node);
 
        if (!inScene->pOwningProto) return node;
        proto = inScene->pOwningProto;
@@ -876,7 +883,7 @@ GF_Err gf_sg_proto_field_set_ised(GF_Proto *proto, u32 protoFieldIndex, GF_Node
                } else if ((gf_sg_vrml_get_sf_type(field.fieldType)==GF_SG_VRML_SFURL) && (gf_sg_vrml_get_sf_type(nodeField.fieldType) == GF_SG_VRML_SFSTRING)) {
                        e = GF_OK;
                } else {
-//                     printf("error in IS - node field %s.%s - inType %s - outType %s\n", gf_node_get_class_name(node) , nodeField.name, gf_sg_vrml_get_field_type_by_name(field.fieldType), gf_sg_vrml_get_field_type_by_name(nodeField.fieldType));
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[VRML] error in IS - node field %s.%s - inType %s - outType %s\n", gf_node_get_class_name(node) , nodeField.name, gf_sg_vrml_get_field_type_by_name(field.fieldType), gf_sg_vrml_get_field_type_by_name(nodeField.fieldType)));
                        return GF_SG_INVALID_PROTO;
                }
        }
@@ -956,7 +963,7 @@ GF_Err gf_sg_proto_instance_set_ised(GF_Node *protoinst, u32 protoFieldIndex, GF
                } else if ((gf_sg_vrml_get_sf_type(field.fieldType)==GF_SG_VRML_SFURL) && (gf_sg_vrml_get_sf_type(nodeField.fieldType) == GF_SG_VRML_SFSTRING)) {
                        e = GF_OK;
                } else {
-//                     printf("error in IS - node field %s.%s - inType %s - outType %s\n", gf_node_get_class_name(node) , nodeField.name, gf_sg_vrml_get_field_type_by_name(field.fieldType), gf_sg_vrml_get_field_type_by_name(nodeField.fieldType));
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[VRML] error in IS - node field %s.%s - inType %s - outType %s\n", gf_node_get_class_name(node) , nodeField.name, gf_sg_vrml_get_field_type_by_name(field.fieldType), gf_sg_vrml_get_field_type_by_name(nodeField.fieldType)));
                        return GF_SG_INVALID_PROTO;
                }
        }
index 17b4a5f63b23cd33917d3e7470cb1304053820b0..5ad5502d976b280e09c53e1476ef2919a34ff365 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index d51f74f3ab687af5eb54ef7eea0f12e3a6630bae..2fdc4e75ace6e14f74dad4b5c16c1dbc020d6710 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index 0ec8310a5b502a0ee645413b6b167f4b85f4c27b..45a626261b93362ef86abc003e321ac3c9a9ba20 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
@@ -34,8 +35,6 @@
 #include <gpac/internal/smjs_api.h>
 
 
-
-
 /*fixes for JS > 1.8.0rc1 where GC routines have changed*/
 GF_EXPORT
 Bool gf_js_add_root(JSContext *cx, void *rp, u32 type)
@@ -85,38 +84,19 @@ Bool gf_js_add_named_root(JSContext *cx, void *rp, u32 type, const char *name)
 #endif
 }
 
-GF_EXPORT
-Bool gf_js_remove_root(JSContext *cx, void *rp, u32 type)
+
+JSObject *gf_sg_js_global_object(JSContext *cx, GF_JSClass *__class)
 {
 #if (JS_VERSION>=185)
-       JSBool ret;
-       switch (type) {
-       case GF_JSGC_STRING:
-               ret = JS_RemoveStringRoot(cx, rp);
-               break;
-       case GF_JSGC_OBJECT:
-               ret = JS_RemoveObjectRoot(cx, rp);
-               break;
-       case GF_JSGC_VAL:
-               ret = JS_RemoveValueRoot(cx, rp);
-               break;
-       default:
-               ret = JS_RemoveGCThingRoot(cx, rp);
-               break;
-       }
-       return (ret == JS_TRUE) ? 1 : 0;
+       __class->_class.flags |= JSCLASS_GLOBAL_FLAGS;
+#ifdef USE_FFDEV_16
+       return JS_NewGlobalObject(cx, &__class->_class, NULL);
 #else
-       return (JS_RemoveRoot(cx, rp)==JS_TRUE) ? 1 : 0;
+       return JS_NewCompartmentAndGlobalObject(cx, &__class->_class, NULL);
 #endif
-}
 
-JSObject *gf_sg_js_global_object(JSContext *cx, JSClass *__class)
-{
-#if (JS_VERSION>=185)
-       __class->flags |= JSCLASS_GLOBAL_FLAGS;
-       return JS_NewCompartmentAndGlobalObject(cx, __class, NULL);
 #else
-       return JS_NewObject(cx, __class, 0, 0 );
+       return JS_NewObject(cx, &__class->_class, 0, 0 );
 #endif
 }
 
@@ -188,28 +168,28 @@ typedef struct
        JSContext *ctx;
 
        GF_Mutex *mx;
-       JSClass SFNodeClass;
+       GF_JSClass SFNodeClass;
 
 #ifndef GPAC_DISABLE_VRML
-       JSClass globalClass;
-       JSClass browserClass;
-       JSClass SFVec2fClass;
-       JSClass SFVec3fClass;
-       JSClass SFRotationClass;
-       JSClass SFColorClass;
-       JSClass SFImageClass;
-       JSClass MFInt32Class;
-       JSClass MFBoolClass;
-       JSClass MFFloatClass;
-       JSClass MFTimeClass;
-       JSClass MFVec2fClass;
-       JSClass MFVec3fClass;
-       JSClass MFRotationClass;
-       JSClass MFColorClass;
-       JSClass MFStringClass;
-       JSClass MFUrlClass;
-       JSClass MFNodeClass;
-       JSClass AnyClass;
+       GF_JSClass globalClass;
+       GF_JSClass browserClass;
+       GF_JSClass SFVec2fClass;
+       GF_JSClass SFVec3fClass;
+       GF_JSClass SFRotationClass;
+       GF_JSClass SFColorClass;
+       GF_JSClass SFImageClass;
+       GF_JSClass MFInt32Class;
+       GF_JSClass MFBoolClass;
+       GF_JSClass MFFloatClass;
+       GF_JSClass MFTimeClass;
+       GF_JSClass MFVec2fClass;
+       GF_JSClass MFVec3fClass;
+       GF_JSClass MFRotationClass;
+       GF_JSClass MFColorClass;
+       GF_JSClass MFStringClass;
+       GF_JSClass MFUrlClass;
+       GF_JSClass MFNodeClass;
+       GF_JSClass AnyClass;
 #endif
 
        /*extensions are loaded for the lifetime of the runtime NOT of the context - this avoids nasty
@@ -219,6 +199,41 @@ typedef struct
 
 static GF_JSRuntime *js_rt = NULL;
 
+GF_EXPORT
+Bool gf_js_remove_root(JSContext *cx, void *rp, u32 type)
+{
+#if (JS_VERSION>=185)
+       switch (type) {
+       case GF_JSGC_STRING:
+#ifdef USE_FFDEV_15
+               if (!cx) JS_RemoveStringRootRT(js_rt->js_runtime, rp);
+               else 
+#endif
+                       JS_RemoveStringRoot(cx, rp);
+               break;
+       case GF_JSGC_OBJECT:
+#ifdef USE_FFDEV_15
+               if (!cx) JS_RemoveObjectRootRT(js_rt->js_runtime, rp);
+               else 
+#endif
+                       JS_RemoveObjectRoot(cx, rp);
+               break;
+       case GF_JSGC_VAL:
+#ifdef USE_FFDEV_15
+               if (!cx) JS_RemoveValueRootRT(js_rt->js_runtime, rp);
+               else 
+#endif
+                       JS_RemoveValueRoot(cx, rp);
+               break;
+       default:
+               if (cx) JS_RemoveGCThingRoot(cx, rp);
+               break;
+       }
+       return 1;
+#else
+       return (JS_RemoveRoot(cx, rp)==JS_TRUE) ? 1 : 0;
+#endif
+}
 
 void gf_sg_load_script_extensions(GF_SceneGraph *sg, JSContext *c, JSObject *obj, Bool unload)
 {
@@ -371,7 +386,11 @@ void gf_sg_ecmascript_del(JSContext *ctx)
 
 GF_EXPORT
 #if (JS_VERSION>=185)
+#ifdef USE_FFDEV_15
+JSBool gf_sg_js_has_instance(JSContext *c, JSHandleObject obj,const jsval *val, JSBool *vp)
+#else
 JSBool gf_sg_js_has_instance(JSContext *c, JSObject *obj,const jsval *val, JSBool *vp)
+#endif
 #else
 JSBool gf_sg_js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp)
 #endif
@@ -414,7 +433,11 @@ Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain);
 void gf_sg_js_call_gc(JSContext *c)
 {
        gf_sg_lock_javascript(c, 1);
+#ifdef         USE_FFDEV_14
+       JS_GC(js_rt->js_runtime);
+#else
        JS_GC(c);
+#endif
        gf_sg_lock_javascript(c, 0);
 }
 
@@ -590,7 +613,7 @@ static JSObject *node_get_binding(GF_ScriptPriv *priv, GF_Node *node, Bool is_co
        node->sgprivate->flags |= GF_NODE_HAS_BINDING;
        gf_node_register(node, NULL);
 
-       obj = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, 0);
+       obj = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass._class, 0, 0);
        SMJS_SET_PRIVATE(priv->js_ctx, obj, field);
 
        field->obj = obj;
@@ -791,7 +814,7 @@ static JSBool SMJS_FUNCTION(addRoute)
        SMJS_ARGS
        if (argc!=4) return JS_FALSE;
 
-       if (!JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (!JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
 
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0]));
        assert(ptr->field.fieldType==GF_SG_VRML_SFNODE);
@@ -816,7 +839,7 @@ static JSBool SMJS_FUNCTION(addRoute)
        if (!JSVAL_IS_OBJECT(argv[2])) return JS_FALSE;
 
        /*regular route*/
-       if (JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[2]), &js_rt->SFNodeClass, NULL) && JSVAL_IS_STRING(argv[3]) ) {
+       if (GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[2]), &js_rt->SFNodeClass, NULL) && JSVAL_IS_STRING(argv[3]) ) {
                GF_Route *r;
                ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[2]));
                assert(ptr->field.fieldType==GF_SG_VRML_SFNODE);
@@ -898,7 +921,7 @@ static JSBool SMJS_FUNCTION(deleteRoute)
        SMJS_ARGS
        if (argc!=4) return JS_FALSE;
 
-       if (!JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (!JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        
        if (JSVAL_IS_STRING(argv[1]) && JSVAL_IS_NULL(argv[2]) && JSVAL_IS_NULL(argv[3])) {
                ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0]));
@@ -915,7 +938,7 @@ static JSBool SMJS_FUNCTION(deleteRoute)
                return JS_TRUE;
        }
 
-       if (!JSVAL_IS_OBJECT(argv[2]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[2]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (!JSVAL_IS_OBJECT(argv[2]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[2]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        if (!JSVAL_IS_STRING(argv[1]) || !JSVAL_IS_STRING(argv[3])) return JS_FALSE;
 
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0]));
@@ -1170,8 +1193,8 @@ void Script_FieldChanged(JSContext *c, GF_Node *parent, GF_JSField *parent_owner
        }
 }
 
-JSBool gf_sg_script_eventout_set_prop(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *val)
-{
+SMJS_FUNC_PROP_SET( gf_sg_script_eventout_set_prop)
+
        u32 i;
        char *eventName;
        GF_ScriptPriv *script;
@@ -1184,6 +1207,8 @@ JSBool gf_sg_script_eventout_set_prop(JSContext *c, JSObject *obj, SMJS_PROP_SET
        if (! SMJS_ID_IS_STRING(id)) return JS_FALSE;
        str = SMJS_ID_TO_STRING(id);
        if (!str) return JS_FALSE;
+       /*avoids gcc warning*/
+       if (!obj) obj=NULL;
 
        script = JS_GetScriptStack(c);
        if (!script) return JS_FALSE;
@@ -1194,7 +1219,7 @@ JSBool gf_sg_script_eventout_set_prop(JSContext *c, JSObject *obj, SMJS_PROP_SET
        while ((sf = gf_list_enum(script->fields, &i))) {
                if (!stricmp(sf->name, eventName)) {
                        gf_node_get_field(n, sf->ALL_index, &info);
-                       gf_sg_script_to_node_field(c, *val, &info, n, NULL);
+                       gf_sg_script_to_node_field(c, *vp, &info, n, NULL);
                        sf->activate_event_out = 1;
                        SMJS_FREE(c, eventName);
                        return JS_TRUE;
@@ -1370,7 +1395,7 @@ static JSBool SMJS_FUNCTION(SFNodeConstructor)
        GF_ScriptPriv *priv = JS_GetScriptStack(c);
        M_Script *sc = JS_GetScript(c);
        SMJS_ARGS
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->SFNodeClass)
        tag = 0;
        if (!argc) {
                field = NewJSField(c);
@@ -1381,7 +1406,7 @@ static JSBool SMJS_FUNCTION(SFNodeConstructor)
                SMJS_SET_RVAL( OBJECT_TO_JSVAL(obj) );
                return JS_TRUE;
        }
-       if (!JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (!GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
 
        ID = 0;
        node_name = SMJS_CHARS(c, argv[0]);
@@ -1443,11 +1468,13 @@ locate_proto:
 
        return JS_TRUE;
 }
-static void node_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call)
+static void node_finalize_ex(JSContext *c, JSObject * obj, Bool is_js_call)
 {
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
 
+#ifndef USE_FFDEV_15
        JS_ObjectDestroyed(c, obj, ptr, is_js_call);
+#endif
 
        if (ptr) {
                JS_GetScript(ptr->js_ctx ? ptr->js_ctx : c);
@@ -1463,13 +1490,14 @@ static void node_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call)
                gf_free(ptr);
        }
 }
-static void node_finalize(JSContext *c, JSObject *obj)
-{
+
+static DECL_FINALIZE(node_finalize)
+
        node_finalize_ex(c, obj, 1);
 }
 
-static JSBool node_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(node_getProperty)
+
        GF_Node *n;
        u32 index;
        JSString *str;
@@ -1477,7 +1505,7 @@ static JSBool node_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
        GF_JSField *ptr;
        GF_ScriptPriv *priv;
 
-       if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (! GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        assert(ptr->field.fieldType==GF_SG_VRML_SFNODE);
        n = * ((GF_Node **)ptr->field.far_ptr);
@@ -1507,7 +1535,7 @@ static JSBool node_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
                        GF_JSAPIParam par;
                        par.bbox.is_set = 0;
                        if (ScriptAction(c, n->sgprivate->scenegraph, GF_JSAPI_OP_GET_LOCAL_BBOX, (GF_Node *)n, &par) ) {
-                               JSObject *_obj = JS_NewObject(priv->js_ctx, &js_rt->AnyClass, 0, 0);
+                               JSObject *_obj = JS_NewObject(priv->js_ctx, &js_rt->AnyClass._class, 0, 0);
                                Float x, y, w, h;
                                x = y = w = h = 0;
                                if (par.bbox.is_set) {
@@ -1532,14 +1560,15 @@ static JSBool node_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js
        return JS_FALSE;
 }
 
-static JSBool node_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( node_setProperty)
+
        GF_Node *n;
        GF_FieldInfo info;
        u32 index;
        char *fieldname;
        GF_JSField *ptr;
-       if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+
+       if (! GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
 
        /*this is the prototype*/
@@ -1595,7 +1624,7 @@ static JSBool SMJS_FUNCTION(node_toString)
        GF_JSField *f;
        const char *name;
        SMJS_OBJ
-       if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (! GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        f = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        if (!f) return JS_FALSE;
 
@@ -1623,7 +1652,7 @@ static JSBool SMJS_FUNCTION(node_getTime)
        GF_Node *n;
        GF_JSField *f;
        SMJS_OBJ
-       if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (! GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        f = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        if (!f) return JS_FALSE;
 
@@ -1634,8 +1663,8 @@ static JSBool SMJS_FUNCTION(node_getTime)
 }
 
 /* Generic field destructor */
-static void field_finalize(JSContext *c, JSObject *obj)
-{
+static DECL_FINALIZE(field_finalize)
+
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        JS_ObjectDestroyed(c, obj, ptr, 1);
        if (!ptr) return;
@@ -1672,10 +1701,10 @@ static JSBool SMJS_FUNCTION(SFImageConstructor)
        u32 w, h, nbComp;
        MFInt32 *pixels;
        SMJS_ARGS
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->SFImageClass)
        if (argc<4) return 0;
        if (!JSVAL_IS_INT(argv[0]) || !JSVAL_IS_INT(argv[1]) || !JSVAL_IS_INT(argv[2])) return JS_FALSE;
-       if (!JSVAL_IS_OBJECT(argv[3]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[3]), &js_rt->MFInt32Class, NULL)) return JS_FALSE;
+       if (!JSVAL_IS_OBJECT(argv[3]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[3]), &js_rt->MFInt32Class, NULL)) return JS_FALSE;
        w = JSVAL_TO_INT(argv[0]);
        h = JSVAL_TO_INT(argv[1]);
        nbComp = JSVAL_TO_INT(argv[2]);
@@ -1684,8 +1713,8 @@ static JSBool SMJS_FUNCTION(SFImageConstructor)
        return JS_TRUE;
 }
 
-static JSBool image_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(image_getProperty)
+
        GF_ScriptPriv *priv = JS_GetScriptStack(c);
        GF_JSField *val = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        SFImage *sfi;
@@ -1714,8 +1743,8 @@ static JSBool image_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, j
        return JS_TRUE;
 }
 
-static JSBool image_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( image_setProperty)
+
        u32 ival;
        Bool changed = 0;
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
@@ -1752,7 +1781,7 @@ static JSBool image_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, j
                {
                        MFInt32 *pixels;
                        u32 len, i;
-                       if (!JSVAL_IS_OBJECT(*vp) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), &js_rt->MFInt32Class, NULL)) return JS_FALSE;
+                       if (!JSVAL_IS_OBJECT(*vp) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), &js_rt->MFInt32Class, NULL)) return JS_FALSE;
                        pixels = (MFInt32 *) ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)))->field.far_ptr;
                        if (sfi->pixels) gf_free(sfi->pixels);
                        len = sfi->width*sfi->height*sfi->numComponents;
@@ -1788,14 +1817,14 @@ static JSBool SMJS_FUNCTION(SFVec2fConstructor)
 {
        jsdouble x = 0.0, y = 0.0;
        SMJS_ARGS
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->SFVec2fClass)
        if (argc > 0) JS_ValueToNumber(c, argv[0], &x);
        if (argc > 1) JS_ValueToNumber(c, argv[1], &y);
        SFVec2f_Create(c, obj, FLT2FIX( x), FLT2FIX( y));
        return JS_TRUE;
 }
-static JSBool vec2f_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(vec2f_getProperty)
+
        GF_JSField *val = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
 
        if (SMJS_ID_IS_INT(id)) {
@@ -1808,8 +1837,8 @@ static JSBool vec2f_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, j
        return JS_TRUE;
 }
 
-static JSBool vec2f_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET(vec2f_setProperty)
+
        jsdouble d;
        Fixed v;
        Bool changed = 0;
@@ -1849,12 +1878,12 @@ static JSBool SMJS_FUNCTION(vec2f_add)
        JSObject *pNew;
        SMJS_ARGS
        SMJS_OBJ
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec2fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec2fClass, NULL))
                return JS_FALSE;
 
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
     v2 = ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec2fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec2f_Create(c, pNew, v1->x + v2->x, v1->y + v2->y);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -1865,12 +1894,12 @@ static JSBool SMJS_FUNCTION(vec2f_subtract)
        JSObject *pNew;
        SMJS_ARGS
        SMJS_OBJ
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec2fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec2fClass, NULL))
                return JS_FALSE;
 
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
     v2 = ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec2fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec2f_Create(c, pNew, v1->x - v2->x, v1->y - v2->y);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -1881,7 +1910,7 @@ static JSBool SMJS_FUNCTION(vec2f_negate)
        JSObject *pNew;
        SMJS_OBJ
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec2fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec2f_Create(c, pNew, -v1->x , -v1->y );
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -1896,7 +1925,7 @@ static JSBool SMJS_FUNCTION(vec2f_multiply)
        SMJS_OBJ
        if (argc<=0) return JS_FALSE;
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec2fClass._class, 0, SMJS_GET_PARENT(c, obj));
        JS_ValueToNumber(c, argv[0], &d );
        v = FLT2FIX( d);
        SFVec2f_Create(c, pNew, gf_mulfix(v1->x , v), gf_mulfix(v1->y, v) );
@@ -1913,7 +1942,7 @@ static JSBool SMJS_FUNCTION(vec2f_divide)
        SMJS_OBJ
        if (argc<=0) return JS_FALSE;
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec2fClass._class, 0, SMJS_GET_PARENT(c, obj));
        JS_ValueToNumber(c, argv[0], &d );
        v = FLT2FIX(d);
        SFVec2f_Create(c, pNew, gf_divfix(v1->x, v),  gf_divfix(v1->y, v));
@@ -1938,7 +1967,7 @@ static JSBool SMJS_FUNCTION(vec2f_normalize)
        SMJS_OBJ
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
        res = gf_v2d_len(v1);
-       pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec2fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec2f_Create(c, pNew, gf_divfix(v1->x, res), gf_divfix(v1->y, res) );
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -1948,7 +1977,7 @@ static JSBool SMJS_FUNCTION(vec2f_dot)
        SFVec2f *v1, *v2;
        SMJS_OBJ
        SMJS_ARGS
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec2fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec2fClass, NULL))
                return JS_FALSE;
 
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
@@ -1977,15 +2006,15 @@ static JSBool SMJS_FUNCTION(SFVec3fConstructor)
 {
        SMJS_ARGS
        jsdouble x = 0.0, y = 0.0, z = 0.0;
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->SFVec3fClass)
        if (argc > 0) JS_ValueToNumber(c, argv[0], &x);
        if (argc > 1) JS_ValueToNumber(c, argv[1], &y);
        if (argc > 2) JS_ValueToNumber(c, argv[2], &z);
        SFVec3f_Create(c, obj, FLT2FIX( x), FLT2FIX( y), FLT2FIX( z));
        return JS_TRUE;
 }
-static JSBool vec3f_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(vec3f_getProperty)
+
        GF_JSField *val = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        if (SMJS_ID_IS_INT(id)) {
                switch (SMJS_ID_TO_INT(id)) {
@@ -1997,8 +2026,8 @@ static JSBool vec3f_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, j
        }
        return JS_TRUE;
 }
-static JSBool vec3f_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( vec3f_setProperty )
+
        jsdouble d;
        Fixed v;
        Bool changed = 0;
@@ -2040,12 +2069,12 @@ static JSBool SMJS_FUNCTION(vec3f_add)
        JSObject *pNew;
        SMJS_ARGS
        SMJS_OBJ
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
                return JS_FALSE;
 
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
     v2 = ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec3f_Create(c, pNew, v1->x + v2->x, v1->y + v2->y, v1->z + v2->z);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2056,12 +2085,12 @@ static JSBool SMJS_FUNCTION(vec3f_subtract)
        JSObject *pNew;
        SMJS_ARGS
        SMJS_OBJ
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
                return JS_FALSE;
 
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
     v2 = ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec3f_Create(c, pNew, v1->x - v2->x, v1->y - v2->y, v1->z - v2->z);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2072,7 +2101,7 @@ static JSBool SMJS_FUNCTION(vec3f_negate)
        JSObject *pNew;
        SMJS_OBJ
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec3f_Create(c, pNew, -v1->x , -v1->y , -v1->z );
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2088,7 +2117,7 @@ static JSBool SMJS_FUNCTION(vec3f_multiply)
        if (argc<=0) return JS_FALSE;
 
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        JS_ValueToNumber(c, argv[0], &d );
        v = FLT2FIX(d);
        SFVec3f_Create(c, pNew, gf_mulfix(v1->x, v), gf_mulfix(v1->y, v), gf_mulfix(v1->z, v) );
@@ -2105,7 +2134,7 @@ static JSBool SMJS_FUNCTION(vec3f_divide)
        SMJS_ARGS
        if (argc<=0) return JS_FALSE;
        v1 = ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        JS_ValueToNumber(c, argv[0], &d );
        v = FLT2FIX(d);
        SFVec3f_Create(c, pNew, gf_divfix(v1->x, v), gf_divfix(v1->y, v), gf_divfix(v1->z, v));
@@ -2129,7 +2158,7 @@ static JSBool SMJS_FUNCTION(vec3f_normalize)
        SMJS_OBJ
        v1 = * (SFVec3f *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
        gf_vec_norm(&v1);
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec3f_Create(c, pNew, v1.x, v1.y, v1.z);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2139,7 +2168,7 @@ static JSBool SMJS_FUNCTION(vec3f_dot)
        SFVec3f v1, v2;
        SMJS_OBJ
        SMJS_ARGS
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
                return JS_FALSE;
 
        v1 = *(SFVec3f *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
@@ -2153,12 +2182,12 @@ static JSBool SMJS_FUNCTION(vec3f_cross)
        JSObject *pNew;
        SMJS_ARGS
        SMJS_OBJ
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
                return JS_FALSE;
 
        v1 = * (SFVec3f *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
     v2 = * (SFVec3f *) ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        v3 = gf_vec_cross(v1, v2);
        SFVec3f_Create(c, pNew, v3.x, v3.y, v3.z);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
@@ -2190,7 +2219,7 @@ static JSBool SMJS_FUNCTION(SFRotationConstructor)
        Fixed l1, l2, dot;
        SMJS_ARGS
        jsdouble x = 0.0, y = 0.0, z = 0.0, a = 0.0;
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->SFRotationClass)
 
        if (argc == 0) {
                SFRotation_Create(c, obj, FLT2FIX(x), FLT2FIX(y), FIX_ONE, FLT2FIX(a) );
@@ -2207,7 +2236,7 @@ static JSBool SMJS_FUNCTION(SFRotationConstructor)
        if (argc!=2) return JS_FALSE;
        if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;
        an_obj = JSVAL_TO_OBJECT(argv[0]);
-       if (! JS_InstanceOf(c, an_obj, &js_rt->SFVec3fClass, NULL)) return JS_FALSE;
+       if (! GF_JS_InstanceOf(c, an_obj, &js_rt->SFVec3fClass, NULL)) return JS_FALSE;
        v1 = * (SFVec3f *) ((GF_JSField *) SMJS_GET_PRIVATE(c, an_obj))->field.far_ptr;
        if (JSVAL_IS_DOUBLE(argv[1])) {
                JS_ValueToNumber(c, argv[1], &a);
@@ -2217,7 +2246,7 @@ static JSBool SMJS_FUNCTION(SFRotationConstructor)
 
        if (!JSVAL_IS_OBJECT(argv[1])) return JS_FALSE;
        an_obj = JSVAL_TO_OBJECT(argv[1]);
-       if (!JS_InstanceOf(c, an_obj, &js_rt->SFVec3fClass, NULL)) return JS_FALSE;
+       if (!GF_JS_InstanceOf(c, an_obj, &js_rt->SFVec3fClass, NULL)) return JS_FALSE;
        v2 = * (SFVec3f *) ((GF_JSField *) SMJS_GET_PRIVATE(c, an_obj))->field.far_ptr;
        l1 = gf_vec_len(v1);
        l2 = gf_vec_len(v2);
@@ -2230,8 +2259,8 @@ static JSBool SMJS_FUNCTION(SFRotationConstructor)
        return JS_TRUE;
 }
 
-static JSBool rot_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET(rot_getProperty)
+
        GF_JSField *val = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        if (SMJS_ID_IS_INT(id)) {
                switch (SMJS_ID_TO_INT(id)) {
@@ -2244,8 +2273,8 @@ static JSBool rot_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsv
        }
        return JS_TRUE;
 }
-static JSBool rot_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET( rot_setProperty )
+
        jsdouble d;
        Fixed v;
        Bool changed = 0;
@@ -2292,7 +2321,7 @@ static JSBool SMJS_FUNCTION(rot_getAxis)
        JSObject *pNew;
        SMJS_OBJ
        r = * (SFRotation *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec3f_Create(c, pNew, r.x, r.y, r.z);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2303,7 +2332,7 @@ static JSBool SMJS_FUNCTION(rot_inverse)
        JSObject *pNew;
        SMJS_OBJ
        r = * (SFRotation *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
-       pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFRotationClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFRotation_Create(c, pNew, r.x, r.y, r.z, r.q-GF_PI);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2317,7 +2346,7 @@ static JSBool SMJS_FUNCTION(rot_multiply)
        SMJS_OBJ
        SMJS_ARGS
 
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFRotationClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFRotationClass, NULL))
                return JS_FALSE;
 
        r1 = * (SFRotation *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
@@ -2327,7 +2356,7 @@ static JSBool SMJS_FUNCTION(rot_multiply)
        q1 = gf_quat_multiply(&q1, &q2);
        r1 = gf_quat_to_rotation(&q1);
 
-       pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFRotationClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFRotation_Create(c, pNew, r1.x, r1.y, r1.z, r1.q);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2342,7 +2371,7 @@ static JSBool SMJS_FUNCTION(rot_multVec)
        SMJS_ARGS
        if (argc<=0) return JS_FALSE;
 
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
                return JS_FALSE;
 
        r = *(SFRotation *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
@@ -2350,7 +2379,7 @@ static JSBool SMJS_FUNCTION(rot_multVec)
        gf_mx_init(mx);
        gf_mx_add_rotation(&mx, r.q, r.x, r.y, r.z);
        gf_mx_apply_vec(&mx, &v);
-       pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFVec3fClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFVec3f_Create(c, pNew, v.x, v.y, v.z);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2364,7 +2393,7 @@ static JSBool SMJS_FUNCTION(rot_setAxis)
        SMJS_ARGS
        if (argc<=0) return JS_FALSE;
 
-       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
+       if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFVec3fClass, NULL))
                return JS_FALSE;
 
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
@@ -2388,7 +2417,7 @@ static JSBool SMJS_FUNCTION(rot_slerp)
        SMJS_OBJ
        if (argc<=1) return JS_FALSE;
 
-       if (!JSVAL_IS_DOUBLE(argv[1]) || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFRotationClass, NULL)) return JS_FALSE;
+       if (!JSVAL_IS_DOUBLE(argv[1]) || !JSVAL_IS_OBJECT(argv[0]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFRotationClass, NULL)) return JS_FALSE;
 
        v1 = *(SFRotation *) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
        v2 = *(SFRotation *) ((GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr;
@@ -2397,7 +2426,7 @@ static JSBool SMJS_FUNCTION(rot_slerp)
        q2 = gf_quat_from_rotation(v2);
        q1 = gf_quat_slerp(q1, q2, FLT2FIX( d));
        res = gf_quat_to_rotation(&q1);
-       pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, SMJS_GET_PARENT(c, obj));
+       pNew = JS_NewObject(c, &js_rt->SFRotationClass._class, 0, SMJS_GET_PARENT(c, obj));
        SFRotation_Create(c, pNew, res.x, res.y, res.z, res.q);
        SMJS_SET_RVAL( OBJECT_TO_JSVAL(pNew) );
        return JS_TRUE;
@@ -2422,15 +2451,15 @@ static JSBool SMJS_FUNCTION(SFColorConstructor)
 {
        SMJS_ARGS
        jsdouble r = 0.0, g = 0.0, b = 0.0;
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->SFColorClass)
        if (argc > 0) JS_ValueToNumber(c, argv[0], &r);
        if (argc > 1) JS_ValueToNumber(c, argv[1], &g);
        if (argc > 2) JS_ValueToNumber(c, argv[2], &b);
        SFColor_Create(c, obj, FLT2FIX( r), FLT2FIX( g), FLT2FIX( b));
        return JS_TRUE;
 }
-static JSBool color_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_GET( color_getProperty )
+
        GF_JSField *val = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        if (SMJS_ID_IS_INT(id)) {
                switch (SMJS_ID_TO_INT(id)) {
@@ -2443,8 +2472,8 @@ static JSBool color_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, j
        return JS_TRUE;
 }
 
-static JSBool color_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
-{
+static SMJS_FUNC_PROP_SET(color_setProperty)
+
        jsdouble d;
        Fixed v;
        Bool changed = 0;
@@ -2529,10 +2558,10 @@ static void setup_js_array(JSContext *c, JSObject *obj, GF_JSField *ptr, uintN a
        gf_list_add(priv->js_cache, obj);
 }
 
-#define MFARRAY_CONSTRUCTOR(_fieldType)        \
+#define MFARRAY_CONSTRUCTOR(__classp, _fieldType)      \
        GF_JSField *ptr;        \
        SMJS_ARGS       \
-       SMJS_OBJ_CONSTRUCTOR    \
+       SMJS_OBJ_CONSTRUCTOR(__classp)  \
        ptr = NewJSField(c);    \
        ptr->field.fieldType = _fieldType;      \
        setup_js_array(c, obj, ptr, (jsint) argc, argv);        \
@@ -2542,31 +2571,31 @@ static void setup_js_array(JSContext *c, JSObject *obj, GF_JSField *ptr, uintN a
 
 static JSBool SMJS_FUNCTION(MFBoolConstructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFBOOL);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFBoolClass, GF_SG_VRML_MFBOOL);
 }
 static JSBool SMJS_FUNCTION(MFInt32Constructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFINT32);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFInt32Class, GF_SG_VRML_MFINT32);
 }
 static JSBool SMJS_FUNCTION(MFFloatConstructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFFLOAT);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFFloatClass, GF_SG_VRML_MFFLOAT);
 }
 static JSBool SMJS_FUNCTION(MFTimeConstructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFTIME);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFTimeClass, GF_SG_VRML_MFTIME);
 }
 static JSBool SMJS_FUNCTION(MFStringConstructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFSTRING);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFStringClass, GF_SG_VRML_MFSTRING);
 }
 static JSBool SMJS_FUNCTION(MFURLConstructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFURL);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFUrlClass, GF_SG_VRML_MFURL);
 }
 static JSBool SMJS_FUNCTION(MFNodeConstructor)
 {
-       MFARRAY_CONSTRUCTOR(GF_SG_VRML_MFNODE);
+       MFARRAY_CONSTRUCTOR(&js_rt->MFNodeClass, GF_SG_VRML_MFNODE);
 }
 
 
@@ -2574,7 +2603,9 @@ static void array_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call)
 {
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
 
+#ifndef USE_FFDEV_15
        JS_ObjectDestroyed(c, obj, ptr, 1);
+#endif
 
        if (!ptr) return;
 
@@ -2593,13 +2624,14 @@ static void array_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call)
        }
        gf_free(ptr);
 }
-static void array_finalize(JSContext *c, JSObject *obj)
-{
+
+static DECL_FINALIZE(array_finalize)
+
        array_finalize_ex(c, obj, 1);
 }
 
-JSBool array_getElement(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *rval)
-{
+static SMJS_FUNC_PROP_GET( array_getElement )
+
        u32 i;
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        if (SMJS_ID_IS_INT(id)) {
@@ -2607,9 +2639,9 @@ JSBool array_getElement(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *rv
                if (ptr->field.fieldType==GF_SG_VRML_MFNODE) {
                        GF_Node *node = gf_node_list_get_child(*(GF_ChildNodeItem **)ptr->field.far_ptr, i);
                        JSObject *anobj = node ? node_get_binding(JS_GetScriptStack(c), node, 0) : NULL;
-                       if (anobj) *rval = OBJECT_TO_JSVAL(anobj);
+                       if (anobj) *vp = OBJECT_TO_JSVAL(anobj);
                } else {
-                       JS_GetElement(c, ptr->js_list, (jsint) i, rval);
+                       JS_GetElement(c, ptr->js_list, (jsint) i, vp);
                }
        }
        return JS_TRUE;
@@ -2617,14 +2649,14 @@ JSBool array_getElement(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *rv
 
 
 //this could be overloaded for each MF type...
-JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rval)
-{
+static SMJS_FUNC_PROP_SET(array_setElement)
+
        u32 ind;
        jsuint len;
        jsdouble d;
        GF_JSField *from;
        JSBool ret;
-       JSClass *the_sf_class = NULL;
+       GF_JSClass *the_sf_class = NULL;
        JSString *str;
        char *str_val;
        void *sf_slot;
@@ -2695,22 +2727,22 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
 
        /*assign object*/
        if (ptr->field.fieldType==GF_SG_VRML_MFNODE) {
-               if (JSVAL_IS_VOID(*rval) || JSVAL_IS_NULL(*rval) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(*rval), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+               if (JSVAL_IS_VOID(*vp) || JSVAL_IS_NULL(*vp) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        } else if (the_sf_class) {
-               if (JSVAL_IS_VOID(*rval)) return JS_FALSE;
-               if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(*rval), the_sf_class, NULL) ) return JS_FALSE;
+               if (JSVAL_IS_VOID(*vp)) return JS_FALSE;
+               if (!GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), the_sf_class, NULL) ) return JS_FALSE;
        } else if (ptr->field.fieldType==GF_SG_VRML_MFBOOL) {
-               if (!JSVAL_IS_BOOLEAN(*rval)) return JS_FALSE;
+               if (!JSVAL_IS_BOOLEAN(*vp)) return JS_FALSE;
        } else if (ptr->field.fieldType==GF_SG_VRML_MFINT32) {
-               if (!JSVAL_IS_INT(*rval)) return JS_FALSE;
+               if (!JSVAL_IS_INT(*vp)) return JS_FALSE;
        } else if (ptr->field.fieldType==GF_SG_VRML_MFFLOAT) {
-               if (!JSVAL_IS_NUMBER(*rval)) return JS_FALSE;
+               if (!JSVAL_IS_NUMBER(*vp)) return JS_FALSE;
        } else if (ptr->field.fieldType==GF_SG_VRML_MFTIME) {
-               if (!JSVAL_IS_NUMBER(*rval)) return JS_FALSE;
+               if (!JSVAL_IS_NUMBER(*vp)) return JS_FALSE;
        } else if (ptr->field.fieldType==GF_SG_VRML_MFSTRING) {
-               if (!JSVAL_IS_STRING(*rval)) return JS_FALSE;
+               if (!JSVAL_IS_STRING(*vp)) return JS_FALSE;
        } else if (ptr->field.fieldType==GF_SG_VRML_MFURL) {
-               if (!JSVAL_IS_STRING(*rval)) return JS_FALSE;
+               if (!JSVAL_IS_STRING(*vp)) return JS_FALSE;
        }
 
 
@@ -2721,14 +2753,14 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
                if (!ptr->owner) return JS_TRUE;
 
                /*get new node*/
-               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*rval));
+               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp));
                new_n = *(GF_Node**)from->field.far_ptr;
 
 #if 0
                anobj = node_get_binding(JS_GetScriptStack(c), from->node, 0);
 
                /*add it to the new object if needed*/
-               ret = JS_SetElement(c, ptr->js_list, ind, rval);
+               ret = JS_SetElement(c, ptr->js_list, ind, vp);
 #endif
 
                /*get and delete previous node if any, but unregister later*/
@@ -2749,7 +2781,7 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
                return JS_TRUE;
        }
 
-       ret = JS_SetElement(c, ptr->js_list, ind, rval);
+       ret = JS_SetElement(c, ptr->js_list, ind, vp);
        if (ret==JS_FALSE) return JS_FALSE;
 
        if (!ptr->owner) return JS_TRUE;
@@ -2757,17 +2789,17 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
        /*rewrite MF slot*/
        switch (ptr->field.fieldType) {
        case GF_SG_VRML_MFBOOL:
-               ((MFBool *)ptr->field.far_ptr)->vals[ind] = (Bool) JSVAL_TO_BOOLEAN(*rval);
+               ((MFBool *)ptr->field.far_ptr)->vals[ind] = (Bool) JSVAL_TO_BOOLEAN(*vp);
                break;
        case GF_SG_VRML_MFINT32:
-               ((MFInt32 *)ptr->field.far_ptr)->vals[ind] = (s32) JSVAL_TO_INT(*rval);
+               ((MFInt32 *)ptr->field.far_ptr)->vals[ind] = (s32) JSVAL_TO_INT(*vp);
                break;
        case GF_SG_VRML_MFFLOAT:
-               JS_ValueToNumber(c, *rval, &d);
+               JS_ValueToNumber(c, *vp, &d);
                ((MFFloat *)ptr->field.far_ptr)->vals[ind] = FLT2FIX(d);
                break;
        case GF_SG_VRML_MFTIME:
-               JS_ValueToNumber(c, *rval, &d);
+               JS_ValueToNumber(c, *vp, &d);
                ((MFTime *)ptr->field.far_ptr)->vals[ind] = d;
                break;
        case GF_SG_VRML_MFSTRING:
@@ -2775,7 +2807,7 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
                        gf_free(((MFString *)ptr->field.far_ptr)->vals[ind]);
                        ((MFString *)ptr->field.far_ptr)->vals[ind] = NULL;
                }
-               str = JSVAL_IS_STRING(*rval) ? JSVAL_TO_STRING(*rval) : JS_ValueToString(c, *rval);
+               str = JSVAL_IS_STRING(*vp) ? JSVAL_TO_STRING(*vp) : JS_ValueToString(c, *vp);
                str_val = SMJS_CHARS_FROM_STRING(c, str);
                ((MFString *)ptr->field.far_ptr)->vals[ind] = gf_strdup(str_val);
                SMJS_FREE(c, str_val);
@@ -2786,7 +2818,7 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
                        gf_free(((MFURL *)ptr->field.far_ptr)->vals[ind].url);
                        ((MFURL *)ptr->field.far_ptr)->vals[ind].url = NULL;
                }
-               str = JSVAL_IS_STRING(*rval) ? JSVAL_TO_STRING(*rval) : JS_ValueToString(c, *rval);
+               str = JSVAL_IS_STRING(*vp) ? JSVAL_TO_STRING(*vp) : JS_ValueToString(c, *vp);
                str_val = SMJS_CHARS_FROM_STRING(c, str);
                ((MFURL *)ptr->field.far_ptr)->vals[ind].url = gf_strdup(str_val);
                ((MFURL *)ptr->field.far_ptr)->vals[ind].OD_ID = 0;
@@ -2794,19 +2826,19 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
                break;
 
        case GF_SG_VRML_MFVEC2F:
-               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*rval));
+               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp));
                gf_sg_vrml_field_copy(& ((MFVec2f *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType);
                break;
        case GF_SG_VRML_MFVEC3F:
-               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*rval));
+               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp));
                gf_sg_vrml_field_copy(& ((MFVec3f *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType);
                break;
        case GF_SG_VRML_MFROTATION:
-               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*rval));
+               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp));
                gf_sg_vrml_field_copy(& ((MFRotation *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType);
                break;
        case GF_SG_VRML_MFCOLOR:
-               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*rval));
+               from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp));
                gf_sg_vrml_field_copy(& ((MFColor *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType);
                break;
        }
@@ -2815,14 +2847,16 @@ JSBool array_setElement(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *rv
        return JS_TRUE;
 }
 
-JSBool array_setLength(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *val)
-{
+static SMJS_FUNC_PROP_SET( array_setLength)
+
        u32 len, i, sftype;
        JSBool ret;
-       JSClass *the_sf_class;
+       GF_JSClass *the_sf_class;
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
-       if (!JSVAL_IS_INT(*val) || JSVAL_TO_INT(*val) < 0) return JS_FALSE;
-       len = JSVAL_TO_INT(*val);
+       if (!JSVAL_IS_INT(*vp) || JSVAL_TO_INT(*vp) < 0) return JS_FALSE;
+       /*avoids gcc warning*/
+       if (!id) id=0;
+       len = JSVAL_TO_INT(*vp);
 
 
        if (!len) {
@@ -2864,8 +2898,9 @@ JSBool array_setLength(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *val
                        if (n) gf_node_unregister(n, ptr->owner);
                        c--;
                }
-               if (len>c)
-                       fprintf(stdout, "NOT SUPPORTED!!!\n");
+               if (len>c) {
+                       GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML] MFARRAY EXPANSION NOT SUPPORTED!!!\n"));
+               }
        }
                return JS_TRUE;
        }
@@ -2895,11 +2930,13 @@ JSBool array_setLength(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *val
        return JS_TRUE;
 }
 
-JSBool array_getLength(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *val)
-{
+static SMJS_FUNC_PROP_GET( array_getLength)
+
        JSBool ret;
        jsuint len;
        GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
+       /*avoids gcc warning*/
+       if (!id) id=0;
 
        if (ptr->field.fieldType==GF_SG_VRML_MFNODE) {
                len = gf_node_list_get_count(*(GF_ChildNodeItem **)ptr->field.far_ptr);
@@ -2907,7 +2944,7 @@ JSBool array_getLength(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *val
        } else {
                ret = JS_GetArrayLength(c, ptr->js_list, &len);
        }
-       *val = INT_TO_JSVAL(len);
+       *vp = INT_TO_JSVAL(len);
        return ret;
 }
 
@@ -2920,14 +2957,14 @@ static JSBool SMJS_FUNCTION(MFVec2fConstructor)
        u32 i;
        SMJS_ARGS
        GF_JSField *ptr = NewJSField(c);
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->MFVec2fClass)
 
        setup_js_array(c, obj, ptr, 0, 0);
        JS_SetArrayLength(c, ptr->js_list, argc);
        SMJS_SET_PRIVATE(c, obj, ptr);
 
        for (i=0; i<argc; i++) {
-               if (!JSVAL_IS_OBJECT(argv[i]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFVec2fClass, NULL) ) {
+               if (!JSVAL_IS_OBJECT(argv[i]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFVec2fClass, NULL) ) {
                        item = SMJS_CONSTRUCT_OBJECT(c, &js_rt->SFVec2fClass, obj);
                        val = OBJECT_TO_JSVAL(item);
                        JS_SetElement(c, ptr->js_list, i, &val);
@@ -2947,7 +2984,7 @@ static JSBool SMJS_FUNCTION(MFVec3fConstructor)
        u32 i;
        SMJS_ARGS
        GF_JSField *ptr;
-       SMJS_OBJ_CONSTRUCTOR    
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->MFVec3fClass)      
        
        ptr = NewJSField(c);
        ptr->field.fieldType = GF_SG_VRML_MFVEC3F;
@@ -2956,7 +2993,7 @@ static JSBool SMJS_FUNCTION(MFVec3fConstructor)
        SMJS_SET_PRIVATE(c, obj, ptr);
 
        for (i=0; i<argc; i++) {
-               if (!JSVAL_IS_OBJECT(argv[i]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFVec3fClass, NULL) ) {
+               if (!JSVAL_IS_OBJECT(argv[i]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFVec3fClass, NULL) ) {
                        item = SMJS_CONSTRUCT_OBJECT(c, &js_rt->SFVec3fClass, obj);
                        val = OBJECT_TO_JSVAL(item);
                        JS_SetElement(c, ptr->js_list, i, &val);
@@ -2976,7 +3013,7 @@ static JSBool SMJS_FUNCTION(MFRotationConstructor)
        u32 i;
        SMJS_ARGS
        GF_JSField *ptr;
-       SMJS_OBJ_CONSTRUCTOR    
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->MFRotationClass)   
        
        ptr = NewJSField(c);
        ptr->field.fieldType = GF_SG_VRML_MFROTATION;
@@ -2985,7 +3022,7 @@ static JSBool SMJS_FUNCTION(MFRotationConstructor)
        SMJS_SET_PRIVATE(c, obj, ptr);
 
        for (i=0; i<argc; i++) {
-               if (!JSVAL_IS_OBJECT(argv[i]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFRotationClass, NULL) ) {
+               if (!JSVAL_IS_OBJECT(argv[i]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFRotationClass, NULL) ) {
                        item = SMJS_CONSTRUCT_OBJECT(c, &js_rt->SFVec3fClass, obj);
                        val = OBJECT_TO_JSVAL(item);
                        JS_SetElement(c, ptr->js_list, i, &val);
@@ -3005,7 +3042,7 @@ static JSBool SMJS_FUNCTION(MFColorConstructor)
        u32 i;
        SMJS_ARGS
        GF_JSField *ptr;
-       SMJS_OBJ_CONSTRUCTOR
+       SMJS_OBJ_CONSTRUCTOR(&js_rt->MFColorClass)
 
        ptr = NewJSField(c);
        ptr->field.fieldType = GF_SG_VRML_MFCOLOR;
@@ -3014,7 +3051,7 @@ static JSBool SMJS_FUNCTION(MFColorConstructor)
        SMJS_SET_PRIVATE(c, obj, ptr);
 
        for (i=0; i<argc; i++) {
-               if (!JSVAL_IS_OBJECT(argv[i]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFColorClass, NULL) ) {
+               if (!JSVAL_IS_OBJECT(argv[i]) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[i]), &js_rt->SFColorClass, NULL) ) {
                        item = SMJS_CONSTRUCT_OBJECT(c, &js_rt->SFColorClass, obj);
                        val = OBJECT_TO_JSVAL(item);
                        JS_SetElement(c, ptr->js_list, i, &val);
@@ -3037,7 +3074,7 @@ JSBool SMJS_FUNCTION(vrml_event_add_listener)
        GF_Node *node;
        GF_JSField *ptr;
        SMJS_OBJ
-       if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (! GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        assert(ptr->field.fieldType==GF_SG_VRML_SFNODE);
        node = * ((GF_Node **)ptr->field.far_ptr);
@@ -3049,7 +3086,7 @@ JSBool SMJS_FUNCTION(vrml_event_remove_listener)
        GF_Node *node;
        GF_JSField *ptr;
        SMJS_OBJ
-       if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
+       if (! GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
        assert(ptr->field.fieldType==GF_SG_VRML_SFNODE);
        node = * ((GF_Node **)ptr->field.far_ptr);
@@ -3066,19 +3103,34 @@ static JSBool SMJS_FUNCTION(vrml_dom3_not_implemented)
 
 void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
 {
-       /*GCC port: classes are declared within code since JS_PropertyStub and co are exported symbols
-       from JS runtime lib, so with non-constant addresses*/
        JS_SETUP_CLASS(js_rt->globalClass, "global", JSCLASS_HAS_PRIVATE,
                JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
 
+
        JS_SETUP_CLASS(js_rt->AnyClass, "AnyClass", JSCLASS_HAS_PRIVATE,
          JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
 
        JS_SETUP_CLASS(js_rt->browserClass , "Browser", 0,
                JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
 
+#if 1
        JS_SETUP_CLASS(js_rt->SFNodeClass, "SFNode", JSCLASS_HAS_PRIVATE,
                node_getProperty, node_setProperty, node_finalize);
+#else
+       /*only used to debug JS_SETUP_CLASS at each of the numerous changes of JSAPI ............ */
+       memset(&js_rt->SFNodeClass, 0, sizeof(js_rt->SFNodeClass));
+       js_rt->SFNodeClass.name = "SFNode";
+       js_rt->SFNodeClass.flags = JSCLASS_HAS_PRIVATE;
+       js_rt->SFNodeClass.addProperty = JS_PropertyStub;
+       js_rt->SFNodeClass.delProperty = JS_PropertyStub;
+       js_rt->SFNodeClass.getProperty = node_getProperty;
+       js_rt->SFNodeClass.setProperty = node_setProperty;
+       js_rt->SFNodeClass.enumerate = JS_EnumerateStub;
+       js_rt->SFNodeClass.resolve = JS_ResolveStub;
+       js_rt->SFNodeClass.convert = JS_ConvertStub;
+       js_rt->SFNodeClass.finalize = node_finalize;
+       js_rt->SFNodeClass.hasInstance = gf_sg_js_has_instance;
+#endif
 
        JS_SETUP_CLASS(js_rt->SFVec2fClass , "SFVec2f", JSCLASS_HAS_PRIVATE,
          vec2f_getProperty, vec2f_setProperty, field_finalize);
@@ -3151,7 +3203,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
        JS_DefineProperty(sc->js_ctx, sc->js_obj, "NULL", JSVAL_NULL, 0, 0, JSPROP_READONLY | JSPROP_PERMANENT );
        JS_DefineProperty(sc->js_ctx, sc->js_obj, "_this", PRIVATE_TO_JSVAL(script), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT );
 
-       sc->js_browser = JS_DefineObject(sc->js_ctx, sc->js_obj, "Browser", &js_rt->browserClass, 0, 0 );
+       sc->js_browser = JS_DefineObject(sc->js_ctx, sc->js_obj, "Browser", &js_rt->browserClass._class, 0, 0 );
        JS_DefineProperty(sc->js_ctx, sc->js_browser, "_this", PRIVATE_TO_JSVAL(script), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT );
        {
                JSFunctionSpec browserFunctions[] = {
@@ -3195,7 +3247,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        {"__dummy",       0,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFNodeClass, SFNodeConstructor, 1, SFNodeProps, SFNodeMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFNodeClass, SFNodeConstructor, 1, SFNodeProps, SFNodeMethods, 0, 0);
        }
        {
                JSPropertySpec SFVec2fProps[] = {
@@ -3215,7 +3267,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        SMJS_FUNCTION_SPEC("toString",        field_toString, 0),
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFVec2fClass, SFVec2fConstructor, 0, SFVec2fProps, SFVec2fMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFVec2fClass, SFVec2fConstructor, 0, SFVec2fProps, SFVec2fMethods, 0, 0);
        }
        {
                JSPropertySpec SFVec3fProps[] = {
@@ -3237,7 +3289,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        SMJS_FUNCTION_SPEC("toString",        field_toString,   0),
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFVec3fClass, SFVec3fConstructor, 0, SFVec3fProps, SFVec3fMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFVec3fClass, SFVec3fConstructor, 0, SFVec3fProps, SFVec3fMethods, 0, 0);
        }
        {
                JSPropertySpec SFRotationProps[] = {
@@ -3257,7 +3309,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        SMJS_FUNCTION_SPEC("toString",        field_toString,   0),
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFRotationClass, SFRotationConstructor, 0, SFRotationProps, SFRotationMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFRotationClass, SFRotationConstructor, 0, SFRotationProps, SFRotationMethods, 0, 0);
        }
        {
                JSPropertySpec SFColorProps[] = {
@@ -3272,7 +3324,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        SMJS_FUNCTION_SPEC("toString",        field_toString,       0),
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFColorClass, SFColorConstructor, 0, SFColorProps, SFColorMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFColorClass, SFColorConstructor, 0, SFColorProps, SFColorMethods, 0, 0);
        }
        {
                JSPropertySpec SFImageProps[] = {
@@ -3282,7 +3334,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        {"array",   3,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0},
                        {0, 0, 0, 0, 0}
                };
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFImageClass, SFImageConstructor, 0, SFImageProps, 0, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFImageClass, SFImageConstructor, 0, SFImageProps, 0, 0, 0);
        }
 
        {
@@ -3296,23 +3348,23 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script)
                        SMJS_FUNCTION_SPEC(0, 0, 0)
                };
 
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFInt32Class, MFInt32Constructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFBoolClass, MFBoolConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFFloatClass, MFFloatConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFTimeClass, MFTimeConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFStringClass, MFStringConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFUrlClass, MFURLConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFVec2fClass, MFVec2fConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFVec3fClass, MFVec3fConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFRotationClass, MFRotationConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFColorClass, MFColorConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
-               JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFNodeClass, MFNodeConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFInt32Class, MFInt32Constructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFBoolClass, MFBoolConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFFloatClass, MFFloatConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFTimeClass, MFTimeConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFStringClass, MFStringConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFUrlClass, MFURLConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFVec2fClass, MFVec2fConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFVec3fClass, MFVec3fConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFRotationClass, MFRotationConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFColorClass, MFColorConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
+               GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFNodeClass, MFNodeConstructor, 0, MFArrayProp, MFArrayMethods, 0, 0);
        }
 
 /*
        cant get any doc specifying if these are supposed to be supported in MPEG4Script...
-       JS_InitClass(sc->js_ctx, sc->js_obj, 0, &SFVec4fClass, SFVec4fConstructor, 0, SFVec4fProps, SFVec4fMethods, 0, 0);
-       JS_InitClass(sc->js_ctx, sc->js_obj, 0, &MFVec4fClass, MFVec4fCons, 0, MFArrayProp, 0, 0, 0);
+       GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &SFVec4fClass, SFVec4fConstructor, 0, SFVec4fProps, SFVec4fMethods, 0, 0);
+       GF_JS_InitClass(sc->js_ctx, sc->js_obj, 0, &MFVec4fClass, MFVec4fCons, 0, MFArrayProp, 0, 0, 0);
 */
 
 }
@@ -3435,7 +3487,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        switch (field->fieldType) {
        case GF_SG_VRML_SFVEC2F:
        {
-               if (JS_InstanceOf(c, obj, &js_rt->SFVec2fClass, NULL) ) {
+               if (GF_JS_InstanceOf(c, obj, &js_rt->SFVec2fClass, NULL) ) {
                        p = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
                        gf_sg_vrml_field_copy(field->far_ptr, p->field.far_ptr, GF_SG_VRML_SFVEC2F);
                        Script_FieldChanged(c, owner, parent, field);
@@ -3444,7 +3496,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        }
        case GF_SG_VRML_SFVEC3F:
        {
-               if (JS_InstanceOf(c, obj, &js_rt->SFVec3fClass, NULL) ) {
+               if (GF_JS_InstanceOf(c, obj, &js_rt->SFVec3fClass, NULL) ) {
                        p = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
                        gf_sg_vrml_field_copy(field->far_ptr, p->field.far_ptr, GF_SG_VRML_SFVEC3F);
                        Script_FieldChanged(c, owner, parent, field);
@@ -3453,7 +3505,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        }
        case GF_SG_VRML_SFROTATION:
        {
-               if ( JS_InstanceOf(c, obj, &js_rt->SFRotationClass, NULL) ) {
+               if ( GF_JS_InstanceOf(c, obj, &js_rt->SFRotationClass, NULL) ) {
                        p = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
                        gf_sg_vrml_field_copy(field->far_ptr, p->field.far_ptr, GF_SG_VRML_SFROTATION);
                        Script_FieldChanged(c, owner, parent, field);
@@ -3462,7 +3514,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        }
        case GF_SG_VRML_SFCOLOR:
        {
-               if (JS_InstanceOf(c, obj, &js_rt->SFColorClass, NULL) ) {
+               if (GF_JS_InstanceOf(c, obj, &js_rt->SFColorClass, NULL) ) {
                        p = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
                        gf_sg_vrml_field_copy(field->far_ptr, p->field.far_ptr, GF_SG_VRML_SFCOLOR);
                        Script_FieldChanged(c, owner, parent, field);
@@ -3479,7 +3531,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
 
                if (JSVAL_IS_NULL(val)) {
                        Script_FieldChanged(c, owner, parent, field);
-               } else if (JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) {
+               } else if (GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) {
                        GF_Node *n = * (GF_Node**) ((GF_JSField *) SMJS_GET_PRIVATE(c, obj))->field.far_ptr;
                        * ((GF_Node **)field->far_ptr) = n;
                        gf_node_register(n, owner);
@@ -3489,7 +3541,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        }
        case GF_SG_VRML_SFIMAGE:
        {
-               if ( JS_InstanceOf(c, obj, &js_rt->SFImageClass, NULL) ) {
+               if ( GF_JS_InstanceOf(c, obj, &js_rt->SFImageClass, NULL) ) {
                        p = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
                        gf_sg_vrml_field_copy(field->far_ptr, p->field.far_ptr, GF_SG_VRML_SFIMAGE);
                        Script_FieldChanged(c, owner, parent, field);
@@ -3501,19 +3553,19 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        }
 
        //from here we handle only MF fields
-       if ( !JS_InstanceOf(c, obj, &js_rt->MFBoolClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFInt32Class, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFFloatClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFTimeClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFStringClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFUrlClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFVec2fClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFVec3fClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFRotationClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFColorClass, NULL)
-               && !JS_InstanceOf(c, obj, &js_rt->MFNodeClass, NULL)
+       if ( !GF_JS_InstanceOf(c, obj, &js_rt->MFBoolClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFInt32Class, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFFloatClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFTimeClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFStringClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFUrlClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFVec2fClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFVec3fClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFRotationClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFColorClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &js_rt->MFNodeClass, NULL)
 /*
-               && !JS_InstanceOf(c, obj, &MFVec4fClass, NULL)
+               && !GF_JS_InstanceOf(c, obj, &MFVec4fClass, NULL)
 */
                ) return;
 
@@ -3522,7 +3574,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
        JS_GetArrayLength(c, p->js_list, &len);
 
        /*special handling for MF node, reset list first*/
-       if (JS_InstanceOf(c, obj, &js_rt->MFNodeClass, NULL)) {
+       if (GF_JS_InstanceOf(c, obj, &js_rt->MFNodeClass, NULL)) {
                GF_Node *child;
                GF_ChildNodeItem *last = NULL;
                gf_node_unregister_children(owner, * (GF_ChildNodeItem **) field->far_ptr);
@@ -3534,7 +3586,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
                        if (JSVAL_IS_NULL(item)) break;
                        if (!JSVAL_IS_OBJECT(item)) break;
                        node_obj = JSVAL_TO_OBJECT(item);
-                       if ( !JS_InstanceOf(c, node_obj, &js_rt->SFNodeClass, NULL)) break;
+                       if ( !GF_JS_InstanceOf(c, node_obj, &js_rt->SFNodeClass, NULL)) break;
                        from = (GF_JSField *) SMJS_GET_PRIVATE(c, node_obj);
 
                        child = * ((GF_Node**)from->field.far_ptr);
@@ -3610,25 +3662,25 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF
                        break;
 
                case GF_SG_VRML_MFVEC2F:
-                       if ( JSVAL_IS_OBJECT(item) && JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFVec2fClass, NULL) ) {
+                       if ( JSVAL_IS_OBJECT(item) && GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFVec2fClass, NULL) ) {
                                from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(item));
                                gf_sg_vrml_field_copy(& ((MFVec2f*)field->far_ptr)->vals[i], from->field.far_ptr, GF_SG_VRML_SFVEC2F);
                        }
                        break;
                case GF_SG_VRML_MFVEC3F:
-                       if ( JSVAL_IS_OBJECT(item) && JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFVec3fClass, NULL) ) {
+                       if ( JSVAL_IS_OBJECT(item) && GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFVec3fClass, NULL) ) {
                                from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(item));
                                gf_sg_vrml_field_copy(& ((MFVec3f*)field->far_ptr)->vals[i], from->field.far_ptr, GF_SG_VRML_SFVEC3F);
                        }
                        break;
                case GF_SG_VRML_MFROTATION:
-                       if ( JSVAL_IS_OBJECT(item) && JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFRotationClass, NULL) ) {
+                       if ( JSVAL_IS_OBJECT(item) && GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFRotationClass, NULL) ) {
                                from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(item));
                                gf_sg_vrml_field_copy(& ((MFRotation*)field->far_ptr)->vals[i], from->field.far_ptr, GF_SG_VRML_SFROTATION);
                        }
                        break;
                case GF_SG_VRML_MFCOLOR:
-                       if ( JSVAL_IS_OBJECT(item) && JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFColorClass, NULL) ) {
+                       if ( JSVAL_IS_OBJECT(item) && GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(item), &js_rt->SFColorClass, NULL) ) {
                                from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(item));
                                gf_sg_vrml_field_copy(& ((MFColor*)field->far_ptr)->vals[i], from->field.far_ptr, GF_SG_VRML_SFCOLOR);
                        }
@@ -3745,7 +3797,7 @@ static void gf_sg_script_update_cached_object(GF_ScriptPriv *priv, JSObject *obj
                        too costly to handle in script*/
                        if (gf_node_list_get_count(f)==count) return;
 
-                       fprintf(stdout, "rewriting MFNode cache\n");
+                       fprintf(stderr, "rewriting MFNode cache\n");
                        while (f) {
                                slot = NULL;
                                /*first look in the original array*/
@@ -3870,23 +3922,23 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No
        switch (field->fieldType) {
     case GF_SG_VRML_SFVEC2F:
                SETUP_FIELD
-               obj = JS_NewObject(priv->js_ctx, &js_rt->SFVec2fClass, 0, priv->js_obj);
+               obj = JS_NewObject(priv->js_ctx, &js_rt->SFVec2fClass._class, 0, priv->js_obj);
                break;
     case GF_SG_VRML_SFVEC3F:
                SETUP_FIELD
-               obj = JS_NewObject(priv->js_ctx, &js_rt->SFVec3fClass, 0, priv->js_obj);
+               obj = JS_NewObject(priv->js_ctx, &js_rt->SFVec3fClass._class, 0, priv->js_obj);
                break;
     case GF_SG_VRML_SFROTATION:
                SETUP_FIELD
-               obj = JS_NewObject(priv->js_ctx, &js_rt->SFRotationClass, 0, priv->js_obj);
+               obj = JS_NewObject(priv->js_ctx, &js_rt->SFRotationClass._class, 0, priv->js_obj);
                break;
     case GF_SG_VRML_SFCOLOR:
                SETUP_FIELD
-               obj = JS_NewObject(priv->js_ctx, &js_rt->SFColorClass, 0, priv->js_obj);
+               obj = JS_NewObject(priv->js_ctx, &js_rt->SFColorClass._class, 0, priv->js_obj);
                break;
     case GF_SG_VRML_SFIMAGE:
                SETUP_FIELD
-               obj = JS_NewObject(priv->js_ctx, &js_rt->SFImageClass, 0, priv->js_obj);
+               obj = JS_NewObject(priv->js_ctx, &js_rt->SFImageClass._class, 0, priv->js_obj);
                break;
        case GF_SG_VRML_SFNODE:
                if (! *(GF_Node**) field->far_ptr)
@@ -3982,7 +4034,7 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No
                obj = SMJS_CONSTRUCT_OBJECT(priv->js_ctx, &js_rt->MFVec2fClass, priv->js_obj);
                SETUP_MF_FIELD
                for (i=0; i<f->count; i++) {
-                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFVec2fClass, 0, obj);
+                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFVec2fClass._class, 0, obj);
                        newVal = OBJECT_TO_JSVAL(pf);
                        slot = SFVec2f_Create(priv->js_ctx, pf, f->vals[i].x, f->vals[i].y);
                        slot->owner = parent;
@@ -3996,7 +4048,7 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No
                obj = SMJS_CONSTRUCT_OBJECT(priv->js_ctx, &js_rt->MFVec3fClass, priv->js_obj);
                SETUP_MF_FIELD
                for (i=0; i<f->count; i++) {
-                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFVec3fClass, 0, obj);
+                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFVec3fClass._class, 0, obj);
                        newVal = OBJECT_TO_JSVAL(pf);
                        slot = SFVec3f_Create(priv->js_ctx, pf, f->vals[i].x, f->vals[i].y, f->vals[i].z);
                        slot->owner = parent;
@@ -4010,7 +4062,7 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No
                obj = SMJS_CONSTRUCT_OBJECT(priv->js_ctx, &js_rt->MFRotationClass, priv->js_obj);
                SETUP_MF_FIELD
                for (i=0; i<f->count; i++) {
-                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFRotationClass, 0, obj);
+                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFRotationClass._class, 0, obj);
                        newVal = OBJECT_TO_JSVAL(pf);
                        slot = SFRotation_Create(priv->js_ctx, pf, f->vals[i].x, f->vals[i].y, f->vals[i].z, f->vals[i].q);
                        slot->owner = parent;
@@ -4024,7 +4076,7 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No
                obj = SMJS_CONSTRUCT_OBJECT(priv->js_ctx, &js_rt->MFColorClass, priv->js_obj);
                SETUP_MF_FIELD
                for (i=0; i<f->count; i++) {
-                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFColorClass, 0, obj);
+                       JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFColorClass._class, 0, obj);
                        newVal = OBJECT_TO_JSVAL(pf);
                        slot = SFColor_Create(priv->js_ctx, pf, f->vals[i].red, f->vals[i].green, f->vals[i].blue);
                        slot->owner = parent;
@@ -4507,6 +4559,7 @@ static void JSScript_LoadVRML(GF_Node *node)
 
        GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] Evaluating script %s\n", str));
 
+#if 1
        ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, str, strlen(str), 0, 0, &rval);
        if (ret==JS_TRUE) {
                /*call initialize if present*/
@@ -4515,6 +4568,7 @@ static void JSScript_LoadVRML(GF_Node *node)
 
                gf_js_vrml_flush_event_out(node, priv);
        }
+#endif
 
        gf_sg_lock_javascript(priv->js_ctx, 0);
 
@@ -4762,7 +4816,7 @@ GF_EXPORT
 GF_Node *gf_sg_js_get_node(JSContext *c, JSObject *obj)
 {
 #ifndef GPAC_DISABLE_VRML
-       if (js_rt && JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) {
+       if (js_rt && GF_JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) {
                GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj);
                if (ptr->field.fieldType==GF_SG_VRML_SFNODE) return * ((GF_Node **)ptr->field.far_ptr);
        }
index 7459f2689ee9e410e5e9b00523bd1ff472d17d57..03f72bc1279c55640bff91cba36b697779137540 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Graph sub-project
index c7e36e24f040653cac6b201e9d53275e1861f4b9..3ee64dfe745b9b296131fb992e2ec5269287049f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / X3D Scene Graph sub-project
index 0af4aa216364de03dd9b4b9947b41b49751f25a3..b5863ed4d96c8479d073f0d5557d4e846509d9d6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Cyril Concolato 2008 - 
+ *                     Authors: Cyril Concolato 
+ *                     Copyright (c) Telecom ParisTech 2008-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Scene Management sub-project
index 2e723772e4a753e01e3cce8c65eb12e3e9a83e83..4b3fdd27139a9a0c179c6e58f6513b8523c386b9 100644 (file)
@@ -1,8 +1,9 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Cyril Concolato - Jean Le Feuvre
- *    Copyright (c)2008-200X ENST - All rights reserved
+ *                     Authors: Jean Le Feuvre - Cyril Concolato
+ *                     Copyright (c) Telecom ParisTech 2000-2012
+ *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Scene Graph sub-project
  *
index 7c833edf317f7b6e5962345744d43c65e869f42a..be98760c7400eb77edba217dd0cdad43dbb5d9cd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -642,7 +643,7 @@ static void gf_es_check_timing(GF_Channel *ch)
        if (!ch->clock->clock_init) {
                if (!ch->clock->use_ocr) {
                        gf_clock_set_time(ch->clock, ch->CTS);
-                       GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: Forcing clock initialization at STB %d - AU DTS %d\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), ch->DTS));
+                       GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: Forcing clock initialization at STB %d - AU DTS %d CTS %d\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), ch->DTS, ch->CTS));
                        ch->IsClockInit = 1;
                } 
        }
@@ -1101,7 +1102,10 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo
        if (ch->AULength == OldLength + payload_size) EndAU = 1;
        if (EndAU) ch->NextIsAUStart = 1;
 
-       if (EndAU && !ch->IsClockInit) gf_es_check_timing(ch);
+       if (EndAU && !ch->IsClockInit && !ch->skip_time_check_for_pending) {
+               ch->skip_time_check_for_pending = 0;
+               gf_es_check_timing(ch);
+       }
 
        /* we need to skip all the packets of the current AU in the carousel scenario */
        if (ch->skip_carousel_au == 1) return;
@@ -1205,6 +1209,8 @@ void gf_es_on_eos(GF_Channel *ch)
        
        /*flush buffer*/
        ch_buffer_off(ch);
+       if (ch->len)
+               Channel_DispatchAU(ch, 0);
 
        gf_odm_on_eos(ch->odm, ch);
 }
index 88838479b71bb8d125f468896126692dbbe1a87b..b559596c9dcf74f4ac21ebc0928e0145e50a8641 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file scene part of GPAC / Media terminal sub-project
index 6fd214a46d9ea4b4f976dc6fdee4526e0fe50617..f18a4332f58c9429fa1f8a2f8873c0776954a6c9 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -60,6 +61,8 @@ GF_Codec *gf_codec_new(GF_ObjectManager *odm, GF_ESD *base_layer, s32 PL, GF_Err
 
        if (tmp->type==GF_STREAM_PRIVATE_MEDIA) tmp->type = GF_STREAM_VISUAL;
 
+       tmp->Priority = base_layer->streamPriority ? base_layer->streamPriority : 1;
+
        GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[Codec] Found decoder %s for stream type %s\n", tmp->decio ? tmp->decio->module_name : "RAW", gf_esd_get_textual_description(base_layer) ));
        return tmp;
 }
@@ -241,7 +244,6 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch)
        Also assign codec priority here*/
        if (!ch->esd->dependsOnESID || !codec->ck) {
                codec->ck = ch->clock;
-               codec->Priority = ch->esd->streamPriority;
                /*insert base layer first - note we are sure this is a stream of the same type
                as the codec (other streams - OCI, MPEG7, MPEGJ - are not added that way)*/
                return gf_list_insert(codec->inChannels, ch, 0);
@@ -383,7 +385,7 @@ check_unit:
                        cap.cap.valueInt = 0;
                        sdec->GetCapabilities(codec->decio, &cap);
                        if (!cap.cap.valueInt) {
-                               gf_term_stop_codec(codec);
+                               gf_term_stop_codec(codec, 0);
                                if ((codec->type==GF_STREAM_OD) && (codec->nb_dec_frames==1)) {
                                        /*this is just by safety, since seeking is only allowed when a single clock is present
                                        in the scene*/
@@ -510,7 +512,7 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable)
        if (codec->Muted) return GF_OK;
 
        if (codec->Status == GF_ESM_CODEC_EOS) {
-               gf_term_stop_codec(codec);
+               gf_term_stop_codec(codec, 0);
                return GF_OK;
        }
 
@@ -670,12 +672,14 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable)
                                e = mdec->ProcessData(mdec, NULL, 0, 0, CU->data, &unit_size, 0, 0);
                                if (e==GF_OK) e = UnlockCompositionUnit(codec, CU, unit_size);
                        }
-                       gf_term_stop_codec(codec);
+                       gf_term_stop_codec(codec, 0);
                        if (codec->CB) gf_cm_set_eos(codec->CB);
                }
                /*if no data, and channel not buffering, ABORT CB buffer (data timeout or EOS not detectable)*/
                else if (ch && !ch->BufferOn)
                        gf_cm_abort_buffering(codec->CB);
+
+               GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] ODM%d: No data in decoding buffer\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID));
                return GF_OK;
        }
 
@@ -687,6 +691,15 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable)
                gf_es_drop_au(ch);
                return GF_BAD_PARAM;
        }
+       /*we are still flushing our CB - keep the current pending AU and wait for CB resize*/
+       if (codec->force_cb_resize) {
+               if (codec->CB->UnitCount>1) {
+                       return GF_OK;
+               }
+               GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[%s] ODM%d: Resizing output buffer %d -> %d\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, codec->CB->UnitSize, codec->force_cb_resize));
+               ResizeCompositionBuffer(codec, codec->force_cb_resize);
+               codec->force_cb_resize=0;
+       }
 
        /*image codecs*/
        if (codec->CB->Capacity == 1) {
@@ -770,7 +783,6 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable)
 
                /*when using temporal scalability make sure we can decode*/
                if (ch->esd->dependsOnESID && (codec->last_unit_dts > AU->DTS)){
-//                     printf("SCALABLE STREAM DEAD!!\n");
                        goto drop;
                }
 
@@ -781,8 +793,10 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable)
                                AU->CTS = codec->last_unit_cts + ch->ts_offset + (u32) (codec->cur_video_frames * 1000 / codec->fps);
                        }
                }
-               if ( LockCompositionUnit(codec, AU->CTS, &CU, &unit_size) == GF_OUT_OF_MEM)
+               if ( LockCompositionUnit(codec, AU->CTS, &CU, &unit_size) == GF_OUT_OF_MEM) {
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Exit decode loop because no more space in composition buffer\n", codec->decio->module_name ));
                        return GF_OK;
+               }
 
 scalable_retry:
 
@@ -794,20 +808,30 @@ scalable_retry:
                else
                        e = mdec->ProcessData(mdec, AU->data, AU->dataLength, ch->esd->ESID, CU->data, &unit_size, AU->PaddingBits, mmlevel);
                now = gf_term_get_time(codec->odm->term) - now;
-               if (codec->Status == GF_ESM_CODEC_STOP) return GF_OK;
-
+               if (codec->Status == GF_ESM_CODEC_STOP) {
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Exit decode loop because codec has been stopped\n", codec->decio->module_name));
+                       return GF_OK;
+               }
                /*input is too small, resize composition memory*/
                switch (e) {
                case GF_BUFFER_TOO_SMALL:
                        /*release but no dispatch*/
                        UnlockCompositionUnit(codec, CU, 0);
+
+                       /*if we have pending media do wait! - this shoud be fixed by avoiding to destroy the CB ... */
+                       if (codec->CB->UnitCount>1) {
+                               GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[%s] ODM%d: Resize output buffer requested\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID));
+                               codec->force_cb_resize = unit_size;
+                               return GF_OK;
+                       }
+                       GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[%s] ODM%d: Resizing output buffer %d -> %d\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, codec->CB->UnitSize, unit_size));
                        ResizeCompositionBuffer(codec, unit_size);
                        continue;
 
                /*this happens a lot when using non-MPEG-4 streams (ex: ffmpeg demuxer)*/
                case GF_PACKED_FRAMES:
                        /*in seek don't dispatch any output*/
-                       if (mmlevel     == GF_CODEC_LEVEL_SEEK)
+                       if (mmlevel     >= GF_CODEC_LEVEL_DROP)
                                unit_size = 0;
                        e = UnlockCompositionUnit(codec, CU, unit_size);
 
@@ -885,6 +909,7 @@ drop:
 
                if (e) {
                        UnlockCompositionUnit(codec, CU, unit_size);
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Exit decode loop because error %s\n", codec->decio->module_name, gf_error_to_string(e) ));
                        return e;
                }
 
@@ -896,22 +921,25 @@ drop:
                }
 
                /*in seek don't dispatch any output*/
-               if (mmlevel     == GF_CODEC_LEVEL_SEEK)
+               if (mmlevel     >= GF_CODEC_LEVEL_DROP)
                        unit_size = 0;
 
                UnlockCompositionUnit(codec, CU, unit_size);
-               if (!ch || !AU) return GF_OK;
-
+               if (!ch || !AU) {
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Exit decode loop because no more input data\n", codec->decio->module_name));
+                       return GF_OK;
+               }
                /*escape from decoding loop only if above critical limit - this is to avoid starvation on audio*/
                if (!ch->esd->dependsOnESID && (codec->CB->UnitCount > codec->CB->Min)) {
                        now = gf_term_get_time(codec->odm->term);
                        if (now - entryTime >= TimeAvailable) {
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Exit decode loop because time is up: %d vs %d available\n", codec->decio->module_name, now - entryTime, TimeAvailable));
                                return GF_OK;
                        }
                }
                Decoder_GetNextAU(codec, &ch, &AU);
                if (!ch || !AU) return GF_OK;
-       }
+               }
        return GF_OK;
 }
 
@@ -976,7 +1004,7 @@ GF_Err gf_codec_process_ocr(GF_Codec *codec, u32 TimeAvailable)
        if (!AU || !ch) {
                /*if the codec is in EOS state, move to STOP*/
                if (codec->Status == GF_ESM_CODEC_EOS) {
-                       gf_term_stop_codec(codec);
+                       gf_term_stop_codec(codec, 0);
 #ifndef GPAC_DISABLE_VRML
                        /*if a mediacontrol is ruling this OCR*/
                        if (codec->odm->media_ctrl && codec->odm->media_ctrl->control->loop) mediacontrol_restart(codec->odm);
index a79f127c6d0558653f6abaddf57dc6c34b6cf2e1..7c60f5736f22316ba848568c03f69158112be0bb 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index 949719dc29d0acdef230df028236b5f9765bba09..7333654ccbf7d83ee36841ff07aaf0fa7a1cb003 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index d7284e776132277baa7b45f83238acc48e2d2e9c..1df75e88ff93247874fc2a5be97b532e8d75b1b7 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -223,6 +224,7 @@ void MC_GetRange(MediaControlStack *ctrl, Double *start_range, Double *end_range
        u32 i;
        Double duration;
        GF_Segment *last_seg, *prev_seg;
+
        if (gf_list_count(ctrl->seg)) {
                GF_Segment *desc = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg);
                if (!desc) {
@@ -292,7 +294,7 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy)
 
        need_restart = (stack->changed==2) ? 1 : 0;
        shall_restart = (stack->control->mediaStartTime>=0) ? 1 : 0;
-
+       
        /*check url target*/
        if (stack->stream) {
                if (MC_URLChanged(&stack->url, &stack->control->url)) {
@@ -314,6 +316,7 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy)
                                /*remove from prev*/
                                if (prev && prev->odm && (prev != stack->stream)) gf_odm_remove_mediacontrol(prev->odm, stack);
                                /*register with new*/
+                               /*if we assigned the media control to an exiting object - force the state of the object*/
                                gf_odm_set_mediacontrol((GF_ObjectManager *) stack->stream->odm, stack);
                                
                                while (gf_list_count(stack->seg)) gf_list_rem(stack->seg, 0);
@@ -389,7 +392,7 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy)
                stack->is_init = 1;
                /*the object has already been started, and media start time is not 0, restart*/
                if (stack->stream->num_open) {
-                       if (stack->media_start > 0) {
+                       if ( (stack->media_start > 0) || (gf_list_count(stack->seg)>0 ) ) {
                                mediacontrol_restart(odm);
                        } else if (stack->media_speed == 0) {
                                mediacontrol_pause(odm);
@@ -535,7 +538,12 @@ void gf_odm_remove_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl)
 {
        gf_list_del_item(odm->mc_stack, ctrl);
        /*removed. Note the spec doesn't say what to do in this case...*/
-       if (odm->media_ctrl == ctrl) gf_odm_set_mediacontrol(odm, NULL);
+       if (odm->media_ctrl == ctrl) {
+               /*we're about to release the media control from this object - if paused, force a resume (as if no MC was set)*/
+               if (ctrl->paused) 
+                       mediacontrol_resume(odm);
+               gf_odm_set_mediacontrol(odm, NULL);
+       }
 }
 
 Bool gf_odm_switch_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl)
index 0f8ef6d16fb2e726768dbcf75219b4ec77391bc9..a991e1ff4fbfde624ca59651710a9f2e37f1d6a5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index 86d753892b581da562ac3a3df427723b27b23f02..21d782d002a829b5f5ebeff5c2771efdfb3a14f0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -137,6 +138,8 @@ void gf_term_add_codec(GF_Terminal *term, GF_Codec *codec)
 
        GF_SAFEALLOC(cd, CodecEntry);
        cd->dec = codec;
+       if (!cd->dec->Priority) 
+               cd->dec->Priority = 1;
 
        cap.CapCode = GF_CODEC_WANTS_THREAD;
        cap.cap.valueInt = 0;
@@ -309,9 +312,9 @@ static u32 MM_SimulationStep_Decoder(GF_Terminal *term)
                /*avoid signaling errors too often...*/
 #ifndef GPAC_DISABLE_LOG
                if (e) {
-                       GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ODM%d] Decoding Error %s\n", ce->dec->odm->OD->objectDescriptorID, gf_error_to_string(e) ));
+                       GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODM%d] Decoding Error %s\n", ce->dec->odm->OD->objectDescriptorID, gf_error_to_string(e) ));
                } else {
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[%s] Decode time slice %d ms out of %d ms\n", ce->dec->decio ? ce->dec->decio->module_name : "RAW", time_taken, time_left ));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Decode time slice %d ms out of %d ms\n", ce->dec->decio ? ce->dec->decio->module_name : "RAW", time_taken, time_left ));
                }
 #endif
                if (ce->flags & GF_MM_CE_DISCRADED) {
@@ -415,7 +418,7 @@ u32 RunSingleDec(void *ptr)
 /*NOTE: when starting/stoping a decoder we only lock the decoder mutex, NOT the media manager. This
 avoids deadlocking in case a system codec waits for the scene graph and the compositor requests 
 a stop/start on a media*/
-void gf_term_start_codec(GF_Codec *codec)
+void gf_term_start_codec(GF_Codec *codec, Bool is_resume)
 {
        GF_CodecCapability cap;
        CodecEntry *ce;
@@ -429,13 +432,15 @@ void gf_term_start_codec(GF_Codec *codec)
        /*clean decoder memory and wait for RAP*/
        if (codec->CB) gf_cm_reset(codec->CB);
 
-       cap.CapCode = GF_CODEC_WAIT_RAP;
-       gf_codec_set_capability(codec, cap);
-
-       if (codec->decio && (codec->decio->InterfaceType == GF_SCENE_DECODER_INTERFACE)) {
-               cap.CapCode = GF_CODEC_SHOW_SCENE;
-               cap.cap.valueInt = 1;
+       if (!is_resume) {
+               cap.CapCode = GF_CODEC_WAIT_RAP;
                gf_codec_set_capability(codec, cap);
+
+               if (codec->decio && (codec->decio->InterfaceType == GF_SCENE_DECODER_INTERFACE)) {
+                       cap.CapCode = GF_CODEC_SHOW_SCENE;
+                       cap.cap.valueInt = 1;
+                       gf_codec_set_capability(codec, cap);
+               }
        }
 
        gf_codec_set_status(codec, GF_ESM_CODEC_PLAY);
@@ -455,7 +460,7 @@ void gf_term_start_codec(GF_Codec *codec)
                gf_mx_v(ce->mx);
 }
 
-void gf_term_stop_codec(GF_Codec *codec)
+void gf_term_stop_codec(GF_Codec *codec, Bool is_pause)
 {
        GF_CodecCapability cap;
        Bool locked = 0;
@@ -477,15 +482,17 @@ void gf_term_stop_codec(GF_Codec *codec)
                locked = gf_mx_try_lock(term->mm_mx);
        }
 
-       cap.CapCode = GF_CODEC_ABORT;
-       cap.cap.valueInt = 0;
-       gf_codec_set_capability(codec, cap);
-       
-       if (codec->decio && codec->odm->mo && (codec->odm->mo->flags & GF_MO_DISPLAY_REMOVE) ) {
-               cap.CapCode = GF_CODEC_SHOW_SCENE;
+       if (!is_pause) {
+               cap.CapCode = GF_CODEC_ABORT;
                cap.cap.valueInt = 0;
                gf_codec_set_capability(codec, cap);
-               codec->odm->mo->flags &= ~GF_MO_DISPLAY_REMOVE;
+               
+               if (codec->decio && codec->odm->mo && (codec->odm->mo->flags & GF_MO_DISPLAY_REMOVE) ) {
+                       cap.CapCode = GF_CODEC_SHOW_SCENE;
+                       cap.cap.valueInt = 0;
+                       gf_codec_set_capability(codec, cap);
+                       codec->odm->mo->flags &= ~GF_MO_DISPLAY_REMOVE;
+               }
        }
 
        /*set status directly and don't touch CB state*/
index 9a538b532d7cf6a89047bb837b1aeb568875a542..3903b1524c52dca717816c278dd29bcefc007f08 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index 5a2d5e32a229558fc4ee068d1d2dd0656f9125d1..508e2495fd8c0b9b35fbd19d22ed0580628105aa 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index 1c083382b829d1549b3cef629506418c864cc1b3..189dc0b2bb9e9b67a430ef283cac0dfb69ad7990 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -828,7 +829,7 @@ Bool gf_mo_url_changed(GF_MediaObject *mo, MFURL *url)
        /*special case for 3GPP text: if not playing and user node changed, force removing it*/
        if (ret && mo->odm && !mo->num_open && (mo->type == GF_MEDIA_OBJECT_TEXT)) {
                mo->flags |= GF_MO_DISPLAY_REMOVE;
-               gf_term_stop_codec(mo->odm->codec);
+               gf_term_stop_codec(mo->odm->codec, 0);
        }
        return ret;
 }
@@ -868,7 +869,7 @@ void gf_mo_set_speed(GF_MediaObject *mo, Fixed speed)
        ctrl = gf_odm_get_mediacontrol(mo->odm);
        if (ctrl) return;
 #endif
-       if (mo->odm->net_service && (mo->odm->net_service->owner->flags & GF_ODM_INHERIT_TIMELINE))
+       if (mo->odm->net_service && mo->odm->net_service->owner && (mo->odm->net_service->owner->flags & GF_ODM_INHERIT_TIMELINE))
                return;
        gf_odm_set_speed(mo->odm, speed);
 }
index 4988b47fe10460dac98f041e2dc9f6b226bb7163..40935fff9c19090f6ac4b01ab392eb764eb85808 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -115,6 +116,24 @@ void MS_Modified(GF_Node *node)
        gf_term_invalidate_compositor(st->parent->root_od->term);
 }
 
+
+static void media_sensor_activate(MediaSensorStack *media_sens, GF_Segment *desc)
+{
+       media_sens->sensor->isActive = 1;
+       gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
+       /*set info*/
+       gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING);
+       gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1);
+       media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL;
+       gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/);
+       /*set duration*/
+       media_sens->sensor->mediaDuration = desc->Duration;
+       gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
+       /*set seg start time*/
+       media_sens->sensor->streamObjectStartTime = desc->startTime;
+       gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/);
+}
+
 void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos)
 {
        GF_Segment *desc;
@@ -152,6 +171,8 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos)
 
                        if (!is_eos && !media_sens->sensor->isActive) {
                                media_sens->sensor->isActive = 1;
+                               gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
+
                                gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
                                if (odm->subscene) {
                                        media_sens->sensor->mediaDuration = (Double) (s64)odm->subscene->duration;
@@ -195,7 +216,7 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos)
 
                                        GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName));
                                }
-                               break;
+                               continue;
                        }
                        if (desc->startTime + desc->Duration < time) continue;
                        if (desc->startTime + desc->Duration == time) {
@@ -208,22 +229,11 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos)
                        }
 
                        if (!media_sens->sensor->isActive) {
-                               media_sens->sensor->isActive = 1;
-                               gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
-                               /*set info*/
-                               gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING);
-                               gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1);
-                               media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL;
-                               gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/);
-                               /*set duration*/
-                               media_sens->sensor->mediaDuration = desc->Duration;
-                               gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
-                               /*set seg start time*/
-                               media_sens->sensor->streamObjectStartTime = desc->startTime;
-                               gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/);
+                               media_sensor_activate(media_sens, desc);
 
                                GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Activating media sensor time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName));
                        }
+
                        /*set media time - relative to segment start time*/
                        time -= desc->startTime;
                        if (media_sens->sensor->mediaCurrentTime != time) {
index 6a2b55645a9dc1925eda7665c49ae3c3871b3b90..d7c0572c447f0bf73e247d1ea195e16afa004993 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -328,14 +329,15 @@ static void gf_inline_traverse(GF_Node *n, void *rs, Bool is_destroy)
 }
 
 
-static Bool gf_inline_is_hardcoded_proto(MFURL *url, GF_Config *cfg)
+static Bool gf_inline_is_hardcoded_proto(GF_Terminal *term, MFURL *url)
 {
        u32 i;
-       const char *sOpt = gf_cfg_get_key(cfg, "Systems", "hardcoded_protos");
        for (i=0; i<url->count; i++) {
                if (!url->vals[i].url) continue;
                if (strstr(url->vals[i].url, "urn:inet:gpac:builtin")) return 1;
-               if (sOpt && strstr(sOpt, url->vals[i].url)) return 1;
+
+               if (gf_sc_uri_is_hardcoded_proto(term->compositor, url->vals[i].url)) 
+                       return 1;
        }
        return 0;
 }
@@ -347,7 +349,7 @@ GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url)
        GF_Scene *scene = (GF_Scene *) _is;
        if (!scene || !lib_url->count) return NULL;
 
-       if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return GF_SG_INTERNAL_PROTO;
+       if (gf_inline_is_hardcoded_proto(scene->root_od->term, lib_url)) return GF_SG_INTERNAL_PROTO;
 
        i=0;
        while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i))) {
@@ -395,7 +397,7 @@ GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url)
        if (!lib_url || !lib_url->count) return NULL;
 
        /*internal, don't waste ressources*/
-       if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return NULL;
+       if (gf_inline_is_hardcoded_proto(scene->root_od->term, lib_url)) return NULL;
        
        i=0;
        while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i)) ) {
index 10bc92c1ed29e5a0fe0f94a15554c57ace1bc78f..3b56074fdbde0b5163621377061c18d73b8a0f3b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -218,7 +219,7 @@ static void term_on_disconnect(void *user_priv, GF_ClientService *service, LPNET
                if (service->subservice_disconnect) {
                        if (service->owner && service->subservice_disconnect==1) {
                                GF_Scene *scene = service->owner->subscene ? service->owner->subscene : service->owner->parentscene;
-                               /*destrou all media*/
+                               /*destroy all media*/
                                gf_scene_disconnect(scene, 1);
                        }
                        return;
@@ -501,7 +502,7 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo
                        }
                }
                gf_mx_v(term->mm_mx);
-//             fprintf(stdout, "Buffer occupancy %d\n", com->buffer.occupancy);
+//             fprintf(stderr, "Buffer occupancy %d\n", com->buffer.occupancy);
                if (com->buffer.occupancy==(u32) -1) com->buffer.occupancy = 0;
                return;
        }
@@ -730,7 +731,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char
                if (sPlug) sPlug = strrchr(sPlug, '"');
                if (sPlug) {
                        sPlug += 2;
-                       GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("%s:%d FOUND matching module %s\n", __FILE__, __LINE__, sPlug));
+                       GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("%s:%d FOUND matching module %s\n", __FILE__, __LINE__, sPlug));
                        ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
                        if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
                                gf_modules_close_interface((GF_BaseInterface *) ifce);
@@ -1123,7 +1124,8 @@ void gf_term_download_update_stats(GF_DownloadSession * sess)
                GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s received %d / %d\n", szURI, bytes_done, total_size));
                gf_term_service_media_event_with_download(serv->owner, GF_EVENT_MEDIA_PROGRESS, bytes_done, total_size, bytes_per_sec);
 
-               if ( (serv->download_rebuffer || serv->auto_rebuffer) && serv->owner && !(serv->owner->flags & GF_ODM_DESTROYED) && serv->owner->duration) {
+               /*JLF fix this*/
+               if (0&& (serv->download_rebuffer || serv->auto_rebuffer) && serv->owner && !(serv->owner->flags & GF_ODM_DESTROYED) && serv->owner->duration) {
                        GF_Clock *ck = gf_odm_get_media_clock(serv->owner);
                        Double download_percent, playback_percent, adj_percent;
                        download_percent = 100 * bytes_done; 
index a034b2c9ce50112361b3f2d0458f8372937a4eff..e5772a6fa282e8fc8c0077e15a8aa24686feadcd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index c0467eda93dfba2b061781b7371d79e8071b6496..da429aac0baa2a166c534d96cf341c8445e24344 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -282,7 +283,7 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove)
 void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url)
 {
        u32 od_type;
-       char *ext;
+       char *ext, *redirect_url;
        char *sub_url = (char *) service_sub_url;
        GF_Descriptor *desc;
 
@@ -334,6 +335,7 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url
                }
        }
 
+       redirect_url = NULL;
        switch (desc->tag) {
        case GF_ODF_IOD_TAG:
        {
@@ -349,6 +351,8 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url
                odm->Visual_PL = the_iod->visual_profileAndLevel;
                odm->flags |= GF_ODM_HAS_PROFILES;
                if (the_iod->inlineProfileFlag) odm->flags |= GF_ODM_INLINE_PROFILES;
+               redirect_url = the_iod->URLString;
+               odm->OD->URLString = NULL;
                gf_odf_desc_del((GF_Descriptor *) the_iod->IPMPToolList);
                gf_free(the_iod);
        }
@@ -356,6 +360,8 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url
        case GF_ODF_OD_TAG:
                odm->Audio_PL = odm->Graphics_PL = odm->OD_PL = odm->Scene_PL = odm->Visual_PL = (u8) -1;
                odm->OD = (GF_ObjectDescriptor *)desc;
+               redirect_url = odm->OD->URLString;
+               odm->OD->URLString = NULL;
                break;
        default:
                gf_term_message(odm->term, odm->net_service->url, "MPEG4 Service Setup Failure", GF_ODF_INVALID_DESCRIPTOR);
@@ -364,10 +370,17 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url
        
        gf_odm_setup_object(odm, odm->net_service);
 
+       if (redirect_url && !strnicmp(redirect_url, "views://", 8)) {
+               
+               gf_scene_generate_views(odm->subscene ? odm->subscene : odm->parentscene , (char *) redirect_url + 8, (char*)odm->parentscene ? odm->parentscene->root_od->net_service->url : NULL);
+       }
        /*it may happen that this object was inserted in a dynamic scene from a service through a URL redirect. In which case, 
        the scene regeneration might not have been completed since the redirection was not done yet - force a scene regenerate*/
-       if (odm->parentscene && odm->parentscene->is_dynamic_scene)
+       else if (odm->parentscene && odm->parentscene->is_dynamic_scene)
                gf_scene_regenerate(odm->parentscene);
+
+
+       gf_free(redirect_url);
        return;
 
 err_exit:
@@ -377,6 +390,8 @@ err_exit:
                evt.connect.is_connected = 0;
                gf_term_send_event(odm->term, &evt);
        }
+       if (redirect_url)
+               gf_free(redirect_url);
 
 }
 
@@ -591,6 +606,7 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv)
        if (odm->OD->URLString) {
                GF_ClientService *parent = odm->net_service;
                char *url = odm->OD->URLString;
+               char *parent_url = NULL;
                odm->OD->URLString = NULL;
                /*store original OD ID */
                if (!odm->current_time) odm->current_time = odm->OD->objectDescriptorID;
@@ -608,7 +624,11 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv)
                        odm->subscene = gf_scene_new(odm->parentscene);
                        odm->subscene->root_od = odm;
                }
-               gf_term_post_connect_object(odm->term, odm, url, parent ? parent->url : NULL);
+               parent_url = parent ? parent->url : NULL;
+               if (parent_url && !strnicmp(parent_url, "views://", 8))
+                       parent_url = NULL;
+
+               gf_term_post_connect_object(odm->term, odm, url, parent_url);
                gf_free(url);
                gf_term_lock_net(odm->term, 0);
                return;
@@ -744,7 +764,7 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv)
                }
                if (force_play) {
                        odm->flags |= GF_ODM_INITIAL_BROADCAST_PLAY;
-                       GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] Inserted from broadcast - forcing play\n", odm->OD->objectDescriptorID));
+                       GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] Inserted from broadcast or input service - forcing play\n", odm->OD->objectDescriptorID));
                        gf_odm_start(odm, 2);
                }
        }
@@ -1187,7 +1207,7 @@ GF_Err gf_odm_post_es_setup(GF_Channel *ch, GF_Codec *dec, GF_Err had_err)
                com.play.start_range /= 1000;
                com.play.end_range = -1.0;
                gf_term_service_command(ch->service, &com);
-               if (dec && (dec->Status!=GF_ESM_CODEC_PLAY)) gf_term_start_codec(dec);
+               if (dec && (dec->Status!=GF_ESM_CODEC_PLAY)) gf_term_start_codec(dec, 0);
                gf_term_lock_net(ch->odm->term, 0);
        }
        return GF_OK;
@@ -1354,6 +1374,7 @@ void gf_odm_play(GF_ObjectManager *odm)
        u32 nb_failure;
        u64 range_end;
        Bool skip_od_st;
+       Bool media_control_paused = 0;
        GF_NetworkCommand com;
 #ifndef GPAC_DISABLE_VRML
        MediaControlStack *ctrl;
@@ -1449,6 +1470,8 @@ void gf_odm_play(GF_ObjectManager *odm)
                        if ((ch->esd->ESID!=ch->clock->clockID) && (ck_time>com.play.start_range) && (com.play.end_range>com.play.start_range) && (ck_time<com.play.end_range)) {
                                com.play.start_range = ck_time;
                        }
+                       if (ctrl->paused) media_control_paused = 1;
+
                        gf_clock_set_speed(ch->clock, ctrl->control->mediaSpeed);
                        /*if requested seek time AND media control, adjust start range to current play time*/
                        if (odm->media_start_time) {
@@ -1504,20 +1527,23 @@ void gf_odm_play(GF_ObjectManager *odm)
 
        /*start codecs last (otherwise we end up pulling data from channels not yet connected->pbs when seeking)*/
        if (odm->codec) {
-               gf_term_start_codec(odm->codec);
+               gf_term_start_codec(odm->codec, 0);
        } else if (odm->subscene) {
-               if (odm->subscene->scene_codec) gf_term_start_codec(odm->subscene->scene_codec);
-               if (!skip_od_st && odm->subscene->od_codec) gf_term_start_codec(odm->subscene->od_codec);
+               if (odm->subscene->scene_codec) gf_term_start_codec(odm->subscene->scene_codec, 0);
+               if (!skip_od_st && odm->subscene->od_codec) gf_term_start_codec(odm->subscene->od_codec, 0);
 
                if (odm->flags & GF_ODM_REGENERATE_SCENE) {
                        odm->flags &= ~GF_ODM_REGENERATE_SCENE;
                        gf_scene_regenerate(odm->subscene);
                }
        }
-       if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec);
+       if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec, 0);
 #ifndef GPAC_MINIMAL_ODF
-       if (odm->oci_codec) gf_term_start_codec(odm->oci_codec);
+       if (odm->oci_codec) gf_term_start_codec(odm->oci_codec, 0);
 #endif
+
+       if (media_control_paused)
+               gf_odm_pause(odm);
 }
 
 Bool gf_odm_owns_clock(GF_ObjectManager *odm, GF_Clock *ck) 
@@ -1578,7 +1604,7 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close)
                while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) {
                        gf_es_stop(ch);
                }
-               gf_term_stop_codec(odm->codec);
+               gf_term_stop_codec(odm->codec, 0);
                /*and wait until frame has been consumed by the renderer
                we don't use semaphore wait as the raw channel may already be pending on the semaphore*/
                while (odm->codec->CB->UnitCount) {
@@ -1597,21 +1623,21 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close)
        if (force_close && odm->mo) odm->mo->flags |= GF_MO_DISPLAY_REMOVE;
        /*stop codecs*/
        if (odm->codec) {
-               gf_term_stop_codec(odm->codec);
+               gf_term_stop_codec(odm->codec, 0);
        } else if (odm->subscene) {
                u32 i=0;
                GF_ObjectManager *sub_odm;
-               if (odm->subscene->scene_codec) gf_term_stop_codec(odm->subscene->scene_codec);
-               if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec);
+               if (odm->subscene->scene_codec) gf_term_stop_codec(odm->subscene->scene_codec, 0);
+               if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec, 0);
 
                /*stops all resources of the subscene as well*/
                while ((sub_odm=(GF_ObjectManager *)gf_list_enum(odm->subscene->resources, &i))) {
                        gf_odm_stop(sub_odm, force_close);
                }
        }
-       if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec);
+       if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec, 0);
 #ifndef GPAC_MINIMAL_ODF
-       if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec);
+       if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec, 0);
 #endif
 
 //     gf_term_lock_net(odm->term, 1);
@@ -1780,18 +1806,18 @@ void gf_odm_pause(GF_ObjectManager *odm)
 
        /*stop codecs, and update status for media codecs*/
        if (odm->codec) {
-               gf_term_stop_codec(odm->codec);
+               gf_term_stop_codec(odm->codec, 1);
                gf_codec_set_status(odm->codec, GF_ESM_CODEC_PAUSE);
        } else if (odm->subscene) {
                if (odm->subscene->scene_codec) {
                        gf_codec_set_status(odm->subscene->scene_codec, GF_ESM_CODEC_PAUSE);
-                       gf_term_stop_codec(odm->subscene->scene_codec);
+                       gf_term_stop_codec(odm->subscene->scene_codec, 1);
                }
-               if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec);
+               if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec, 1);
        }
-       if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec);
+       if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec, 1);
 #ifndef GPAC_MINIMAL_ODF
-       if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec);
+       if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec, 1);
 #endif
 
        com.command_type = GF_NET_CHAN_PAUSE;
@@ -1800,6 +1826,7 @@ void gf_odm_pause(GF_ObjectManager *odm)
                gf_clock_pause(ch->clock);
                com.base.on_channel = ch;
                gf_term_service_command(ch->service, &com);
+               GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH%d: At OTB %d requesting PAUSE (clock init %d)\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock), ch->clock->clock_init ));
        }
 
 #ifndef GPAC_DISABLE_VRML
@@ -1822,6 +1849,7 @@ void gf_odm_resume(GF_ObjectManager *odm)
        GF_Channel *ch;
 #ifndef GPAC_DISABLE_VRML
        MediaSensorStack *media_sens;
+       MediaControlStack *ctrl;
 #endif
 
        if (odm->flags & GF_ODM_NO_TIME_CTRL) return;
@@ -1829,26 +1857,33 @@ void gf_odm_resume(GF_ObjectManager *odm)
 
        /*start codecs, and update status for media codecs*/
        if (odm->codec) {
-               gf_term_start_codec(odm->codec);
+               gf_term_start_codec(odm->codec, 1);
                gf_codec_set_status(odm->codec, GF_ESM_CODEC_PLAY);
        } else if (odm->subscene) {
                if (odm->subscene->scene_codec) {
                        gf_codec_set_status(odm->subscene->scene_codec, GF_ESM_CODEC_PLAY);
-                       gf_term_start_codec(odm->subscene->scene_codec);
+                       gf_term_start_codec(odm->subscene->scene_codec, 1);
                }
-               if (odm->subscene->od_codec) gf_term_start_codec(odm->subscene->od_codec);
+               if (odm->subscene->od_codec) gf_term_start_codec(odm->subscene->od_codec, 1);
        }
-       if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec);
+       if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec, 1);
 #ifndef GPAC_MINIMAL_ODF
-       if (odm->oci_codec) gf_term_start_codec(odm->oci_codec);
+       if (odm->oci_codec) gf_term_start_codec(odm->oci_codec, 1);
 #endif
 
+       ctrl = gf_odm_get_mediacontrol(odm);
        com.command_type = GF_NET_CHAN_RESUME;
        i=0;
        while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ){
                gf_clock_resume(ch->clock);
                com.base.on_channel = ch;
                gf_term_service_command(ch->service, &com);
+               GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH%d: At OTB %d requesting RESUME (clock init %d)\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock), ch->clock->clock_init ));
+
+               /*override speed with MC*/
+               if (ctrl) {
+                       gf_clock_set_speed(ch->clock, ctrl->control->mediaSpeed);
+               }
        }
 
 #ifndef GPAC_DISABLE_VRML
index ef8e6b3a80c4b9c66603f762fcbcd3faa01ab55f..64cfe1ff9c3478dbc9b00eec9ff2f64f5549629f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -270,6 +271,7 @@ void gf_scene_disconnect(GF_Scene *scene, Bool for_shutdown)
        if (dec && dec->ReleaseScene) dec->ReleaseScene(dec);
        gf_sg_reset(scene->graph);
        scene->graph_attached = 0;
+       scene->simulation_time = 0;
        
 
        /*reset statc ressource flag since we destroyed scene objects*/
@@ -1545,9 +1547,10 @@ GF_SceneGraph *gf_scene_enum_extra_scene(GF_SceneGraph *sg, u32 *i)
 
 #define USE_TEXTURES   0
 
-void gf_scene_generate_views(GF_Scene *scene, char *url)
+void gf_scene_generate_views(GF_Scene *scene, char *url, char *parent_path)
 {
        char *url_search;
+       Bool use_old_syntax = 1;
        GF_Node *n1, *switcher;
 #if USE_TEXTURES
        GF_Node *n2;
@@ -1568,16 +1571,24 @@ void gf_scene_generate_views(GF_Scene *scene, char *url)
        gf_node_list_add_child( &((GF_ParentNode *)n1)->children, switcher);
        ((M_Switch*)switcher)->whichChoice = -2;
 
+       if (strstr(url, "::")) use_old_syntax = 0;
+
        url_search = url;
        while (1) {
-               char *sep = strchr(url_search, ':');
-               /*if :// or :\ is found, skip it*/
-               if (sep && ( ((sep[1] == '/') && (sep[2] == '/')) || (sep[1] == '\\') ) ) {
-                       url_search = sep+1;
-                       continue;
+               char *sep;
+               
+               if (use_old_syntax) {
+                       sep = strchr(url_search, ':');
+                       /*if :// or :\ is found, skip it*/
+                       if (sep && ( ((sep[1] == '/') && (sep[2] == '/')) || (sep[1] == '\\') ) ) {
+                               url_search = sep+1;
+                               continue;
+                       }
+               } else {
+                       sep = strstr(url_search, "::");
                }
-
                if (sep) sep[0] = 0;
+
 #if USE_TEXTURES
                /*create a shape and bitmap node*/
                n2 = is_create_node(scene->graph, TAG_MPEG4_Shape, NULL);
@@ -1600,7 +1611,7 @@ void gf_scene_generate_views(GF_Scene *scene, char *url)
 
                gf_sg_vrml_mf_reset(&mt->url, GF_SG_VRML_MFURL);
                gf_sg_vrml_mf_append(&mt->url, GF_SG_VRML_MFURL, NULL);
-               mt->url.vals[0].url = gf_strdup(url);
+               mt->url.vals[0].url = gf_url_concatenate(parent_path, url);
 #else
                inl = (M_Inline *) is_create_node(scene->graph, TAG_MPEG4_Inline, NULL);
                gf_node_list_add_child( &((M_Switch *)switcher)->choice, (GF_Node *)inl);
@@ -1608,12 +1619,16 @@ void gf_scene_generate_views(GF_Scene *scene, char *url)
 
                gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL);
                gf_sg_vrml_mf_append(&inl->url, GF_SG_VRML_MFURL, NULL);
-               inl->url.vals[0].url = gf_strdup(url);
+               inl->url.vals[0].url = gf_url_concatenate(parent_path, url);
 #endif
 
                if (!sep) break;
                sep[0] = ':';
-               url = sep+1;
+               if (use_old_syntax) {
+                       url = sep+1;
+               } else {
+                       url = sep+2;
+               }
                url_search = url;
        }
 
index 3c89af8513454bd290c758ad12c751d8ec7ae9ee..9fa8b06b4a3206e99ffd75b660520ab91c2b54c6 100644 (file)
@@ -2,7 +2,7 @@
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Cyril Concolato - Jean le Feuvre
- *                             Copyright (c) 2005-200X ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / SVG Rendering sub-project
index 7f4556fe246d1caf4abb0d0bb4ea14631b61b503..75502bc97f7bb6f22c785ee8e03d9b103b854234 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
index b68b30805d8a9481adfeb22be6cdbe071e724b39..062010a45c4be2ab393294972af28a7c66935fea 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / Media terminal sub-project
@@ -465,9 +466,10 @@ static void gf_term_connect_from_time_ex(GF_Terminal * term, const char *URL, u6
 
        if (!strnicmp(URL, "views://", 8)) {
                odm->OD = (GF_ObjectDescriptor *)gf_odf_desc_new(GF_ODF_OD_TAG);
-               gf_scene_generate_views(term->root_scene, (char *) URL+8);
+               gf_scene_generate_views(term->root_scene, (char *) URL+8, (char*)parent_path);
                return;
        }
+
        /*connect - we don't have any parentID */
        gf_term_connect_object(term, odm, (char *) URL, (char*)parent_path);
 }
index 83bf5cff0a354097584070134b495e413750626e..616ef2b610767cf3bedf0e1d64d526589f4e9a98 100644 (file)
@@ -3,7 +3,6 @@
  *
  *          Authors: Romain Bouqueau - Jean Le Feuvre
  *                     Copyright (c) Telecom ParisTech 2010-20XX 
- *                    
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -299,37 +298,44 @@ static void *(*gf_mem_realloc_proto)(void *ptr, size_t size, char *filename, int
 static void (*gf_mem_free_proto)(void *ptr, char *filename, int line) = gf_mem_free_basic;
 static char *(*gf_mem_strdup_proto)(const char *str, char *filename, int line) = gf_mem_strdup_basic;
 
-SYMBOL_EXPORT CDECL
-void *gf_mem_malloc(size_t size, char *filename, int line)
+#ifndef MY_GF_EXPORT
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define GF_EXPORT __attribute__((visibility("default")))
+#else
+/*use def files for windows or let compiler decide*/
+#define MY_GF_EXPORT
+#endif
+#endif
+
+MY_GF_EXPORT void *gf_mem_malloc(size_t size, char *filename, int line)
 {
        return gf_mem_malloc_proto(size, filename, line);
 }
 
-SYMBOL_EXPORT CDECL
-void *gf_mem_calloc(size_t num, size_t size_of, char *filename, int line)
+MY_GF_EXPORT void *gf_mem_calloc(size_t num, size_t size_of, char *filename, int line)
 {
        return gf_mem_calloc_proto(num, size_of, filename, line);
 }
 
-SYMBOL_EXPORT CDECL
+MY_GF_EXPORT 
 void *gf_mem_realloc(void *ptr, size_t size, char *filename, int line)
 {
        return gf_mem_realloc_proto(ptr, size, filename, line);
 }
 
-SYMBOL_EXPORT CDECL
+MY_GF_EXPORT 
 void gf_mem_free(void *ptr, char *filename, int line)
 {
        gf_mem_free_proto(ptr, filename, line);
 }
 
-SYMBOL_EXPORT CDECL
+MY_GF_EXPORT 
 char *gf_mem_strdup(const char *str, char *filename, int line)
 {
        return gf_mem_strdup_proto(str, filename, line);
 }
 
-CDECL
+MY_GF_EXPORT 
 void gf_mem_enable_tracker()
 {
        gf_mem_malloc_proto = gf_mem_malloc_tracker;
index 3f8907c9a2084fbdd943b9d8614cdb494f2a4fb0..cb92a1b4892d392beb0cf2706b30ad97fbafea01 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -132,11 +133,6 @@ u32 gf_base64_decode(char *in_buf, u32 inSize, char *out, u32 outSize)
        return j;
 }
 
-
-/*
- *                     Copyright (c) ENST 2004  - Philippe de Cuetos 
- */
-
 static const char base_16[] = "0123456789abcdef";
 
 GF_EXPORT
@@ -269,4 +265,4 @@ GF_Err gf_gz_decompress_payload(char *data, u32 data_len, char **uncompressed_da
                *uncompressed_data = NULL;
        }
        return e;
-}
\ No newline at end of file
+}
index 509185065523d3365dbe7f4dbd0f4ec247446ef2..f59fcf70fbba8d9138bf9f48842c23e1d1fdbfa6 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -56,6 +57,10 @@ struct __tag_bitstream
 
        void (*EndOfStream)(void *par);
        void *par;
+
+
+       char *buffer_io;
+       u32 buffer_io_size, buffer_written;
 };
 
 
@@ -137,12 +142,47 @@ GF_BitStream *gf_bs_from_file(FILE *f, u32 mode)
        return tmp;
 }
 
+static void bs_flush_cache(GF_BitStream *bs)
+{
+       if (bs->buffer_written) {
+               u32 nb_write = fwrite(bs->buffer_io, 1, bs->buffer_written, bs->stream);
+               bs->size += nb_write;
+               bs->position += nb_write;
+               bs->buffer_written = 0;
+       }
+}
+
+
+GF_EXPORT
+GF_Err gf_bs_set_output_buffering(GF_BitStream *bs, u32 size)
+{
+       if (!bs->stream) return GF_OK;
+       if (bs->bsmode != GF_BITSTREAM_FILE_WRITE) {
+               return GF_OK;
+       }
+       bs_flush_cache(bs);
+       bs->buffer_io = gf_realloc(bs->buffer_io, size);
+       if (!bs->buffer_io) return GF_IO_ERR;
+       bs->buffer_io_size = size;
+       bs->buffer_written = 0;
+       return GF_OK;
+}
+
+
+GF_EXPORT
+u32 gf_bs_get_output_buffering(GF_BitStream *bs)
+{
+       return bs ? bs->buffer_io_size : 0;
+}
+
 GF_EXPORT
 void gf_bs_del(GF_BitStream *bs)
 {
        if (!bs) return;
        /*if we are in dynamic mode (alloc done by the bitstream), free the buffer if still present*/
        if ((bs->bsmode == GF_BITSTREAM_WRITE_DYN) && bs->original) gf_free(bs->original);
+       if (bs->buffer_io)
+               bs_flush_cache(bs);
        gf_free(bs);
 }
 
@@ -170,6 +210,9 @@ static u8 BS_ReadByte(GF_BitStream *bs)
                }
                return (u32) bs->original[bs->position++];
        }
+       if (bs->buffer_io) 
+               bs_flush_cache(bs);
+
        /*we are in FILE mode, test for end of file*/
        if (!feof(bs->stream)) {
                bs->position++;
@@ -336,6 +379,8 @@ u32 gf_bs_read_data(GF_BitStream *bs, char *data, u32 nbBytes)
                        return nbBytes;
                case GF_BITSTREAM_FILE_READ:
                case GF_BITSTREAM_FILE_WRITE:
+                       if (bs->buffer_io) 
+                               bs_flush_cache(bs);
                        nbBytes = fread(data, 1, nbBytes, bs->stream);
                        bs->position += nbBytes;
                        return nbBytes;
@@ -374,6 +419,14 @@ static void BS_WriteByte(GF_BitStream *bs, u8 val)
                bs->position++;
                return;
        }
+       if (bs->buffer_io && (bs->buffer_written<bs->buffer_io_size)) {
+               bs->buffer_io[bs->buffer_written] = val;
+               bs->buffer_written++;
+               if (bs->buffer_written == bs->buffer_io_size) {
+                       bs_flush_cache(bs);
+               }
+               return;
+       }
        /*we are in FILE mode, no pb for any gf_realloc...*/
        fputc(val, bs->stream);
        /*check we didn't rewind the stream*/
@@ -462,7 +515,7 @@ void gf_bs_write_u64(GF_BitStream *bs, u64 value)
 GF_EXPORT
 u32 gf_bs_write_byte(GF_BitStream *bs, u8 byte, u32 repeat_count)
 {
-       if (!BS_IsAlign(bs)) {
+       if (!BS_IsAlign(bs) || bs->buffer_io) {
                u32 count = 0;
                while (count<repeat_count) {
                        gf_bs_write_int(bs, byte, 8);
@@ -493,6 +546,7 @@ u32 gf_bs_write_byte(GF_BitStream *bs, u8 byte, u32 repeat_count)
                return repeat_count;
        case GF_BITSTREAM_FILE_READ:
        case GF_BITSTREAM_FILE_WRITE:
+
                if (gf_fwrite(&byte, 1, repeat_count, bs->stream) != repeat_count) return 0;
                if (bs->size == bs->position) bs->size += repeat_count;
                bs->position += repeat_count;
@@ -564,6 +618,18 @@ u32 gf_bs_write_data(GF_BitStream *bs, const char *data, u32 nbBytes)
                        return nbBytes;
                case GF_BITSTREAM_FILE_READ:
                case GF_BITSTREAM_FILE_WRITE:
+                       if (bs->buffer_io) {
+                               if (bs->buffer_written + nbBytes > bs->buffer_io_size) {
+                                       bs_flush_cache(bs);
+                                       if (nbBytes>bs->buffer_io_size) {
+                                               bs->buffer_io = gf_realloc(bs->buffer_io, 2*nbBytes);
+                                               bs->buffer_io_size = 2*nbBytes;
+                                       }
+                               }
+                               memcpy(bs->buffer_io+bs->buffer_written, data, nbBytes);
+                               bs->buffer_written+=nbBytes;
+                               return nbBytes;
+                       }
                        if (gf_fwrite(data, nbBytes, 1, bs->stream) != 1) return 0;
                        if (bs->size == bs->position) bs->size += nbBytes;
                        bs->position += nbBytes;
@@ -622,6 +688,9 @@ u64 gf_bs_available(GF_BitStream *bs)
        /*FILE READ: assume size hasn't changed, otherwise the user shall call gf_bs_get_refreshed_size*/
        if (bs->bsmode==GF_BITSTREAM_FILE_READ) return (bs->size - bs->position);
 
+       if (bs->buffer_io)
+               bs_flush_cache(bs);
+
        cur = gf_f64_tell(bs->stream);
        gf_f64_seek(bs->stream, 0, SEEK_END);
        end = gf_f64_tell(bs->stream);
@@ -686,6 +755,8 @@ void gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes)
        
        /*special case for file skipping...*/
        if ((bs->bsmode == GF_BITSTREAM_FILE_WRITE) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) {
+               if (bs->buffer_io)
+                       bs_flush_cache(bs);
                gf_f64_seek(bs->stream, nbBytes, SEEK_CUR);
                bs->position += nbBytes;
                return;
@@ -743,6 +814,9 @@ static GF_Err BS_SeekIntern(GF_BitStream *bs, u64 offset)
                return GF_OK;
        }
 
+       if (bs->buffer_io)
+               bs_flush_cache(bs);
+
        gf_f64_seek(bs->stream, offset, SEEK_SET);
 
        bs->position = offset;
@@ -800,6 +874,8 @@ u64 gf_bs_get_refreshed_size(GF_BitStream *bs)
                return bs->size;
 
        default:
+               if (bs->buffer_io)
+                       bs_flush_cache(bs);
                offset = gf_f64_tell(bs->stream);
                gf_f64_seek(bs->stream, 0, SEEK_END);
                bs->size = gf_f64_tell(bs->stream);
@@ -811,12 +887,16 @@ u64 gf_bs_get_refreshed_size(GF_BitStream *bs)
 GF_EXPORT
 u64 gf_bs_get_size(GF_BitStream *bs)
 {
+       if (bs->buffer_io)
+               return bs->size + bs->buffer_written;
        return bs->size;
 }
 
 GF_EXPORT
 u64 gf_bs_get_position(GF_BitStream *bs)
 {
+       if (bs->buffer_io)
+               return bs->position + bs->buffer_written;
        return bs->position;
 }
 
index 56a84715298ded64897ffed921e5d1e9174d079b..7b08685a3e2d88c6a919f6f61d6f6f1dc06f2654 100644 (file)
@@ -1,8 +1,8 @@
 /*
 *                                      GPAC Multimedia Framework
 *
-*                      Authors: Jean Le Feuvre
-*                              Copyright (c) 2005-2005 ENST
+ *                     Authors: Pierre Souchay, Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2010-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / common tools sub-project
index 75534af60d069e25820f430b95efb5dbb2f3c068..edbbe9c5933c1ce8b2c83bb03b2f8d34a5e1d593 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
 #include <gpac/color.h>
 
 
-/* original YUV table code from XviD colorspace module */
-
-/*****************************************************************************
- *
- *  XVID MPEG-4 VIDEO CODEC
- *  - colorspace conversion module -
- *
- *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
- *               2002 Michael Militzer <isibaar@xvid.org>
- *
- *  follows the usual GPL license terms
- ****************************************************************************/
+/* YUV -> RGB conversion loading two lines at each call */
 
 #define col_clip(a) MAX(0, MIN(255, a))
+#define SCALEBITS_OUT  13
+#define FIX_OUT(x)             ((unsigned short) ((x) * (1L<<SCALEBITS_OUT) + 0.5))
 
 static s32 RGB_Y[256];
 static s32 B_U[256];
@@ -49,19 +41,14 @@ static s32 G_U[256];
 static s32 G_V[256];
 static s32 R_V[256];
 
-#define SCALEBITS_OUT  13
-#define FIX_OUT(x)             ((unsigned short) ((x) * (1L<<SCALEBITS_OUT) + 0.5))
-
-
-static s32 is_init = 0;
 
-/**/
+static s32 yuv2rgb_is_init = 0;
 static void yuv2rgb_init(void)
 {
        s32 i;
-       if (is_init) return;
+       if (yuv2rgb_is_init) return;
+       yuv2rgb_is_init = 1;
 
-       is_init = 1;
        for(i = 0; i < 256; i++) {
                RGB_Y[i] = FIX_OUT(1.164) * (i - 16);
                B_U[i] = FIX_OUT(2.018) * (i - 128);
index 97a5e9819ddbbb90a42a0cfc72e09af105ba0cb8..c502d4f8da2caf3689e38e2c34ff2b715aa2a950 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -22,7 +23,7 @@
  *
  */
 
-#include <gpac/module.h>
+#include <gpac/config_file.h>
 #include <gpac/list.h>
 
 #define MAX_INI_LINE                   2046
@@ -200,6 +201,11 @@ GF_Config *gf_cfg_new(const char *filePath, const char* file_name)
 {
        GF_Config *tmp = (GF_Config *)gf_malloc(sizeof(GF_Config));
        memset((void *)tmp, 0, sizeof(GF_Config));
+       if (!filePath && !file_name) {
+               tmp->sections = gf_list_new();
+               return tmp;
+       }
+
        if (gf_cfg_parse_config_file(tmp, filePath, file_name)){
            gf_free( tmp );
            tmp = NULL;
@@ -224,6 +230,7 @@ GF_Err gf_cfg_save(GF_Config *iniFile)
        FILE *file;
 
        if (!iniFile->hasChanged) return GF_OK;
+       if (!iniFile->fileName) return GF_OK;
 
        file = gf_f64_open(iniFile->fileName, "wt");
        if (!file) return GF_IO_ERR;
index b297cb146e514094115beb288a63e276339347ef..bf8f1ffc5ff0eb9a5d2099db24dd881c7f13d79c 100644 (file)
@@ -2,7 +2,7 @@
  *                                     GPAC Multimedia Framework
  *
  *                     Authors: Jean Le Feuvre
- *                             Copyright (c) 2005-2005 ENST
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -50,7 +50,7 @@
 #define SESSION_RETRY_COUNT    20
 
 #define GF_DOWNLOAD_AGENT_NAME         "GPAC/" GPAC_FULL_VERSION
-#define GF_DOWNLOAD_BUFFER_SIZE                8192
+#define GF_DOWNLOAD_BUFFER_SIZE                8193
 #define GF_WAIT_REPLY_SLEEP    20
 
 
@@ -650,18 +650,8 @@ void gf_dm_sess_del(GF_DownloadSession *sess)
     }
 
     if (sess->dm) gf_list_del_item(sess->dm->sessions, sess);
-    /*
-             TODO: something to clean an cache files ?
-       if (sess->cache_name && !sess->use_cache_extension && !(sess->flags & GF_NETIO_SESSION_KEEP_CACHE) ) {
-            if (sess->dm)
-                opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "CleanCache");
-            else
-                opt = NULL;
-            if (!opt || !stricmp(opt, "yes")) gf_delete_file(sess->cache_name);
-               gf_free(sess->cache_name);
-       }
-    */
-    gf_dm_remove_cache_entry_from_session(sess);
+
+       gf_dm_remove_cache_entry_from_session(sess);
     sess->cache_entry = NULL;
     if (sess->orig_url) gf_free(sess->orig_url);
     if (sess->orig_url_before_redirect) gf_free(sess->orig_url_before_redirect);
@@ -673,6 +663,8 @@ void gf_dm_sess_del(GF_DownloadSession *sess)
     if (sess->init_data) gf_free(sess->init_data);
     sess->orig_url = sess->server_name = sess->remote_path;
     sess->creds = NULL;
+       if (sess->sock) 
+               gf_sk_del(sess->sock);
     gf_free(sess);
     GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[Downloader] gf_dm_sess_del(%p) : DONE\n", sess ));
 }
@@ -1052,51 +1044,66 @@ static GF_Err gf_dm_read_data(GF_DownloadSession *sess, char *data, u32 data_siz
         return GF_BAD_PARAM;
 #ifdef GPAC_HAS_SSL
     if (sess->ssl) {
-        u32 size = SSL_read(sess->ssl, data, data_size);
-        e = GF_OK;
-        data[size] = 0;
-        if (!size) e = GF_IP_NETWORK_EMPTY;
-        *out_read = size;
-    } else
+        s32 size = SSL_read(sess->ssl, data, data_size);
+        if (size < 0) 
+                       e = GF_IO_ERR;
+        else if (!size) 
+                       e = GF_IP_NETWORK_EMPTY;
+               else {
+                       e = GF_OK;
+               data[size] = 0;
+                   *out_read = size;
+               }
+           return e;
+    } 
 #endif
-        if (!sess->sock)
-            return GF_NETIO_DISCONNECTED;
-    e = gf_sk_receive(sess->sock, data, data_size, 0, out_read);
-
-    return e;
+    if (!sess->sock)
+        return GF_NETIO_DISCONNECTED;
+    return gf_sk_receive(sess->sock, data, data_size, 0, out_read);
 }
 
 
 #ifdef GPAC_HAS_SSL
-/*pattern comp taken from wget*/
-#define ASTERISK_EXCLUDES_DOT  /* mandated by rfc2818 */
 
-#define TOLOWER(x) ('A' <= (x) && (x) <= 'Z' ? (x) - 32 : (x))
+#define LWR(x) ('A' <= (x) && (x) <= 'Z' ? (x) - 32 : (x))
 
-static Bool pattern_match(const char *pattern, const char *string)
+static Bool rfc2818_match(const char *pattern, const char *string)
 {
-    const char *p = pattern, *n = string;
-    char c;
-    for (; (c = TOLOWER (*p++)) != '\0'; n++) {
-        if (c == '*') {
-            for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p))
-                ;
-            for (; *n != '\0'; n++)
-                if (TOLOWER (*n) == c && pattern_match (p, n))
+    char c, d;
+       u32 i=0, k=0;
+       while (1) {
+               c = LWR(pattern[i]);
+               if (c == '\0') break;
+
+               if (c=='*') {
+                       /*remove *** patterns*/
+                       while (c == '*') {
+                               i++;
+                               c = LWR(pattern[i]);
+                       }
+                       /*look for same c character*/
+                       while (1) {
+                               d = LWR(string[k]);  
+                               if (d == '\0') break;
+                               /*matched c character, check following substrings*/
+                if ((d == c) && rfc2818_match (&pattern[i], &string[k]))
                     return 1;
-#ifdef ASTERISK_EXCLUDES_DOT
-                else if (*n == '.')
+                else if (d == '.')
                     return 0;
-#endif
-            return c == '\0';
-        } else {
-            if (c != TOLOWER (*n))
-                return 0;
-        }
-    }
-    return *n == '\0';
+
+                               k++;
+                       }
+                       return (c == '\0') ? 1 : 0;
+               } else {
+                       if (c != LWR(string[k]))
+                               return 0;
+               }
+               i++;
+               k++;
+       }
+       return (string[k]=='\0') ? 1 : 0;
 }
-#undef TOLOWER
+#undef LWR
 
 #endif
 
@@ -1197,7 +1204,7 @@ static void gf_dm_connect(GF_DownloadSession *sess)
             X509 *cert;
             Bool success = 1;
 
-            sess->ssl = SSL_new(sess->dm->ssl_ctx);
+                       sess->ssl = SSL_new(sess->dm->ssl_ctx);
             SSL_set_fd(sess->ssl, gf_sk_get_handle(sess->sock));
             SSL_set_connect_state(sess->ssl);
             ret = SSL_connect(sess->ssl);
@@ -1206,13 +1213,27 @@ static void gf_dm_connect(GF_DownloadSession *sess)
             cert = SSL_get_peer_certificate(sess->ssl);
             /*if we have a cert, check it*/
             if (cert) {
+                                       SSL_set_verify_result(sess->ssl, 0);
                 vresult = SSL_get_verify_result(sess->ssl);
-                if (vresult != X509_V_OK) success = 0;
-                else {
+                               
+                               if (vresult == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
+                    GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[SSL] Cannot locate issuer's certificate on the local system, will not attempt to validate\n"));
+                                       SSL_set_verify_result(sess->ssl, 0);
+                       vresult = SSL_get_verify_result(sess->ssl);
+                               }
+
+                               if (vresult == X509_V_OK) {
                     common_name[0] = 0;
                     X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, common_name, sizeof (common_name));
-                    if (!pattern_match(common_name, sess->server_name)) success = 0;
-                }
+                                       if (!rfc2818_match(common_name, sess->server_name)) {
+                                               success = 0;
+                                               GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[SSL] Mismatch in certificate names: got %s expected %s\n", common_name, sess->server_name));
+                                       }
+                               } else {
+                                       success = 0;
+                                       GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[SSL] Error verifying certificate %x\n", vresult));
+                               }
+
                 X509_free(cert);
 
                 if (!success) {
@@ -1358,6 +1379,7 @@ GF_Err gf_dm_sess_process(GF_DownloadSession *sess)
     return sess->last_error;
 }
 
+GF_EXPORT
 GF_Err gf_dm_sess_process_headers(GF_DownloadSession *sess)
 {
     Bool go;
@@ -1990,8 +2012,10 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) {
 
 #ifdef GPAC_HAS_SSL
         if (sess->ssl) {
-            e = GF_IP_NETWORK_FAILURE;
-            if (!SSL_write(sess->ssl, tmp_buf, len+par.size)) e = GF_OK;
+            u32 writelen = len+par.size;
+                       e = GF_OK;
+                       if (writelen != SSL_write(sess->ssl, tmp_buf, writelen))
+                               e = GF_IP_NETWORK_FAILURE;
         } else
 #endif
             e = gf_sk_send(sess->sock, tmp_buf, len+par.size);
@@ -2002,9 +2026,11 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) {
 
 #ifdef GPAC_HAS_SSL
         if (sess->ssl) {
-            e = GF_IP_NETWORK_FAILURE;
-            if (!SSL_write(sess->ssl, sHTTP, strlen(sHTTP))) e = GF_OK;
-        } else
+            u32 len = strlen(sHTTP);
+                       e = GF_OK;
+                       if (len != SSL_write(sess->ssl, sHTTP, len))
+                               e = GF_IP_NETWORK_FAILURE;
+         } else
 #endif
             e = gf_sk_send(sess->sock, sHTTP, strlen(sHTTP));
 
@@ -2047,7 +2073,7 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP)
             }
         }
 #endif
-        e = gf_dm_read_data(sess, sHTTP, GF_DOWNLOAD_BUFFER_SIZE, &size);
+        e = gf_dm_read_data(sess, sHTTP, GF_DOWNLOAD_BUFFER_SIZE-1, &size);
         if (e!= GF_IP_CONNECTION_CLOSED && (!size || e == GF_IP_NETWORK_EMPTY)) {
             if (e == GF_IP_CONNECTION_CLOSED || (!sess->total_size && (gf_sys_clock() - sess->start_time > 5000))) {
                 sess->total_size = sess->bytes_done;
@@ -2112,7 +2138,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP)
     new_location = NULL;
     sess->use_cache_file = 1;
     while (1) {
-        e = gf_dm_read_data(sess, sHTTP + bytesRead, GF_DOWNLOAD_BUFFER_SIZE - bytesRead, &res);
+        e = gf_dm_read_data(sess, sHTTP + bytesRead, GF_DOWNLOAD_BUFFER_SIZE - 1 - bytesRead, &res);
         switch (e) {
         case GF_IP_NETWORK_EMPTY:
             if (!bytesRead) return GF_OK;
@@ -2213,7 +2239,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP)
         gf_dm_sess_user_io(sess, &par);
 #endif
 
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] Processing header %s: %s\n", hdr, hdr_val));
//       GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] Processing header %s: %s\n", hdr, hdr_val));
 
         if (!stricmp(hdr, "Content-Length") ) {
             ContentLength = (u32) atoi(hdr_val);
@@ -2625,20 +2651,20 @@ static void wget_NetIO(void *cbk, GF_NETIO_Parameter *param)
 
 
 GF_EXPORT
-GF_Err gf_dm_wget(const char *url, const char *filename)
+GF_Err gf_dm_wget(const char *url, const char *filename, u64 start_range, u64 end_range)
 {
        GF_Err e;
        GF_DownloadManager * dm = NULL;
        dm = gf_dm_new(NULL);
        if (!dm)
                return GF_OUT_OF_MEM;
-       e = gf_dm_wget_with_cache(dm, url, filename);
+       e = gf_dm_wget_with_cache(dm, url, filename, start_range, end_range);
        gf_dm_del(dm);
        return e;
 }
 
 GF_Err gf_dm_wget_with_cache(GF_DownloadManager * dm,
-                               const char *url, const char *filename)
+                               const char *url, const char *filename, u64 start_range, u64 end_range)
 {
        GF_Err e;
        FILE * f;
@@ -2656,6 +2682,11 @@ GF_Err gf_dm_wget_with_cache(GF_DownloadManager * dm,
        }
        dnload->use_cache_file = 1;
        dnload->force_data_write_callback = 1;
+       if (end_range) {
+               dnload->range_start = start_range;
+               dnload->range_end = end_range;
+           dnload->needs_range = 1;
+       }
        if (e == GF_OK) {
                e = gf_dm_sess_process(dnload);
        }
@@ -2897,6 +2928,7 @@ GF_Err gf_dm_sess_reassign(GF_DownloadSession *sess, u32 flags, gf_dm_user_io us
        }
 #endif
 
+       if (sess->flags & GF_DOWNLOAD_SESSION_USE_SSL) flags |= GF_DOWNLOAD_SESSION_USE_SSL;
        sess->flags = flags;
        sess->user_proc = user_io;
        sess->usr_cbk = cbk;
index d1059f6ece84a27ef223580fd363fadbcfe2cb96..f6c57d1f2bb956f74a3cbba0d7fe09d884b58fd1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -74,7 +75,7 @@ static const char *szProg[] =
 
 static u64 prev_pos = 0;
 static u64 prev_pc = 0;
-static void gf_on_progress_stdout(const char *_title, u64 done, u64 total)
+static void gf_on_progress_std(const char *_title, u64 done, u64 total)
 {
        Double prog;
        u32 pos;
@@ -89,16 +90,16 @@ static void gf_on_progress_stdout(const char *_title, u64 done, u64 total)
        }
        if (done==total) {
                u32 len = strlen(szT) + 40;
-               while (len) { fprintf(stdout, " "); len--; };
-               fprintf(stdout, "\r");
+               while (len) { fprintf(stderr, " "); len--; };
+               fprintf(stderr, "\r");
        }
        else {
                u32 pc = (u32) ( 100 * prog);
                if ((pos!=prev_pos) || (pc!=prev_pc)) {
                        prev_pos = pos;
                        prev_pc = pc;
-                       fprintf(stdout, "%s: |%s| (%02d/100)\r", szT, szProg[pos], pc);
-                       fflush(stdout);
+                       fprintf(stderr, "%s: |%s| (%02d/100)\r", szT, szProg[pos], pc);
+                       fflush(stderr);
                }
        }
 }
@@ -114,7 +115,7 @@ void gf_set_progress(const char *title, u64 done, u64 total)
        }
 #ifndef _WIN32_WCE
        else {
-               gf_on_progress_stdout(title, done, total);
+               gf_on_progress_std(title, done, total);
        }
 #endif
 }
@@ -151,7 +152,9 @@ static struct log_tool_info {u32 type;  const char *name; u32 level; } global_lo
        { GF_LOG_AUDIO, "audio", GF_LOG_WARNING },
        { GF_LOG_MODULE, "module", GF_LOG_WARNING },
        { GF_LOG_MUTEX, "mutex", GF_LOG_WARNING },
-       { GF_LOG_CONSOLE, "console", GF_LOG_INFO }
+       { GF_LOG_DASH, "dash", GF_LOG_WARNING },
+       { GF_LOG_CONSOLE, "console", GF_LOG_INFO },
+       { GF_LOG_APP, "app", GF_LOG_INFO }
 };
 
 GF_EXPORT
@@ -324,7 +327,7 @@ Bool gf_log_tool_level_on(u32 log_tool, u32 log_level)
 void default_log_callback(void *cbck, u32 level, u32 tool, const char* fmt, va_list vlist)
 {
 #ifndef _WIN32_WCE
-    vfprintf(stdout, fmt, vlist);
+    vfprintf(stderr, fmt, vlist);
 #endif
 }
 
@@ -497,8 +500,6 @@ const char *gf_error_to_string(GF_Err e)
        }
 }
 
-
-/* crc32 from ffmpeg*/
 static const u32 gf_crc_table[256] = {
        0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
        0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
@@ -557,6 +558,7 @@ u32 gf_crc_32(char *data, u32 len)
     return crc;
 }
 
+
 #define CHECK_MAC(_a) "#_a :" ? (_a) ? "yes":"no"
 
 GF_EXPORT
index 8e8e8f0bb10e7705ebf7b22ef40049bc8513d74e..1b93a4c21f49b162ea05876efd181aaf8ed9f6bc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 7e9b6b382c07ede39390bc7b8a93003e4f5f665c..21df7f986910f4295a07c0e7172b88993b044a3b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 38539dc0857a48ed8b4c41c006697061744072b9..0957e05fc5fca98bd92f4e0ad4ff73f42740ef0e 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index a6d594f843dac7fa7aeb2dc9e396daaafcb732e5..de3e65f2a0f748d1a3a86d4c27d546981b0a428b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 8de4c42d4ed9e11f0eff74224bb1b5ec7e46540d..7471fd8836695548290f9a2fbfc893a9135447bb 100644 (file)
@@ -1,9 +1,9 @@
 /*\r
  *                     GPAC - Multimedia Framework C SDK\r
  *\r
- *                     Copyright (c) Telecom ParisTech 2011-\r
- *                                     All rights reserved\r
  *                     Authors: Jean Le Feuvre\r
+ *                     Copyright (c) Telecom ParisTech 2000-2012\r
+ *                                     All rights reserved\r
  *\r
  *  This file is part of GPAC / common tools sub-project\r
  *\r
@@ -361,7 +361,7 @@ static GF_Config *create_default_config(char *file_path)
 \r
        if (! get_default_install_path(szPath, GF_PATH_MODULES)) {\r
                gf_delete_file(szPath);\r
-               fprintf(stdout, "default modules not found\n");\r
+               GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] default modules not found\n"));\r
                return NULL;\r
        }\r
 \r
@@ -376,8 +376,6 @@ static GF_Config *create_default_config(char *file_path)
                gf_cfg_set_key(cfg, "General", "CacheDirectory", cache_dir);\r
                gf_free(cache_dir);\r
        }\r
-       gf_cfg_set_key(cfg, "DSMCC", "Activated", "false");\r
-\r
        gf_cfg_set_key(cfg, "Compositor", "Raster2D", "GPAC 2D Raster");\r
        gf_cfg_set_key(cfg, "Audio", "ForceConfig", "yes");\r
        gf_cfg_set_key(cfg, "Audio", "NumBuffers", "2");\r
@@ -490,6 +488,15 @@ GF_Config *gf_cfg_init(const char *file, Bool *new_cfg)
 \r
        if (file) {\r
                cfg = gf_cfg_new(NULL, file);\r
+               /*force creation of a new config*/\r
+               if (!cfg) {\r
+                       FILE *fcfg = fopen(file, "wt");\r
+                       if (fcfg) {\r
+                               fclose(fcfg);\r
+                               cfg = gf_cfg_new(NULL, file);\r
+                               if (new_cfg) *new_cfg = 1;\r
+                       }\r
+               }\r
                if (cfg) {\r
                        check_modules_dir(cfg);\r
                        return cfg;\r
@@ -502,16 +509,16 @@ GF_Config *gf_cfg_init(const char *file, Bool *new_cfg)
        }\r
        cfg = gf_cfg_new(szPath, CFG_FILE_NAME);\r
        if (!cfg) {\r
-               fprintf(stdout, "GPAC config file %s not found in %s - creating new file\n", CFG_FILE_NAME, szPath);\r
+               fprintf(stderr, "GPAC config file %s not found in %s - creating new file\n", CFG_FILE_NAME, szPath);\r
                cfg = create_default_config(szPath);\r
        }\r
 \r
        if (!cfg) {\r
-               fprintf(stdout, "Cannot create config file %s in %s directory\n", CFG_FILE_NAME, szPath);\r
+               fprintf(stderr, "Cannot create config file %s in %s directory\n", CFG_FILE_NAME, szPath);\r
                return NULL;\r
        }\r
 \r
-       fprintf(stdout, "Using config file in %s directory\n", szPath);\r
+       fprintf(stderr, "Using config file in %s directory\n", szPath);\r
 \r
        check_modules_dir(cfg);\r
 \r
index f80e2b85c029d337ada28aa3c449d795fe98ccb1..7c383fb3b8a64c870809571cdd778660706b2865 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -215,14 +216,107 @@ GF_Err gf_cleanup_dir(char* DirPathName)
 #ifndef gettimeofday
 #ifdef _WIN32_WCE
 
+#include <time.h>
+//#include <wce_time.h>
+
+/*
+ * Author of first version (timeval.h): by Wu Yongwei
+ * Author of Windows CE version: Mateusz Loskot (mateusz@loskot.net)
+ *
+ * All code here is considered in the public domain though we do wish our names
+ * could be retained if anyone uses them.
+ */
+
+/*
+ * Constants used internally by time functions.
+ */
+
+#ifndef _TM_DEFINED
+struct tm
+{
+       int tm_sec;     /* seconds after the minute - [0,59] */
+       int tm_min;     /* minutes after the hour - [0,59] */
+       int tm_hour;    /* hours since midnight - [0,23] */
+       int tm_mday;    /* day of the month - [1,31] */
+       int tm_mon;     /* months since January - [0,11] */
+       int tm_year;    /* years since 1900 */
+       int tm_wday;    /* days since Sunday - [0,6] */
+       int tm_yday;    /* days since January 1 - [0,365] */
+       int tm_isdst;   /* daylight savings time flag */
+};
+#define _TM_DEFINED
+#endif /* _TM_DEFINED */
+
+#ifndef _TIMEZONE_DEFINED
+struct timezone
+{
+    int tz_minuteswest; /* minutes W of Greenwich */
+    int tz_dsttime;     /* type of dst correction */
+};
+#define _TIMEZONE_DEFINED
+#endif /* _TIMEZONE_DEFINED */
+
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define EPOCHFILETIME (116444736000000000i64)
+#else
+#define EPOCHFILETIME (116444736000000000LL)
+#endif
+
+int gettimeofday(struct timeval *tp, struct timezone *tzp)
+{
+    SYSTEMTIME      st;
+    FILETIME        ft;
+    LARGE_INTEGER   li;
+    TIME_ZONE_INFORMATION tzi;
+    __int64         t;
+    static int      tzflag;
+
+    if (NULL != tp)
+    {
+        GetSystemTime(&st);
+        SystemTimeToFileTime(&st, &ft);
+        li.LowPart  = ft.dwLowDateTime;
+        li.HighPart = ft.dwHighDateTime;
+        t  = li.QuadPart;       /* In 100-nanosecond intervals */
+        t -= EPOCHFILETIME;     /* Offset to the Epoch time */
+        t /= 10;                /* In microseconds */
+        tp->tv_sec  = (long)(t / 1000000);
+        tp->tv_usec = (long)(t % 1000000);
+    }
+
+    if (NULL != tzp)
+    {   
+        GetTimeZoneInformation(&tzi);
+
+        tzp->tz_minuteswest = tzi.Bias;
+        if (tzi.StandardDate.wMonth != 0)
+        {
+            tzp->tz_minuteswest += tzi.StandardBias * 60;
+        }
+
+        if (tzi.DaylightDate.wMonth != 0)
+        {
+            tzp->tz_dsttime = 1;
+        }
+        else
+        {
+            tzp->tz_dsttime = 0;
+        }
+    }
+
+    return 0;
+}
+
+
+#if 0
 /*
-       Conversion code for WinCE from pthreads WinCE
-       (FILETIME in Win32 is from jan 1, 1601)
        time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds 
+       FILETIME in Win32 is from jan 1, 1601
 */
 #define TIMESPEC_TO_FILETIME_OFFSET (((LONGLONG)27111902 << 32) + (LONGLONG)3577643008)
 
-s32 gettimeofday(struct timeval *tp, void *tz)
+s32 __gettimeofday(struct timeval *tp, void *tz)
 {
        FILETIME ft;
        SYSTEMTIME st;
@@ -237,6 +331,8 @@ s32 gettimeofday(struct timeval *tp, void *tz)
        tp->tv_usec = val;
        return 0;
 }
+#endif
+
 
 #elif defined(WIN32)
 
@@ -296,18 +392,21 @@ GF_Err gf_delete_file(const char *fileName)
 #endif
 }
 
-void gf_move_file(const char *fileName, const char *newFileName)
+GF_EXPORT
+GF_Err gf_move_file(const char *fileName, const char *newFileName)
 {
 #if defined(_WIN32_WCE)
        TCHAR swzName[MAX_PATH];
        TCHAR swzNewName[MAX_PATH];
        CE_CharToWide((char*)fileName, swzName);
        CE_CharToWide((char*)newFileName, swzNewName);
-       MoveFile(swzName, swzNewName);
+       return (MoveFile(swzName, swzNewName) == 0 ) ? GF_IO_ERR : GF_OK;
 #elif defined(WIN32)
-       MoveFile(fileName, newFileName);
+       /* success if != 0 */
+       return (MoveFile(fileName, newFileName) == 0 ) ? GF_IO_ERR : GF_OK;
 #else
-       rename(fileName, newFileName);
+       /* success is == 0 */
+       return ( rename(fileName, newFileName) == 0) ? GF_OK : GF_IO_ERR;
 #endif
 }
 
@@ -815,7 +914,7 @@ static void init_keyboard()
 static void close_keyboard(Bool new_line)
 {
        tcsetattr(0,TCSANOW, &t_orig);
-       if (new_line) fprintf(stdout, "\n");
+       if (new_line) fprintf(stderr, "\n");
 }
 
 void gf_prompt_set_echo_off(Bool echo_off) 
index 7a8145985f4488573a4466a5517e80c3eb676058..33e5d52263b8128edc9a8acaafbb2ceca352c4a1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index d17ef2f37af9018ec732c802a78fb7742e53c984..6053347053b3581f6eff0dcd0e5a47f55172fc62 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -59,6 +60,7 @@
 #endif
 
 /*common win32 redefs*/
+#undef EAGAIN
 #define EAGAIN                         WSAEWOULDBLOCK
 #define EISCONN                                WSAEISCONN
 #define ENOTCONN                       WSAENOTCONN
@@ -66,7 +68,9 @@
 #define EMSGSIZE                       WSAEMSGSIZE
 #define ECONNABORTED           WSAECONNABORTED
 #define ENETDOWN                       WSAENETDOWN
+#undef EINTR
 #define EINTR                          WSAEINTR
+#undef EBADF
 #define EBADF                          WSAEBADF
 
 #define LASTSOCKERROR WSAGetLastError()
index ec82ad2f3e5ffe9b0535537ade8832c9b7c66c2e..9a1c990e1b2df0c1dd5bc6aefdd49d1fda6eac45 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -283,6 +284,7 @@ void Thread_Stop(GF_Thread *t, Bool Destroy)
        t->status = GF_THREAD_STATUS_DEAD;
 }
 
+GF_EXPORT
 void gf_th_stop(GF_Thread *t)
 {
        Thread_Stop(t, 0);
index 8a618dab1f75b5b7baf52efc55464ff734ef3513..e7ba3c0a3967c89ff3a0c651dc96e91b0e60c468 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 0e5c754d1fa36495fe5f79917fbd1dbfdd8faf2d..f085358e8dd464e91925f1ff63d4e292ea776c36 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005 
+ *                     Authors: Pierre Souchay
+ *                     Copyright (c) Telecom ParisTech 2010
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 7b18e9b2c23b7614e8a7b14f5941e2c2bce3f71e..fe4f7a04fbfdc59a35e1ff3c7232e421e7cd3ba5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 5adf6e4358b3a04eda3c91b3778099f94d1f9aca..9a2e3aa0ba590c0c125d92931c10ac68f1f90ccc 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 163766953d82c412bce0c7e8d83f722f5e6dd96f..bb909c894669e44108fc62d91d217d7ac3f0f5b5 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 5043c14303228b4483d26b07295e08c5c3d0e654..449673594ebd1a451f9b435ca7895a2f25cf89a4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index 4f50a04f9fc65921f94f81f8485646ebc56e8b3a..a14a4f27f88c3a9a74f0d5f913e7b3d5af062f7f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2000-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
@@ -95,7 +96,9 @@ char *gf_url_concatenate(const char *parentName, const char *pathName)
        char *outPath, *name, *rad;
        char tmp[GF_MAX_PATH];
 
-       if (!pathName || !parentName) return NULL;
+       if (!pathName && !parentName) return NULL;
+       if (!pathName) return gf_strdup(parentName);
+       if (!parentName) return gf_strdup(pathName);
 
        if ( (strlen(parentName) > GF_MAX_PATH) || (strlen(pathName) > GF_MAX_PATH) ) return NULL;
 
@@ -179,6 +182,10 @@ char *gf_url_concatenate(const char *parentName, const char *pathName)
                        pathSepCount = 1;
                        name = "";
                }
+               if (!strcmp(pathName, "./")) {
+                       pathSepCount = 0;
+                       name = "";
+               }
                for (i = 0; i< strlen(pathName) - 2; i++) {
                        /*current dir*/
                        if ( (pathName[i] == '.') 
@@ -202,6 +209,11 @@ char *gf_url_concatenate(const char *parentName, const char *pathName)
        if (!name) name = (char *) pathName;
 
        strcpy(tmp, parentName);
+       while (strchr(" \r\n\t", tmp[strlen(tmp)-1])) {
+               tmp[strlen(tmp)-1] = 0;
+       }
+
+       /*remove the last /*/
        for (i = strlen(parentName); i > 0; i--) {
                //break our path at each separator
                if ((parentName[i-1] == GF_PATH_SEPARATOR) || (parentName[i-1] == '/'))  {
@@ -217,9 +229,6 @@ char *gf_url_concatenate(const char *parentName, const char *pathName)
                        strcat(tmp, "../");
                        pathSepCount--;
                }
-/*             outPath = gf_strdup(pathName);
-               goto check_spaces;
-               */      
        } else {
                strcat(tmp, "/");
        }
@@ -300,3 +309,29 @@ char *gf_url_percent_encode(const char *path)
        }
        return outpath;
 }
+
+GF_EXPORT
+const char *gf_url_get_resource_name(const char *sURL)
+{
+       char *sep;
+       if (!sURL) return NULL;
+       sep = strrchr(sURL, '/');
+       if (!sep) sep = strrchr(sURL, '\\');
+       if (sep) return sep+1;
+       return sURL;
+}
+
+GF_EXPORT
+Bool gf_url_get_resource_path(const char *sURL, char *res_path)
+{
+       char *sep;
+       strcpy(res_path, sURL);
+       sep = strrchr(res_path, '/');
+       if (!sep) sep = strrchr(res_path, '\\');
+       if (sep) {
+               sep[1] = 0;
+               return 1;
+       }
+       return 0;
+}
+
index 4118ff45fb3b9947d18a1906bfec091bb33a92f4..8a276373af790bb127f522efee06b1ce26baa3ec 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Copyright (c) Jean Le Feuvre 2000-2005
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2007-2012
  *                                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
 
 #include <gpac/utf.h>
 
- /*
- * Original code from the GNU UTF-8 Library
+
+#if 1
+
+
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+    Sept 2001: fixed const & error conditions per
+       mods suggested by S. Parent & A. Lillich.
+    June 2002: Tim Dodd added detection and handling of incomplete
+       source sequences, enhanced error detection, added casts
+       to eliminate compiler warnings.
+    July 2003: slight mods to back out aggressive FFFE detection.
+    Jan 2004: updated switches in from-UTF8 conversions.
+    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+    See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+typedef u32 UTF32;     /* at least 32 bits */
+typedef u16 UTF16;     /* at least 16 bits */
+typedef u8 UTF8;       /* typically 8 bits */
+typedef u8 Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+       conversionOK,           /* conversion successful */
+       sourceExhausted,        /* partial character in source, but hit end */
+       targetExhausted,        /* insuff. room in target for conversion */
+       sourceIllegal           /* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+       strictConversion = 0,
+       lenientConversion
+} ConversionFlags;
+
+static const int halfShift  = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START  (UTF32)0xD800
+#define UNI_SUR_HIGH_END    (UTF32)0xDBFF
+#define UNI_SUR_LOW_START   (UTF32)0xDC00
+#define UNI_SUR_LOW_END     (UTF32)0xDFFF
+#define false     0
+#define true       1
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
+                    0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow.  There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+ * Constants have been gathered. Loops & conditionals have been removed as
+ * much as possible for efficiency, in favor of drop-through switches.
+ * (See "Note A" at the bottom of the file for equivalent code.)
+ * If your compiler supports it, the "isLegalUTF8" call can be turned
+ * into an inline function.
+ */
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF8 (
+       const UTF16** sourceStart, const UTF16* sourceEnd, 
+       UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+       UTF32 ch;
+       unsigned short bytesToWrite = 0;
+       const UTF32 byteMask = 0xBF;
+       const UTF32 byteMark = 0x80; 
+       const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+       ch = *source++;
+       /* If we have a surrogate pair, convert to UTF32 first. */
+       if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+           /* If the 16 bits following the high surrogate are in the source buffer... */
+           if (source < sourceEnd) {
+               UTF32 ch2 = *source;
+               /* If it's a low surrogate, convert to UTF32. */
+               if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+                   ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+                       + (ch2 - UNI_SUR_LOW_START) + halfBase;
+                   ++source;
+               } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+                   --source; /* return to the illegal value itself */
+                   result = sourceIllegal;
+                   break;
+               }
+           } else { /* We don't have the 16 bits following the high surrogate. */
+               --source; /* return to the high surrogate */
+               result = sourceExhausted;
+               break;
+           }
+       } else if (flags == strictConversion) {
+           /* UTF-16 surrogate values are illegal in UTF-32 */
+           if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+               --source; /* return to the illegal value itself */
+               result = sourceIllegal;
+               break;
+           }
+       }
+       /* Figure out how many bytes the result will require */
+       if (ch < (UTF32)0x80) {      bytesToWrite = 1;
+       } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+       } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+       } else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
+       } else {                            bytesToWrite = 3;
+                                           ch = UNI_REPLACEMENT_CHAR;
+       }
+
+       target += bytesToWrite;
+       if (target > targetEnd) {
+           source = oldSource; /* Back up source pointer! */
+           target -= bytesToWrite; result = targetExhausted; break;
+       }
+       switch (bytesToWrite) { /* note: everything falls through. */
+           case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+           case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+           case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+           case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+       }
+       target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ *  length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false.  The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
  */
 
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+    UTF8 a;
+    const UTF8 *srcptr = source+length;
+    switch (length) {
+    default: return false;
+       /* Everything else falls through when "true"... */
+    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+
+       switch (*source) {
+           /* no fall-through in this inner switch */
+           case 0xE0: if (a < 0xA0) return false; break;
+           case 0xED: if (a > 0x9F) return false; break;
+           case 0xF0: if (a < 0x90) return false; break;
+           case 0xF4: if (a > 0x8F) return false; break;
+           default:   if (a < 0x80) return false;
+       }
+
+    case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+    }
+    if (*source > 0xF4) return false;
+    return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (
+       const UTF8** sourceStart, const UTF8* sourceEnd, 
+       UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+       UTF32 ch = 0;
+       unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+       if (source + extraBytesToRead >= sourceEnd) {
+           result = sourceExhausted; break;
+       }
+       /* Do this check whether lenient or strict */
+       if (! isLegalUTF8(source, extraBytesToRead+1)) {
+           result = sourceIllegal;
+           break;
+       }
+       /*
+        * The cases all fall through. See "Note A" below.
+        */
+       switch (extraBytesToRead) {
+           case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+           case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+           case 3: ch += *source++; ch <<= 6;
+           case 2: ch += *source++; ch <<= 6;
+           case 1: ch += *source++; ch <<= 6;
+           case 0: ch += *source++;
+       }
+       ch -= offsetsFromUTF8[extraBytesToRead];
+
+       if (target >= targetEnd) {
+           source -= (extraBytesToRead+1); /* Back up source pointer! */
+           result = targetExhausted; break;
+       }
+       if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+           /* UTF-16 surrogate values are illegal in UTF-32 */
+           if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+               if (flags == strictConversion) {
+                   source -= (extraBytesToRead+1); /* return to the illegal value itself */
+                   result = sourceIllegal;
+                   break;
+               } else {
+                   *target++ = UNI_REPLACEMENT_CHAR;
+               }
+           } else {
+               *target++ = (UTF16)ch; /* normal case */
+           }
+       } else if (ch > UNI_MAX_UTF16) {
+           if (flags == strictConversion) {
+               result = sourceIllegal;
+               source -= (extraBytesToRead+1); /* return to the start */
+               break; /* Bail out; shouldn't continue */
+           } else {
+               *target++ = UNI_REPLACEMENT_CHAR;
+           }
+       } else {
+           /* target is a character in range 0xFFFF - 0x10FFFF. */
+           if (target + 1 >= targetEnd) {
+               source -= (extraBytesToRead+1); /* Back up source pointer! */
+               result = targetExhausted; break;
+           }
+           ch -= halfBase;
+           *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+           *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+       }
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+
+
+GF_EXPORT
+size_t gf_utf8_wcslen (const unsigned short *s)
+{
+  const unsigned short* ptr;
+  for (ptr = s; *ptr != (unsigned short)'\0'; ptr++) {
+  }
+  return ptr - s;
+}
+
 GF_EXPORT
 size_t gf_utf8_wcstombs(char* dest, size_t len, const unsigned short** srcp)
 {
+       const UTF16** sourceStart = srcp;
+       const UTF16* sourceEnd = *srcp + gf_utf8_wcslen(*srcp);
+       UTF8* targetStart = dest;
+       UTF8* targetEnd = dest + len;
+       ConversionFlags flags = strictConversion;
+
+       ConversionResult res = ConvertUTF16toUTF8(sourceStart, sourceEnd, &targetStart, targetEnd, flags);
+       if (res != conversionOK) return (size_t)-1;
+       *targetStart = 0;
+       *srcp=NULL;
+       return strlen(dest);
+}
+
+GF_EXPORT
+size_t gf_utf8_mbstowcs(unsigned short* dest, size_t len, const char** srcp)
+{
+       const UTF8** sourceStart = (const UTF8**) srcp;
+       const UTF8* sourceEnd = (const UTF8*) ( *srcp + strlen( *srcp) ); 
+       UTF16* targetStart = (UTF16* ) dest;
+       UTF16* targetEnd = (UTF16* ) (dest + len);
+       ConversionFlags flags = strictConversion;
+       ConversionResult res = ConvertUTF8toUTF16(sourceStart, sourceEnd, &targetStart, targetEnd, flags);
+       if (res != conversionOK) return (size_t)-1;
+       *targetStart = 0;
+       *srcp=NULL;
+       return gf_utf8_wcslen(dest);
+}
+
+
+#else
+
+GF_EXPORT
+size_t gf_utf8_wcslen (const unsigned short *s)
+{
+  const unsigned short* ptr;
+  for (ptr = s; *ptr != (unsigned short)'\0'; ptr++) {
+  }
+  return ptr - s;
+}
+
+GF_EXPORT
+size_t gf_utf8_wcstombs(char* dest, size_t len, const unsigned short** srcp)
+{
+       /*
+       * Original code from the GNU UTF-8 Library
+       */
        size_t count;
        const unsigned short * src = *srcp;
 
@@ -175,14 +532,4 @@ bad_input:
        return (size_t)(-1);
 }
 
-
-GF_EXPORT
-size_t gf_utf8_wcslen (const unsigned short *s)
-{
-  const unsigned short* ptr;
-  for (ptr = s; *ptr != (unsigned short)'\0'; ptr++) {
-  }
-  return ptr - s;
-}
-
-
+#endif
index dafa8728edd061f454dc0f8e00707f061d0cdd6e..45d742d9c5b04d9a1e084ebbc82372b64c99f66a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *                     GPAC - Multimedia Framework C SDK
  *
- *                     Authors: Jean le Feuvre
- *                     Copyright (c) 2005-200X ENST
+ *                     Authors: Jean Le Feuvre
+ *                     Copyright (c) Telecom ParisTech 2005-2012
  *                     All rights reserved
  *
  *  This file is part of GPAC / common tools sub-project
index a6ebea7bc68ff623c7a450eada9c311fe2e9f471..d0a1bcca5909a9c4f0b91dd8fd9703bb0a1ff524 100644 (file)
@@ -1,10 +1,10 @@
 @echo off\r
 cd /d %~dp0\r
 for /f "delims=" %%a in ('svnversion') do echo #define GPAC_SVN_REVISION "%%a" > test.h \r
-if not exist include\gpac\version.h goto create \r
-ECHO n|COMP test.h include\gpac\version.h > nul \r
+if not exist include\gpac\revision.h goto create \r
+ECHO n|COMP test.h include\gpac\revision.h > nul \r
 if errorlevel 1 goto create\r
 DEL test.h\r
 exit/b\r
 :create\r
-MOVE /Y test.h include\gpac\version.h\r
+MOVE /Y test.h include\gpac\revision.h\r